bookmarks_;
+
+ // 确保配置目录存在
+ static bool ensure_config_dir();
+};
+
+} // namespace tut
diff --git a/src/browser_v2.cpp b/src/browser_v2.cpp
index fb11a79..644f45b 100644
--- a/src/browser_v2.cpp
+++ b/src/browser_v2.cpp
@@ -1,5 +1,6 @@
#include "browser_v2.h"
#include "dom_tree.h"
+#include "bookmark.h"
#include "render/colors.h"
#include "render/decorations.h"
#include "render/image.h"
@@ -33,6 +34,7 @@ public:
HttpClient http_client;
HtmlParser html_parser;
InputHandler input_handler;
+ tut::BookmarkManager bookmark_manager;
// 新渲染系统
Terminal terminal;
@@ -407,6 +409,18 @@ public:
show_help();
break;
+ case Action::ADD_BOOKMARK:
+ add_bookmark();
+ break;
+
+ case Action::REMOVE_BOOKMARK:
+ remove_bookmark();
+ break;
+
+ case Action::SHOW_BOOKMARKS:
+ show_bookmarks();
+ break;
+
case Action::QUIT:
break; // 在main loop处理
@@ -589,9 +603,17 @@ public:
N - Previous match
+Bookmarks
+
+- B - Add bookmark
+- D - Remove bookmark
+- :bookmarks - Show bookmarks
+
+
Commands
- :o URL - Open URL
+- :bookmarks - Show bookmarks
- :q - Quit
- ? - Show this help
@@ -613,6 +635,79 @@ public:
active_link = current_tree.links.empty() ? -1 : 0;
status_message = "Help - Press any key to continue";
}
+
+ void show_bookmarks() {
+ std::ostringstream html;
+ html << R"(
+
+
+Bookmarks
+
+Bookmarks
+)";
+
+ const auto& bookmarks = bookmark_manager.get_all();
+
+ if (bookmarks.empty()) {
+ html << "No bookmarks yet.
\n";
+ html << "Press B on any page to add a bookmark.
\n";
+ } else {
+ html << "\n";
+ html << "
\n";
+ html << "" << bookmarks.size() << " bookmark(s). Press D on any page to remove its bookmark.
\n";
+ }
+
+ html << R"(
+
+
+)";
+
+ current_tree = html_parser.parse_tree(html.str(), "bookmarks://");
+ current_layout = layout_engine->layout(current_tree);
+ scroll_pos = 0;
+ active_link = current_tree.links.empty() ? -1 : 0;
+ status_message = "Bookmarks";
+ }
+
+ void add_bookmark() {
+ if (current_url.empty() || current_url.find("://") == std::string::npos) {
+ status_message = "Cannot bookmark this page";
+ return;
+ }
+
+ // 不要书签特殊页面
+ if (current_url.find("help://") == 0 || current_url.find("bookmarks://") == 0) {
+ status_message = "Cannot bookmark special pages";
+ return;
+ }
+
+ std::string title = current_tree.title.empty() ? current_url : current_tree.title;
+
+ if (bookmark_manager.add(current_url, title)) {
+ status_message = "Bookmarked: " + title;
+ } else {
+ status_message = "Already bookmarked";
+ }
+ }
+
+ void remove_bookmark() {
+ if (current_url.empty()) {
+ status_message = "No page to unbookmark";
+ return;
+ }
+
+ if (bookmark_manager.remove(current_url)) {
+ status_message = "Bookmark removed";
+ } else {
+ status_message = "Not bookmarked";
+ }
+ }
};
BrowserV2::BrowserV2() : pImpl(std::make_unique()) {
diff --git a/src/input_handler.cpp b/src/input_handler.cpp
index 63717b8..4a4c683 100644
--- a/src/input_handler.cpp
+++ b/src/input_handler.cpp
@@ -174,6 +174,12 @@ public:
case '?':
result.action = Action::HELP;
break;
+ case 'B':
+ result.action = Action::ADD_BOOKMARK;
+ break;
+ case 'D':
+ result.action = Action::REMOVE_BOOKMARK;
+ break;
default:
buffer.clear();
break;
@@ -201,6 +207,8 @@ public:
result.action = Action::OPEN_URL;
result.text = command.substr(space_pos + 1);
}
+ } else if (command == "bookmarks" || command == "bm" || command == "b") {
+ result.action = Action::SHOW_BOOKMARKS;
} else if (!command.empty() && std::isdigit(command[0])) {
try {
result.action = Action::GOTO_LINE;
diff --git a/src/input_handler.h b/src/input_handler.h
index 9f7625a..379bc0a 100644
--- a/src/input_handler.h
+++ b/src/input_handler.h
@@ -38,7 +38,10 @@ enum class Action {
QUIT,
HELP,
SET_MARK, // Set a mark (m + letter)
- GOTO_MARK // Jump to mark (' + letter)
+ GOTO_MARK, // Jump to mark (' + letter)
+ ADD_BOOKMARK, // Add current page to bookmarks (B)
+ REMOVE_BOOKMARK, // Remove current page from bookmarks (D)
+ SHOW_BOOKMARKS // Show bookmarks page (:bookmarks)
};
struct InputResult {