diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-04-19 17:56:03 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-04-19 17:56:03 +0530 |
| commit | 0e95e99e72237058465959d55b77750a9d7c1bef (patch) | |
| tree | 5b99cd64f7c49b949a6381c4654ec253822934b5 | |
| parent | 7a458b424c2c1a6ed251211b25261acffef59b7f (diff) | |
| download | null-browser-0e95e99e72237058465959d55b77750a9d7c1bef.tar.gz null-browser-0e95e99e72237058465959d55b77750a9d7c1bef.zip | |
Add web.search and search text implemnetation
| -rw-r--r-- | TODO.org | 29 | ||||
| -rw-r--r-- | config.lua | 10 | ||||
| -rw-r--r-- | lua/null-browser/api.lua | 18 | ||||
| -rw-r--r-- | src/AsyncEventLoop.cpp | 2 | ||||
| -rw-r--r-- | src/LuaRuntime.hpp | 3 | ||||
| -rw-r--r-- | src/LuaRuntimeApi.hpp | 29 | ||||
| -rw-r--r-- | src/WindowActionRouter.cpp | 17 | ||||
| -rw-r--r-- | src/WindowActionRouter.hpp | 1 | ||||
| -rw-r--r-- | src/WindowMediator.hpp | 1 | ||||
| -rw-r--r-- | src/widgets/WebView.hpp | 1 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.cpp | 20 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.hpp | 1 |
12 files changed, 128 insertions, 4 deletions
@@ -1,6 +1,6 @@ ** Usable - [ ] Tests for api -- [ ] Search text in page +- [X] Search text in page - [ ] Dev tools - [ ] Fullscreen - [ ] Zoom in/out @@ -10,6 +10,7 @@ - [ ] Notifications ** Bugs +- [ ] INVESTIGATE: segfault on api module error - [ ] INVESTIGATE: Check why urlchanged doesnt fire for first url open - [ ] INVESTIGATE: Segfault on close - [ ] INVESTIGATE: Errors in keymap/thread segfaults @@ -84,4 +85,30 @@ web.history.back(1, { win = 1 }) -- Back for current view in win 1 web.keymap.set('n', '<c-r>', ..., { view = 1 }) -- Set keymap for view 1 web.keymap.set('n', '<c-r>', ..., { win = 1 }) -- Set keymap for win 1 web.opt.new_tab_url = 'https://duckduckgo.com' + +-- Search api +web.search.set_search_text('whatever') +web.search.next() +web.search.prev() +web.search.get_search_text() +web.search.current() +web.search.total() + +web.keymap.set('n', '/', function() + dmenu.input({ prompt = 'Search:' }, function(err, input) + if err or not input then return end + web.search.set_search_text(input) + end) +end) +web.keymap.set('n', 'n', function() web.search.next() end) +web.keymap.set('n', 'p', function() web.search.prev() end) + +web.event.add_listener('SearchChanged', { + callback = function() + local label = + web.search.get_search_text() .. ': ' .. web.search.current() .. '/' .. web.search.total() + -- CALL notify-send + -- OR inject js into view to show ui + end, +}) #+end_src @@ -41,6 +41,16 @@ local function to_url(url) return "https://" .. trim(url) end +web.keymap.set('n', '<esc>', function() web.search.set_text('') end) +web.keymap.set('n', 'n', function() web.search.next() end) +web.keymap.set('n', '<s-n>', function() web.search.previous() end) +web.keymap.set('n', '<c-f>', function() + dmenu.input({ prompt = 'Search:' }, function(err, input) + if err or not input then return end + web.search.set_text(input) + end) +end) + -- Open in new view web.keymap.set('n', 'o', function() print(web.get('new_view_url'), web.get('user_agent')) diff --git a/lua/null-browser/api.lua b/lua/null-browser/api.lua index ac7aa08..5e4beab 100644 --- a/lua/null-browser/api.lua +++ b/lua/null-browser/api.lua @@ -3,6 +3,7 @@ __internals = __internals --- @type table _G.web = _G.web or { + search = {}, keymap = {}, view = {}, history = {}, @@ -171,4 +172,21 @@ function web.history.back(count, view_id) return __internals.history_back(count, --- ``` function web.history.forward(count, view_id) return __internals.history_forward(count, view_id) end +--- Search +--- +--- @param text string Text to search +--- @param view_id? number Id of the view +--- +--- @example +--- ```lua +--- web.search.set_text('whatever') +--- ``` +function web.search.set_text(text, view_id) return __internals.search_set_text(text, view_id) end + +-- TODO: Documentation please +function web.search.next(view_id) return __internals.search_next(view_id) end + +-- TODO: Documentation please +function web.search.previous(view_id) return __internals.search_previous(view_id) end + print("api loaded") diff --git a/src/AsyncEventLoop.cpp b/src/AsyncEventLoop.cpp index f11babb..12e0351 100644 --- a/src/AsyncEventLoop.cpp +++ b/src/AsyncEventLoop.cpp @@ -74,7 +74,7 @@ AsyncEventLoop::~AsyncEventLoop() { uv_run(loop, UV_RUN_DEFAULT); if (uv_loop_alive(loop) > 0) - qDebug() << "WARNING: Loop still has active handles!"; + qWarning() << "WARNING: Loop still has active handles!"; free(loop); loop = nullptr; diff --git a/src/LuaRuntime.hpp b/src/LuaRuntime.hpp index f684409..0855570 100644 --- a/src/LuaRuntime.hpp +++ b/src/LuaRuntime.hpp @@ -52,6 +52,9 @@ signals: void webview_closed(WebViewId webview_id); void webview_selected(WebViewId webview_id); void config_updated(const QString &key, const QVariant &value); + void search_requested(const QString &text, WebViewId webview_id); + void search_next_requested(WebViewId webview_id); + void search_previous_requested(WebViewId webview_id); protected: LuaRuntime(); diff --git a/src/LuaRuntimeApi.hpp b/src/LuaRuntimeApi.hpp index 809b579..b6302ff 100644 --- a/src/LuaRuntimeApi.hpp +++ b/src/LuaRuntimeApi.hpp @@ -5,7 +5,7 @@ #include "LuaRuntime.hpp" #include "WindowActionRouter.hpp" -int lua_api_open_url(lua_State *state) { +int lua_api_view_set_url(lua_State *state) { const char *url = lua_tostring(state, 1); WebViewId view_id = lua_isnoneornil(state, 2) ? 0 : lua_tointeger(state, 2); auto &runtime = LuaRuntime::instance(); @@ -187,6 +187,28 @@ int lua_event_register(lua_State *state) { return 1; } +int lua_api_search_set_text(lua_State *state) { + const char *text = lua_tostring(state, 1); + WebViewId view_id = lua_isnoneornil(state, 1) ? 0 : lua_tointeger(state, 1); + auto &runtime = LuaRuntime::instance(); + emit runtime.search_requested(text, view_id); + return 1; +} + +int lua_api_search_next(lua_State *state) { + WebViewId view_id = lua_isnoneornil(state, 1) ? 0 : lua_tointeger(state, 1); + auto &runtime = LuaRuntime::instance(); + emit runtime.search_next_requested(view_id); + return 1; +} + +int lua_api_search_previous(lua_State *state) { + WebViewId view_id = lua_isnoneornil(state, 1) ? 0 : lua_tointeger(state, 1); + auto &runtime = LuaRuntime::instance(); + emit runtime.search_previous_requested(view_id); + return 1; +} + // NOLINTNEXTLINE static luaL_Reg internals_api[] = { luaL_Reg{"event_add_listener", &lua_event_register}, @@ -198,8 +220,11 @@ static luaL_Reg internals_api[] = { luaL_Reg{"view_current", &lua_api_view_current}, luaL_Reg{"view_list", &lua_view_list}, luaL_Reg{"view_select", &lua_view_select}, - luaL_Reg{"view_set_url", &lua_api_open_url}, + luaL_Reg{"view_set_url", &lua_api_view_set_url}, luaL_Reg{"history_back", &lua_history_back}, luaL_Reg{"history_forward", &lua_history_forward}, + luaL_Reg{"search_set_text", &lua_api_search_set_text}, + luaL_Reg{"search_previous", &lua_api_search_previous}, + luaL_Reg{"search_next", &lua_api_search_next}, luaL_Reg{nullptr, nullptr}, }; diff --git a/src/WindowActionRouter.cpp b/src/WindowActionRouter.cpp index d0b529b..5f787c0 100644 --- a/src/WindowActionRouter.cpp +++ b/src/WindowActionRouter.cpp @@ -58,6 +58,23 @@ void WindowActionRouter::initialize(Configuration *config) { WITH_WEBVIEW_WINDOW(webview_id, window, { emit window->mediator()->webview_selected(webview_id); }); }); + connect(&runtime, &LuaRuntime::search_requested, this, + [this](const QString &text, WebViewId webview_id) { + WITH_WEBVIEW_WINDOW(webview_id, window, { + this->current_search_text = text; + win_match.second->mediator()->set_search_text(text, webview_id, true); + }) + }); + connect(&runtime, &LuaRuntime::search_next_requested, this, [this](WebViewId webview_id) { + WITH_WEBVIEW_WINDOW(webview_id, window, { + win_match.second->mediator()->set_search_text(this->current_search_text, webview_id, true); + }) + }); + connect(&runtime, &LuaRuntime::search_previous_requested, this, [this](WebViewId webview_id) { + WITH_WEBVIEW_WINDOW(webview_id, window, { + win_match.second->mediator()->set_search_text(this->current_search_text, webview_id, false); + }) + }); } void WindowActionRouter::add_window(BrowserWindow *window) { diff --git a/src/WindowActionRouter.hpp b/src/WindowActionRouter.hpp index 17b935f..c1e6ecc 100644 --- a/src/WindowActionRouter.hpp +++ b/src/WindowActionRouter.hpp @@ -54,4 +54,5 @@ private: Configuration *configuration; EventQueue event_queue; + QString current_search_text; }; diff --git a/src/WindowMediator.hpp b/src/WindowMediator.hpp index b2ecb77..17190b3 100644 --- a/src/WindowMediator.hpp +++ b/src/WindowMediator.hpp @@ -16,6 +16,7 @@ public: DELEGATE(webview_stack, has_webview, has_webview) DELEGATE(webview_stack, current_webview_id, current_webview_id) DELEGATE(webview_stack, get_webview_list, get_webview_list) + DELEGATE(webview_stack, set_search_text, set_search_text) signals: void history_back_requested(WebViewId webview_id, qsizetype history_index); diff --git a/src/widgets/WebView.hpp b/src/widgets/WebView.hpp index 3f73316..98dceba 100644 --- a/src/widgets/WebView.hpp +++ b/src/widgets/WebView.hpp @@ -3,6 +3,7 @@ #include <QWebEngineView> #include <QtCore> #include <cstdint> +#include <qtypes.h> #include "utils.hpp" diff --git a/src/widgets/WebViewStack.cpp b/src/widgets/WebViewStack.cpp index 258fbc6..16fd3e9 100644 --- a/src/widgets/WebViewStack.cpp +++ b/src/widgets/WebViewStack.cpp @@ -1,4 +1,5 @@ #include <QStackedLayout> +#include <QWebEngineFindTextResult> #include <QWebEngineHistory> #include <QWebEngineNewWindowRequest> #include <QWebEngineProfile> @@ -198,6 +199,25 @@ void WebViewStack::focus_webview(WebViewId webview_id) { layout->setCurrentIndex((int)webview_index); } +void WebViewStack::set_search_text(const QString &text, WebViewId webview_id, bool forward) { + auto *webview = get_webview(webview_id); + if (webview == nullptr) { + qDebug() << "Webview does not exist"; + return; + } + + QString search_text = text.trimmed(); + + auto flags = + search_text.isLower() ? QWebEnginePage::FindFlags() : QWebEnginePage::FindCaseSensitively; + if (!forward) + flags |= QWebEnginePage::FindBackward; + + webview->page()->findText(search_text, flags, [](const QWebEngineFindTextResult &result) { + qDebug() << result.numberOfMatches() << result.activeMatch(); + }); +} + WebView *WebViewStack::get_webview(WebViewId webview_id) { auto webview_index = get_webview_index(webview_id); if (webview_index < 0) diff --git a/src/widgets/WebViewStack.hpp b/src/widgets/WebViewStack.hpp index 05362d6..e41af43 100644 --- a/src/widgets/WebViewStack.hpp +++ b/src/widgets/WebViewStack.hpp @@ -65,6 +65,7 @@ public slots: void webview_history_forward(WebViewId webview_id, qsizetype history_index); void close(WebViewId webview_id); void focus_webview(WebViewId webview_id); + void set_search_text(const QString &text, WebViewId webview_id, bool forward = true); protected slots: void on_new_webview_request(const QWebEngineNewWindowRequest &request); |
