Critical bugfix for async image loading:
Problem:
- When images are downloading and user navigates to new page,
the old DocumentTree is destroyed
- Image download completion handlers still have pointers to old DomNodes
- Accessing freed memory caused SIGSEGV
Solution:
1. Cancel all image downloads when starting new page load
2. Validate DomNode pointers before use (check if still in current tree)
3. Safely skip images for nodes that no longer exist
This fixes crashes on sites like docs.nbtca.space where navigation
can happen while images are loading.
Tested: No more crashes, basic functionality intact
- Add test_browser.sh interactive testing script
- Add TESTING.md comprehensive testing guide
- Update help text with form interaction details
- Include keyboard shortcuts for text input and dropdowns
- Add instructions for all new features
Improvements:
- Help now shows 'i' key for form focus
- Text input editing instructions
- Dropdown selection navigation guide
- Testing checklist for all features
- Interactive test script for easy website testing
- Add ImageCacheEntry structure with timestamp and expiration
- Implement LRU cache for up to 100 images
- Cache images for 10 minutes (configurable)
- Show cache hit count in status message
- Display "cached: N" when loading images from cache
- Automatically evict oldest images when cache is full
- Improves performance by avoiding redundant downloads
Performance improvements:
- Images are only downloaded once within 10 minutes
- Subsequent page views use cached images
- Significantly faster page load times for image-heavy sites
- Parse and store OPTION elements in SELECT fields
- Display selected option text in dropdown UI
- Add SELECT_OPTION input mode for dropdown navigation
- Support Enter on SELECT to enter selection mode
- Use j/k or arrow keys to navigate through options
- Enter to confirm selection, Esc to cancel
- Auto-select first option or option marked with 'selected'
- Real-time option preview in status bar
- Status bar shows "-- SELECT --" mode
Data structure:
- Added options vector to DomNode (value, text pairs)
- Added selected_option index to track current selection
Keyboard shortcuts in SELECT mode:
- j/Down: Next option
- k/Up: Previous option
- Enter: Select current option
- Esc: Cancel selection
- Add FORM_EDIT input mode for editing text fields
- Add actions: NEXT_FIELD, PREV_FIELD, EDIT_TEXT, ACTIVATE_FIELD
- Support 'i' key to focus first form field
- Tab/Shift+Tab to navigate between fields
- Enter on text input fields to edit them
- Real-time text editing with live preview
- Enter/Esc to exit edit mode
- Checkbox toggle support (press Enter on checkbox)
- Status bar shows "-- INSERT --" mode and current text
- Form fields highlighted when active
Keyboard shortcuts:
- i: Focus first form field
- Tab: Next field
- Shift+Tab: Previous field
- Enter: Activate/edit field or toggle checkbox
- Esc: Exit edit mode
- Replace ncurses clear/refresh with ANSI codes for consistency
- Replace ncurses move/curs_set with ANSI cursor control codes
- Improves consistency since colors and attributes already use ANSI codes
- All tests pass successfully
Previously, script and style tags were only filtered during render,
but their text content (JavaScript code) was still in the DOM tree.
Now we skip these tags entirely during DOM tree construction,
resulting in much cleaner output for modern websites.
- Implement HistoryManager for JSON persistence (~/.config/tut/history.json)
- Auto-record page visits with URL, title, and timestamp
- Update visit time when revisiting URLs (move to front)
- Limit to 1000 entries maximum
- Add :history command to view browsing history
- History entries are clickable links
- Add test_history test suite
- Merge browser_v2 implementation into browser.cpp
- Remove deprecated files: browser_v2.cpp/h, main_v2.cpp, text_renderer.cpp/h
- Simplify CMakeLists.txt to build single 'tut' executable
- Remove test HTML files no longer needed
- Add stb_image.h for image support
- Implement curl multi interface for async HTTP in HttpClient
- Add loading spinner animation during page load
- Support Esc key to cancel loading
- Non-blocking main loop with 50ms polling
- Loading state management (IDLE, LOADING_PAGE, LOADING_IMAGES)
- Preserve sync API for backward compatibility
- Add BookmarkManager class for bookmark CRUD operations
- Store bookmarks in JSON format at ~/.config/tut/bookmarks.json
- Add keyboard shortcuts: B (add), D (remove)
- Add :bookmarks/:bm command to view bookmark list
- Bookmarks page shows clickable links
- Auto-save on add/remove, auto-load on startup
- Add image data storage in DomNode for decoded images
- Collect image nodes in DocumentTree during parsing
- Download and decode images in browser_v2 before layout
- Render images as colored ASCII art using True Color
- Use stb_image for PNG/JPEG/GIF/BMP decoding (requires manual download)
- Fall back to placeholder for failed/missing images
Major features:
- New modular architecture with Terminal, FrameBuffer, Renderer layers
- True Color (24-bit) support with warm, eye-friendly color scheme
- Unicode support with proper CJK character width handling
- Differential rendering for improved performance
- Page caching (LRU, 20 pages, 5-minute expiry)
- Search functionality with highlighting (/, n/N)
- Form rendering (input, button, checkbox, radio, select)
- Image placeholder support ([alt text] or [Image: filename])
- Binary data download via fetch_binary()
- Loading state indicators
New files:
- src/browser_v2.cpp/h - Browser with new rendering system
- src/main_v2.cpp - Entry point for tut2
- src/render/* - Terminal, FrameBuffer, Renderer, Layout, Image modules
- src/utils/unicode.cpp/h - Unicode handling utilities
- tests/* - Test programs for each module
Build with: cmake --build build_v2
Run: ./build_v2/tut2 [URL]
Add full support for POST method form submissions alongside existing GET support.
Changes:
- Add HttpClient::post() method with configurable Content-Type
- Implement URL encoding for form data (RFC 3986 compliant)
- Update Browser::submit_form() to detect and handle both GET and POST methods
- Add proper form data encoding with special character handling
- Include Content-Type header for POST requests
Features:
- Automatic method detection from form's method attribute
- URL-encoded form data (application/x-www-form-urlencoded)
- Proper encoding of special characters (spaces, &, =, etc.)
- Status messages for form submission feedback
- History tracking for POST responses
Testing:
- Add test_post_form.html with GET, POST, and special character test cases
- Uses httpbin.org endpoints for validation
Resolves TODO at browser.cpp:238 - POST handling is now fully implemented.
Major improvements:
- Add proper DOM tree structure (dom_tree.cpp/h) with hierarchical node representation
- Refactor HTML parser to use DOM tree instead of flat ContentElement structure
- Enhance text renderer with improved inline content handling and UTF-8 support
- Improve browser interactive element tracking with byte-accurate positioning
- Add comprehensive HTML entity decoding (80+ named entities + numeric)
- Enhance form handling with better field tracking and submission
Code quality improvements:
- Fix all compiler warnings (unused parameters/variables)
- Clean build with zero warnings
- Better separation of concerns between parsing and rendering
Testing:
- Add test_table.html for table rendering verification
This change enables better handling of complex HTML structures while
maintaining the Unix philosophy of simplicity and focus.
Removed ~45% dead code and simplified architecture:
Dead Code Removal (~1,687 LOC):
- calendar.cpp/h - Unused calendar stub
- ics_fetcher.cpp/h - Orphaned ICS fetching
- ics_parser.cpp/h - Abandoned iCalendar parsing
- tui_view.cpp/h - Separate UI implementation
Build System:
- Simplified Makefile to CMake wrapper
- Added install target to CMakeLists.txt
- Improved .gitignore for build artifacts
- Removed Chinese comments, replaced with English
Code Simplification:
- Removed unimplemented features:
* VISUAL/VISUAL_LINE modes (no actual functionality)
* YANK action (copy not implemented)
* Tab support (NEXT_TAB, PREV_TAB, etc.)
* TOGGLE_MOUSE (mouse always enabled)
- Removed process_visual_mode() function (~36 lines)
- Removed gt/gT keybindings for tabs
- Updated help text to remove placeholders
HTML Entity Decoding:
- Made entity list static const (performance)
- Added numeric entity support ({, «)
- Added UTF-8 encoding for decoded entities
- Cleaner, more complete implementation
This brings the browser closer to Unix principles:
- Do one thing well (browse, don't manage calendar)
- Keep it simple (removed over-engineered features)
- Clear, focused codebase (2,058 LOC vs 3,745)
Build tested successfully with only minor warnings.
Add documentation for vim-style marks (m[a-z] to set, '[a-z] to jump)
and mouse support (link clicks, scroll wheel) to match the features
implemented in the previous commit.
- Implement vim-style marks (ma to set, 'a to jump)
* Store mark positions per character (a-z)
* Display status messages when setting/jumping to marks
* Integrated with vim keybinding infrastructure
- Add full mouse support
* Click on links to follow them directly
* Mouse wheel scrolling (up/down)
* Proper click detection within link ranges
* Works with most modern terminal emulators
- Enable ncurses mouse events
* ALL_MOUSE_EVENTS for comprehensive support
* Zero mouseinterval for instant response
* Handle BUTTON1_CLICKED, BUTTON4_PRESSED (wheel up), BUTTON5_PRESSED (wheel down)
- Update help documentation
* Document marks keybindings
* Add mouse support section
* Note infrastructure for visual mode and tabs
This brings TUT closer to feature parity with modern vim plugins
while maintaining excellent usability for both keyboard and mouse users.
* feat: Add table, image, and nested list support to HTML parser
- Add Table, Image, and Form data structures
- Implement table extraction with proper row/column parsing
- Add image extraction with alt text and dimensions
- Implement recursive nested list parsing (ul/ol)
- Support ordered and unordered lists with nesting levels
- Extract list item numbers for ordered lists
- Add HEADING4-6, ORDERED_LIST_ITEM, TABLE, IMAGE element types
This enhancement allows TUT to properly extract and represent
structured content from HTML, enabling better rendering of
data-heavy websites.
* feat: Implement beautiful table and image rendering with box-drawing
- Add Unicode box-drawing characters for table borders (┌─┬─┐, │, etc.)
- Implement table rendering with proper column width calculation
- Add header row styling with heavy borders and bold text
- Support automatic text wrapping within table cells
- Implement image placeholder rendering with bordered boxes
- Display image alt text and dimensions (width × height)
- Enhance list rendering with different bullet styles per nesting level
* Level 0: • (bullet)
* Level 1: ◦ (white bullet)
* Level 2: ▪ (small square)
* Level 3: ▫ (white small square)
- Add ordered list rendering with proper numbering
- Support proper indentation for nested lists
These visual enhancements make TUT significantly more modern and
readable compared to traditional text browsers like w3m.
* feat: Add Vimium-style link hints and vim keybindings infrastructure
- Add LINK_HINTS mode for Vimium-style link navigation
- Implement 'f' key to activate link hints mode
- Add visual mode support (v/V keys)
- Implement marks support (m[a-z] to set, '[a-z] to jump)
- Add tab navigation keys (gt/gT for next/previous tab)
- Add new actions:
* SHOW_LINK_HINTS - activate link hints overlay
* FOLLOW_LINK_HINT - follow link by hint letters
* ENTER_VISUAL_MODE / ENTER_VISUAL_LINE_MODE
* SET_MARK / GOTO_MARK - vim-style position bookmarks
* NEXT_TAB / PREV_TAB - tab navigation
* YANK - copy selected text
This brings modern browser vim plugin functionality (like Vimium)
to the terminal, making link navigation much faster than traditional
tab-through methods.
Major improvements to link handling and navigation:
Features:
- Display links inline with numbered indicators [0], [1], etc.
- Quick navigation: type number + Enter to jump to link
- Fast follow: press 'f' + number to open link directly
- Visual improvements: links shown with underline and highlight
- Remove separate link list at bottom for better readability
Technical changes:
- Add InlineLink structure to track link positions in text
- Implement wrap_text_with_links() for intelligent text wrapping
- Add GOTO_LINK and FOLLOW_LINK_NUM actions
- Implement LINK input mode for 'f' command
- Character-by-character rendering for proper link highlighting
- Update help documentation with new navigation methods
Usage examples:
- 3<Enter> : Jump to link 3
- f5 or 5f : Open link 5 directly
- Tab/Enter : Traditional navigation still works
All comments converted to standard Unix style (English).
Following Unix philosophy and documentation standards:
- Rewrite README.md in man page format (NAME, SYNOPSIS, DESCRIPTION, etc.)
- Remove all Chinese comments from source code
- Keep code clean and self-documenting
- Add PHILOSOPHY section explaining Unix principles
- Include proper EXIT STATUS, ENVIRONMENT, and FILES sections
- Reference related tools in SEE ALSO section
* feat: Add HTTP/HTTPS client module
Implement HTTP client with libcurl for fetching web pages:
- Support for HTTP and HTTPS protocols
- Configurable timeout and user agent
- Automatic redirect following
- SSL certificate verification
- Pimpl pattern for implementation hiding
This module provides the foundation for web page retrieval
in the terminal browser.
* feat: Add HTML parser and content extraction
Implement HTML parser for extracting readable content:
- Parse HTML structure (headings, paragraphs, lists, links)
- Extract and decode HTML entities
- Smart content area detection (article, main, body)
- Relative URL to absolute URL conversion
- Support for both absolute and relative paths
- Filter out scripts, styles, and non-content elements
The parser uses regex-based extraction optimized for
text-heavy websites and documentation.
* feat: Add newspaper-style text rendering engine
Implement text renderer with adaptive layout:
- Adaptive width with maximum 80 characters
- Center-aligned content for comfortable reading
- Smart text wrapping and paragraph spacing
- Color scheme optimized for terminal reading
- Support for headings, paragraphs, lists, and links
- Link indicators with numbering
- Horizontal rules and visual separators
The renderer creates a newspaper-like reading experience
optimized for terminal displays.
* feat: Implement vim-style input handling
Add complete vim-style keyboard navigation:
- Normal mode: hjkl movement, gg/G jump, numeric prefixes
- Command mode: :q, :o URL, :r, :h, :[number]
- Search mode: / for search, n/N for next/previous match
- Link navigation: Tab/Shift-Tab, Enter to follow
- Scroll commands: Ctrl-D/U, Space, b for page up/down
- History navigation: h for back, l for forward
Input handler manages mode transitions and command parsing
with full vim compatibility.
* feat: Implement browser core with TUI interface
Add main browser engine and user interface:
- Page loading with HTTP client integration
- HTML parsing and text rendering pipeline
- History management (back/forward navigation)
- Link selection and following with Tab navigation
- Search functionality with highlighting
- Scrolling with position tracking
- Status bar with mode indicator and progress
- Built-in help page with usage instructions
- Error handling and user feedback
- Support for static HTML websites
The browser provides a complete vim-style terminal
browsing experience optimized for reading text content.
* build: Update build system for terminal browser
Update CMake and add Makefile for the new project:
- Rename project from NBTCA_TUI to TUT
- Update executable name from nbtca_tui to tut
- Add all new source files to build
- Include Makefile for environments without CMake
- Update .gitignore for build artifacts
Both CMake and Make build systems are now supported
for maximum compatibility.
* docs: Complete project transformation to terminal browser
Transform project from ICS calendar viewer to terminal browser:
- Rewrite main.cpp for browser launch with URL argument support
- Complete README rewrite with:
- New project description and features
- Comprehensive keyboard shortcuts documentation
- Installation guide for multiple platforms
- Usage examples and best practices
- JavaScript/SPA limitations explanation
- Architecture overview
- Add help command line option
- Update version to 1.0.0
The project is now TUT (Terminal User Interface Browser),
a vim-style terminal web browser optimized for reading.
- Change trigger from tags to push on main branch
- Add matrix build for macOS and Linux platforms
- Use softprops/action-gh-release for creating releases
- Auto-generate version using date and commit hash
- Upload platform-specific binaries to release
- Fix CMakeLists.txt to conditionally set Homebrew path for macOS only
- Replace Braille spinner with classic ASCII spinner (|/-\)
- Update calendar banner: [CAL] NBTCA CALENDAR [CAL]
- Update tools banner: [TOOL] NBTCA UTILITY TOOLS [TOOL]
- Replace event status icons: * for today, v for past, ○ for upcoming
- Update menu items: [CAL] Calendar, [X] Exit
- Replace location emoji with @ symbol
- Ensure compatibility across all terminal environments including legacy systems