UnifiedBrowser.Maui (1.1.9)
Installation
dotnet nuget add source --name logikonline --username your_username --password your_token dotnet add package --source logikonline --version 1.1.9 UnifiedBrowser.MauiAbout this package
A comprehensive browser control library for .NET MAUI applications with advanced features including:
- Multi-tab support with state persistence and thumbnails
- Bookmark management with import/export (Netscape HTML format)
- Browsing history with topic filtering and search
- AI-powered page summarization using UnifiedRag.Maui
- Smart link extraction with ad detection
- Markdown rendering with syntax highlighting
- Support for multiple LLM providers (OpenAI, Claude, Together.AI, local models)
- Full data integration with UnifiedData.Maui
- Customizable UI with 30+ bindable properties
- Touch gesture support and responsive design
UnifiedBrowser.Maui
A comprehensive browser control library for .NET MAUI applications with AI-powered summarization, multi-tab support, bookmark management, persistent state, browsing history, and link extraction capabilities.
Features
Core Browser Functionality
- Full WebView integration with MarketAlly.ViewEngine
- Navigation controls (back, forward, home, refresh)
- Address bar with URL entry and search
- Page load status indicators with progress bar
- Customizable user agent and user agent modes
- Multiple platform support (iOS, Android, Windows)
Multi-Tab Support
- Create, switch, and close multiple tabs
- Tab state persistence across app sessions
- Tab thumbnails with automatic capture
- Tab switcher with grid/list view
- Configurable maximum tabs limit
- Drag-to-close gesture support
Bookmark Management
- One-click bookmark toggle for current page
- Visual bookmark indicator (filled/unfilled icon)
- Import/export bookmarks in Netscape HTML format
- Compatible with Chrome, Firefox, Edge, Safari
- Persistent bookmark storage
- Quick access from toolbar
Browsing History
- Automatic history tracking for visited pages
- Filter history by topic and date
- Search through history
- View saved page summaries offline
- Delete individual items or clear all history
- Topic-based organization
Smart Link Extraction
- Automatic link extraction from pages
- Ad detection and filtering
- Link occurrence counting and ranking
- Configurable maximum links (default: 200)
- Copy all links as JSON array
- Filter view to show/hide ads
AI-Powered Summarization
- AI-generated page summaries using UnifiedRag.Maui
- Markdown rendering with syntax highlighting
- Configurable token limits (MaxContextTokens, MaxTokens)
- Support for multiple LLM providers:
- OpenAI (GPT-4, GPT-4o)
- Anthropic Claude
- Together.AI (Llama, Mixtral, etc.)
- Local models via LlamaSharp
- Automatic or on-demand generation
- Summary persistence in database
Data Integration
- Save pages to UnifiedData storage
- Full-text search capabilities
- Vector search with embeddings
- Metadata and topic preservation
- Offline access to saved content
Customizable UI
- 30+ bindable properties
- Toggle individual UI components
- Customizable colors for light/dark themes
- Adjustable toolbar layouts
- MarketAlly MALayout/MAToolbar integration
- Syncfusion ListView for links display
- Touch gesture support
Installation
dotnet add package UnifiedBrowser.Maui
Quick Start
1. Configure in MauiProgram.cs
using UnifiedBrowser.Maui.Extensions;
using CommunityToolkit.Maui;
using Syncfusion.Maui.Core.Hosting;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureSyncfusionCore()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Configure UnifiedBrowser with OpenAI
builder.AddUnifiedBrowser(
openAiApiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"),
modelName: "gpt-4o-mini",
configureBrowser: options =>
{
options.DefaultHomeUrl = "https://www.google.com";
options.EnableAISummarization = true;
}
);
return builder.Build();
}
}
2. Use in XAML
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:browser="clr-namespace:UnifiedBrowser.Maui.Controls;assembly=UnifiedBrowser.Maui">
<browser:UnifiedBrowserControl
HomeUrl="https://www.google.com"
ShowAddressBar="True"
EnableAISummarization="True"
EnableJSONState="True"
BookmarksFilePath="{Binding BookmarksPath}"
MaxRoutes="200"
MaxContextTokens="8192"
MaxTokens="4096" />
</ContentPage>
Configuration Options
Bindable Properties
Navigation & Display
| Property | Type | Default | Description |
|---|---|---|---|
HomeUrl |
string | "https://www.google.com" | Default home page URL |
ShowAddressBar |
bool | true | Show/hide the address bar |
ShowBottomNavigation |
bool | true | Show/hide bottom navigation |
ShowNavigationInAddressBar |
bool | false | Show back/forward in address bar |
AutoLoadHomePage |
bool | true | Auto-load home page on start |
StartWithBlankTab |
bool | false | Start with a blank tab |
UI Components
| Property | Type | Default | Description |
|---|---|---|---|
ShowTabsButton |
bool | true | Show/hide tabs button |
ShowHistoryButton |
bool | true | Show/hide history button |
ShowLinksButton |
bool | true | Show/hide links extraction button |
ShowMarkdownButton |
bool | true | Show/hide markdown view button |
ShowShareButton |
bool | true | Show/hide share button |
ShowSaveButton |
bool | true | Show/hide save button |
ShowRefreshButton |
bool | true | Show/hide refresh button |
ShowHomeButton |
bool | false | Show/hide home button |
ShowSearchButton |
bool | false | Show/hide search button |
Link Extraction
| Property | Type | Default | Description |
|---|---|---|---|
EnableRouteExtraction |
bool | false | Enable automatic route extraction |
NormalizeRoutes |
bool | true | Normalize extracted routes |
EnableAdDetection |
bool | true | Detect and flag ads |
MaxRoutes |
int | 200 | Maximum links to extract |
AI Features
| Property | Type | Default | Description |
|---|---|---|---|
EnableAISummarization |
bool | true | Enable AI features |
AutoGenerateSummary |
bool | false | Auto-generate summary on load |
AutoShowSummaryPane |
bool | false | Auto-show markdown pane when generating new summary |
GeneratingSummaryMessage |
string | "Generating summary..." | Loading message |
MaxContextTokens |
int | 8192 | Max tokens for context |
MaxTokens |
int | 4096 | Max tokens for generation |
State & Storage
| Property | Type | Default | Description |
|---|---|---|---|
EnableJSONState |
bool | false | Enable tab state persistence |
RestoreUrlOnInit |
bool | true | When true, restores saved URLs on init. Set to false to restore state (thumbnails, titles) without auto-navigation |
BookmarksFilePath |
string | null | Path to bookmarks file |
DefaultBookmarkTitle |
string | "MarketAlly" | Default bookmark title |
DefaultBookmarkUrl |
string | "https://www.marketally.com" | Default bookmark URL |
ShowMarkdownHistory |
bool | true | Show markdown in history |
Thumbnails
| Property | Type | Default | Description |
|---|---|---|---|
EnableThumbnailCapture |
bool | true | Enable thumbnail capture |
ThumbnailStoragePath |
string | null | Thumbnail storage location |
ThumbnailWidth |
int | 1280 | Thumbnail width in pixels |
ThumbnailHeight |
int | 720 | Thumbnail height in pixels |
CaptureThumbnailOnNavigation |
bool | true | Auto-capture after navigation |
Appearance
| Property | Type | Default | Description |
|---|---|---|---|
IconColorLight |
Color | #007AFF | Icon color for light theme |
IconColorDark |
Color | #0A84FF | Icon color for dark theme |
ToolbarBackgroundColorLight |
Color | #F5F5F5 | Toolbar color (light) |
ToolbarBackgroundColorDark |
Color | #1C1C1E | Toolbar color (dark) |
Advanced
| Property | Type | Default | Description |
|---|---|---|---|
UserAgent |
string | "" | Custom user agent string |
UserAgentMode |
enum | Default | User agent mode |
Public Methods
Navigation
// Navigate to a URL
browser.NavigateTo("https://example.com");
// Navigation controls
await browser.GoBackAsync();
await browser.GoForwardAsync();
await browser.RefreshAsync();
browser.GoHome();
// Get current state
string url = browser.CurrentUrl;
string content = browser.PageContent;
// Load with optional summary generation
await browser.LoadUrlAsync("https://example.com", generateSummary: true);
Bookmarks
// Add bookmark for current page
await browser.AddBookmarkAsync();
// Add bookmark with specific title and URL
await browser.AddBookmarkAsync("Google", "https://www.google.com");
// Delete bookmark
await browser.DeleteBookmarkAsync("https://example.com");
// Check if bookmarked
bool isBookmarked = browser.IsBookmarked("https://example.com");
// Import/Export
await browser.ImportBookmarksAsync("/path/to/bookmarks.html");
await browser.ExportBookmarksAsync("/path/to/bookmarks.html");
// Get bookmark count and list
int count = browser.GetBookmarkCount();
var bookmarks = browser.GetBookmarks();
Links
// Navigate to ANY URL and get all links in one call
var links = await browser.GetLinksFromUrlAsync("https://news.ycombinator.com");
foreach (var link in links)
{
Console.WriteLine($"{link.Title}: {link.Url}");
}
// Navigate to URL and get FULL page data (content, links, screenshot)
var pageData = await browser.GetPageDataFromUrlAsync(
"https://example.com",
includeScreenshot: true
);
Console.WriteLine($"Title: {pageData.Title}");
Console.WriteLine($"Body: {pageData.Body}");
Console.WriteLine($"Links: {pageData.Links.Count}");
// Extract links from currently loaded page
var currentLinks = await browser.ExtractLinksAsync();
foreach (var link in currentLinks)
{
Console.WriteLine($"{link.Title}: {link.Url}");
Console.WriteLine($" Occurrences: {link.Occurrences}");
Console.WriteLine($" Is Ad: {link.IsPotentialAd}");
}
// Show links view in UI
browser.ShowLinks();
AI Summarization
// Show summary view and generate summary in one call
string summary = await browser.ShowSummaryAsync();
// Force regenerate even if summary exists
string freshSummary = await browser.ShowSummaryAsync(forceRegenerate: true);
// Hide summary and return to web view
browser.HideSummary();
// Generate summary without showing the view
string summary = await browser.GenerateSummaryAsync();
// Load URL with auto-summary
await browser.LoadUrlAsync("https://example.com", generateSummary: true);
// Just toggle the markdown view (won't auto-generate)
browser.ShowMarkdownView();
Page Data & Screenshots (AI/Developer Integration)
// Get comprehensive page data for AI processing
var pageData = await browser.GetCurrentPageDataAsync();
Console.WriteLine($"URL: {pageData.Url}");
Console.WriteLine($"Title: {pageData.Title}");
Console.WriteLine($"Body Text: {pageData.Body}");
Console.WriteLine($"Meta Description: {pageData.MetaDescription}");
Console.WriteLine($"Links Count: {pageData.Links.Count}");
Console.WriteLine($"AI Summary: {pageData.Summary}");
Console.WriteLine($"Is Loading: {pageData.IsLoading}");
Console.WriteLine($"Is Bookmarked: {pageData.IsBookmarked}");
// Get page data with screenshot
var pageDataWithScreenshot = await browser.GetCurrentPageDataAsync(
includeScreenshot: true,
includeLinks: true
);
if (pageDataWithScreenshot.Screenshot != null)
{
MyImage.Source = pageDataWithScreenshot.Screenshot;
}
// Capture screenshot only (high resolution)
var screenshot = await browser.CaptureScreenshotAsync(1920, 1080);
// Capture screenshot with default size (1280x720)
var thumbnail = await browser.CaptureScreenshotAsync();
// Access the underlying WebView for advanced scenarios
var webView = browser.GetWebView();
BrowserPageData Properties
| Property | Type | Description |
|---|---|---|
Url |
string | Current page URL |
Title |
string | Page title |
Body |
string | Raw text content of the page |
MetaDescription |
string | Meta description tag content |
Links |
List | All extracted links |
BodyLinks |
List | Links in the body content |
Summary |
string? | AI-generated summary (if available) |
IsLoading |
bool | Whether the page is loading |
IsBookmarked |
bool | Whether the page is bookmarked |
Screenshot |
ImageSource? | Page screenshot (if captured) |
CapturedAt |
DateTime | Timestamp when data was captured |
Thumbnails
// Capture thumbnail for current tab
await browser.CaptureTabThumbnailAsync();
// Configure thumbnail settings
browser.ThumbnailWidth = 1024;
browser.ThumbnailHeight = 576;
browser.CaptureThumbnailOnNavigation = true;
DOM Interaction API (AI/Automation)
Interact with page elements programmatically for AI-driven automation:
// Click an element
await browser.ClickElementAsync("#submit-button");
await browser.ClickElementAsync("button.primary");
// Fill input fields
await browser.FillInputAsync("#username", "user@example.com");
await browser.FillInputAsync("input[name='password']", "secret123");
// Get element text and attributes
string text = await browser.GetElementTextAsync("h1.title");
string href = await browser.GetElementAttributeAsync("a.link", "href");
// Scroll to an element
await browser.ScrollToElementAsync("#section-2", "smooth");
// Wait for an element to appear (useful for SPAs)
bool appeared = await browser.WaitForElementAsync(".loading-complete", timeoutMs: 5000);
// Check if element exists
bool exists = await browser.ElementExistsAsync("#dynamic-content");
// Focus an input
await browser.FocusElementAsync("#search-input");
// Execute custom JavaScript
string result = await browser.ExecuteJavaScriptAsync("document.title");
Form Handling
Extract and interact with forms:
// Extract all forms from the page
List<FormInfo> forms = await browser.ExtractFormsAsync();
foreach (var form in forms)
{
Console.WriteLine($"Form: {form.Id ?? form.Name ?? "unnamed"}");
Console.WriteLine($" Action: {form.Action}");
Console.WriteLine($" Method: {form.Method}");
Console.WriteLine($" Fields: {form.Fields.Count}");
foreach (var field in form.Fields)
{
Console.WriteLine($" - {field.Name}: {field.Type} ({field.Label})");
}
}
// Fill a form with multiple values
await browser.FillFormAsync("form#login", new Dictionary<string, string>
{
{ "username", "user@example.com" },
{ "password", "secret123" },
{ "remember", "true" }
});
// Submit a form
await browser.SubmitFormAsync("form#login");
Page Analysis for AI
Analyze the page to understand available actions:
// Get all clickable elements
List<ClickableElement> clickables = await browser.GetClickableElementsAsync();
foreach (var el in clickables)
{
Console.WriteLine($"{el.TagName}: {el.Text} ({el.Selector})");
}
// Comprehensive page analysis
PageAnalysis analysis = await browser.AnalyzePageForActionsAsync();
Console.WriteLine($"URL: {analysis.Url}");
Console.WriteLine($"Is Login Page: {analysis.IsLoginPage}");
Console.WriteLine($"Is Search Page: {analysis.IsSearchPage}");
Console.WriteLine($"Has Checkout: {analysis.HasCheckoutForm}");
Console.WriteLine($"Forms: {analysis.Forms.Count}");
Console.WriteLine($"Clickable Elements: {analysis.ClickableElements.Count}");
// AI can use suggested actions
foreach (var action in analysis.SuggestedActions)
{
Console.WriteLine($"Suggested: {action.ActionType} - {action.Description}");
Console.WriteLine($" Selector: {action.Selector}");
Console.WriteLine($" Priority: {action.Priority}");
}
PageAnalysis Properties
| Property | Type | Description |
|---|---|---|
Url |
string | Current page URL |
Title |
string | Page title |
Forms |
List | All forms on the page |
ClickableElements |
List | Buttons, links, etc. |
NavigationLinks |
List | Nav menu links |
IsLoginPage |
bool | Detected as login page |
IsSearchPage |
bool | Detected as search page |
HasCheckoutForm |
bool | Has payment form |
SuggestedActions |
List | AI action suggestions |
FormInfo Properties
| Property | Type | Description |
|---|---|---|
Selector |
string | CSS selector for the form |
Id |
string? | Form ID attribute |
Name |
string? | Form name attribute |
Action |
string? | Form action URL |
Method |
string | GET or POST |
Fields |
List | Input fields |
ClickableElement Properties
| Property | Type | Description |
|---|---|---|
Selector |
string | CSS selector |
TagName |
string | HTML tag (a, button, etc.) |
Text |
string | Visible text |
Href |
string? | Link URL (for anchors) |
IsVisible |
bool | Currently visible |
IsDisabled |
bool | Disabled state |
BoundingRect |
ElementRect? | Position and size |
Events
// Navigation events
browser.Navigating += (sender, e) =>
{
Console.WriteLine($"Navigating to: {e.Url}");
// Can cancel: e.Cancel = true;
};
browser.Navigated += (sender, e) =>
{
Console.WriteLine($"Navigated: {e.Url} - {e.Result}");
};
browser.PageLoadComplete += (sender, e) =>
{
Console.WriteLine("Page fully loaded");
};
// Page data changes
browser.PageDataChanged += (sender, pageData) =>
{
Console.WriteLine($"Title: {pageData.Title}");
Console.WriteLine($"Links: {pageData.BodyRoutes?.Count ?? 0}");
};
// Link selection
browser.LinkSelected += (sender, e) =>
{
Console.WriteLine($"Selected: {e.SelectedLink.Url}");
};
// Page title changes
browser.PageTitleChanged += (sender, e) =>
{
Console.WriteLine($"Title: {e.Title}");
};
// Summary generation
browser.SummaryGenerated += (sender, e) =>
{
Console.WriteLine($"Summary: {e.Summary}");
};
// Action events (for AI/automation monitoring)
browser.ActionRequested += (sender, e) =>
{
Console.WriteLine($"Action requested: {e.ActionType} on {e.Selector}");
// Can cancel: e.Cancel = true;
};
browser.ActionCompleted += (sender, e) =>
{
Console.WriteLine($"Action completed: {e.ActionType}");
Console.WriteLine($" Success: {e.Success}");
Console.WriteLine($" Duration: {e.Duration.TotalMilliseconds}ms");
if (!e.Success)
Console.WriteLine($" Error: {e.ErrorMessage}");
};
Tab State Persistence
Enable automatic tab state saving and restoration:
browser.EnableJSONState = true;
browser.ThumbnailStoragePath = Path.Combine(
FileSystem.AppDataDirectory,
"thumbnails"
);
State includes:
- All open tabs with URLs and titles
- Active tab selection
- Tab thumbnails
- Last accessed timestamps
Storage locations:
- Android:
/data/data/[app]/files/browser_tabs_state.json - iOS:
[sandbox]/Documents/browser_tabs_state.json
Bookmark Management
Configure bookmark storage:
browser.BookmarksFilePath = Path.Combine(
FileSystem.AppDataDirectory,
"bookmarks.html"
);
browser.DefaultBookmarkTitle = "MyApp";
browser.DefaultBookmarkUrl = "https://myapp.com";
Features:
- Netscape Bookmark HTML format (cross-browser compatible)
- Import from Chrome, Firefox, Edge, Safari
- Export for backup or sharing
- Automatic persistence
- Visual bookmark indicator in toolbar
Browsing History
History is automatically tracked when UnifiedData service is configured. Pages are saved when:
- AI summary is generated
- User explicitly saves the page
- Page content is stored for offline access
History features:
- Filter by topic or date
- Search through history
- View saved summaries offline
- Delete individual items
- Clear all history
- Organized by creation date
Access history through the toolbar history button or programmatically through UnifiedDataService.
Provider Setup Options
OpenAI
builder.AddUnifiedBrowser(
openAiApiKey: "your-api-key",
modelName: "gpt-4o-mini"
);
Anthropic Claude
builder.AddUnifiedBrowserWithClaude(
anthropicApiKey: "your-api-key",
modelName: "claude-3-5-sonnet-20241022"
);
Together.AI
builder.AddUnifiedBrowserWithTogetherAI(
togetherApiKey: "your-api-key",
modelName: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
);
Local Model
builder.AddUnifiedBrowserWithLocalModel(
modelPath: "/path/to/model.gguf",
maxTokens: 512
);
Basic (No AI)
builder.AddUnifiedBrowserBasic();
Custom Provider
builder.AddUnifiedBrowserCustom(
configureServices: services =>
{
// Add your own IRAGService implementation
services.AddSingleton<IRAGService, MyCustomRAGService>();
},
configureBrowser: options =>
{
options.DefaultHomeUrl = "https://myapp.com";
}
);
Dynamic Settings (App-Provided IProviderSettings)
// Register your settings adapter first
builder.Services.AddSingleton<IProviderSettings, MySettingsAdapter>();
// Then add browser with dynamic settings
builder.AddUnifiedBrowserWithDynamicSettings(
configureBrowser: options =>
{
options.DefaultHomeUrl = "https://myapp.com";
}
);
Runtime Settings (Built-in RuntimeProviderSettings)
// Initial setup with runtime-updateable settings
builder.AddUnifiedBrowserWithRuntimeSettings(
provider: "openai",
apiKey: "sk-...",
modelName: "gpt-4o-mini",
configureBrowser: options =>
{
options.DefaultHomeUrl = "https://myapp.com";
}
);
// Later, update settings at runtime:
var settings = serviceProvider.GetRequiredService<RuntimeProviderSettings>();
// Update just the API key
await settings.UpdateApiKeyAsync("sk-new-key");
// Or switch to a different provider entirely
await settings.SwitchProviderAsync(
provider: "anthropic",
apiKey: "sk-ant-...",
modelName: "claude-3-5-sonnet-20241022"
);
XAML Instantiation with Lazy Service Resolution
When you create the control in XAML (without DI), services are automatically resolved from the DI container when needed:
<!-- In XAML - services will be resolved lazily -->
<browser:UnifiedBrowserControl
HomeUrl="https://www.google.com"
EnableAISummarization="True" />
How it works:
- When the control is created in XAML, the default constructor is used
- Services (
IRAGService,IUnifiedDataService) are resolved lazily fromApplication.Current.Handler.MauiContext.Services - Resolution happens automatically when AI features are first used (e.g., clicking Summarize)
- If you registered services via
AddUnifiedBrowserWithDynamicSettings()or other methods, they will be available
This means you can:
- Configure services in
MauiProgram.csusing anyAddUnifiedBrowser*method - Create the control in XAML without constructor parameters
- AI features will work automatically when the user interacts with them
// In MauiProgram.cs
builder.Services.AddSingleton<IProviderSettings, MySettingsAdapter>();
builder.AddUnifiedBrowserWithDynamicSettings();
// In XAML - just use the control, services resolve automatically
// <browser:UnifiedBrowserControl EnableAISummarization="True" />
Use Cases
Research Browser with History
var browser = new UnifiedBrowserControl
{
EnableAISummarization = true,
AutoGenerateSummary = true,
ShowSaveButton = true,
EnableJSONState = true,
MaxContextTokens = 16384,
MaxTokens = 8192
};
Document Viewer with Bookmarks
var browser = new UnifiedBrowserControl
{
HomeUrl = "https://docs.company.com",
ShowAddressBar = false,
ShowMarkdownButton = true,
EnableAISummarization = true,
BookmarksFilePath = Path.Combine(
FileSystem.AppDataDirectory,
"bookmarks.html"
)
};
Link Aggregator
var browser = new UnifiedBrowserControl
{
ShowLinksButton = true,
EnableRouteExtraction = true,
EnableAdDetection = true,
MaxRoutes = 500
};
Architecture
UnifiedBrowser.Maui/
├── Controls/
│ ├── UnifiedBrowserControl.xaml # Main control XAML
│ ├── UnifiedBrowserControl.xaml.cs # Control code-behind
│ ├── UnifiedBrowserControl.BindableProperties.cs
│ ├── UnifiedBrowserControl.Events.cs
│ ├── UnifiedBrowserControl.Initialization.cs
│ └── UnifiedBrowserControl.Platform.cs
├── Extensions/
│ ├── MauiAppBuilderExtensions.cs # UseUnifiedBrowser()
│ ├── ServiceCollectionExtensions.cs # AddUnifiedBrowser*()
│ └── WebViewPoolExtensions.cs
├── Models/
│ ├── BrowserTab.cs
│ ├── LinkItem.cs
│ ├── TabState.cs
│ └── BookmarkItemViewModel.cs
├── Services/
│ ├── BookmarkManager.cs
│ ├── TabManager.cs
│ └── WebViewPool.cs
├── ViewModels/
│ └── BrowserViewModel.cs
├── Views/
│ ├── HistoryView.xaml
│ └── TabSwitcherView.xaml
├── Converters/
│ ├── AdBackgroundColorConverter.cs
│ ├── InvertedBoolConverter.cs
│ └── ...
└── Bookmarks/
└── NetscapeBookmarks.cs # Import/export
Dependencies
| Package | Version | Purpose |
|---|---|---|
| Microsoft.Maui.Controls | 9.0.x | MAUI framework |
| CommunityToolkit.Maui | 12.x | MAUI extensions |
| CommunityToolkit.Mvvm | 8.x | MVVM toolkit |
| Syncfusion.Maui.ListView | 31.x | List views for links |
| Syncfusion.Maui.Core | 31.x | Syncfusion core |
| MarketAlly.ViewEngine | 2.x | Enhanced WebView |
| MarketAlly.MALayout | 3.x | Adaptive layout |
| MarketAlly.MAToolbar | 1.x | Toolbar controls |
| MarketAlly.Dialogs.Maui | 1.x | Dialogs |
| MarketAlly.TouchEffect.Maui | 1.x | Touch gestures |
| Markdig | 0.43.x | Markdown rendering |
| SkiaSharp | 2.88.x | Image processing |
| UnifiedRag.Maui | - | AI/RAG services (project reference) |
Platform Support
| Platform | Version | Status |
|---|---|---|
| iOS | 11.0+ | Fully supported |
| Android | API 24+ | Fully supported |
| Windows | 10.0.19041+ | Supported |
Performance Considerations
- AI Summarization: On-demand to avoid unnecessary API calls
- Link Extraction: Limited to configurable maximum (default 200)
- Content Extraction: Configurable token limits for summarization
- Tab State: Saved asynchronously to avoid UI blocking
- Thumbnails: Captured at configurable resolution, uses SkiaSharp for resizing
- History: Indexed for fast search and filtering
- WebView Pool: Reuses WebView instances to reduce memory allocation
License
This project is licensed under the MIT License.
Author
David H Friedel Jr
Company
MarketAlly
Support
For issues, questions, or feature requests, please open an issue on the repository.
Built by the MarketAlly team for the .NET MAUI community.
v1.1.0 - AI/Developer Integration Release: NEW: DOM Interaction API for AI automation
- ClickElementAsync, FillInputAsync, GetElementTextAsync
- ScrollToElementAsync, WaitForElementAsync, FocusElementAsync
- ExecuteJavaScriptAsync for custom scripts NEW: Form Handling
- ExtractFormsAsync - get all forms with field details
- FillFormAsync - fill multiple fields at once
- SubmitFormAsync - submit forms programmatically NEW: Page Analysis for AI
- GetClickableElementsAsync - find all buttons/links
- AnalyzePageForActionsAsync - comprehensive page analysis
- Auto-detection of login, search, and checkout pages
- AI-suggested actions with priority ranking NEW: Convenience Methods
- GetLinksFromUrlAsync(url) - navigate and get links in one call
- GetPageDataFromUrlAsync(url) - navigate and get full page data
- GetCurrentPageDataAsync - get BrowserPageData with all info
- CaptureScreenshotAsync - capture page screenshots
- ShowSummaryAsync - show and generate summary in one call NEW: Action Events
- ActionRequested - monitor/cancel actions before execution
- ActionCompleted - track action results and timing NEW: Models
- BrowserPageData, FormInfo, ClickableElement, PageAnalysis
Dependencies
| ID | Version | Target Framework |
|---|---|---|
| UnifiedRag.Maui | 1.1.3 | net9.0-android35.0 |
| CommunityToolkit.Maui | 12.3.0 | net9.0-android35.0 |
| CommunityToolkit.Mvvm | 8.4.0 | net9.0-android35.0 |
| Markdig | 0.43.0 | net9.0-android35.0 |
| MarketAlly.Dialogs.Maui | 1.5.0 | net9.0-android35.0 |
| MarketAlly.MABottomSheet | 1.3.0 | net9.0-android35.0 |
| MarketAlly.MALayout | 3.6.4 | net9.0-android35.0 |
| MarketAlly.MAToolbar | 1.9.9 | net9.0-android35.0 |
| MarketAlly.TouchEffect.Maui | 1.0.0 | net9.0-android35.0 |
| MarketAlly.ViewEngine | 2.5.1 | net9.0-android35.0 |
| Microsoft.Extensions.Logging.Abstractions | 9.0.10 | net9.0-android35.0 |
| Microsoft.Maui.Controls | 9.0.120 | net9.0-android35.0 |
| Microsoft.Maui.Controls.Compatibility | 9.0.120 | net9.0-android35.0 |
| SkiaSharp | 2.88.8 | net9.0-android35.0 |
| SkiaSharp.Views.Maui.Controls | 2.88.8 | net9.0-android35.0 |
| Syncfusion.Maui.Core | 31.2.5 | net9.0-android35.0 |
| Syncfusion.Maui.DataSource | 31.2.5 | net9.0-android35.0 |
| Syncfusion.Maui.ListView | 31.2.5 | net9.0-android35.0 |
| UnifiedRag.Maui | 1.1.3 | net9.0-ios18.0 |
| CommunityToolkit.Maui | 12.3.0 | net9.0-ios18.0 |
| CommunityToolkit.Mvvm | 8.4.0 | net9.0-ios18.0 |
| Markdig | 0.43.0 | net9.0-ios18.0 |
| MarketAlly.Dialogs.Maui | 1.5.0 | net9.0-ios18.0 |
| MarketAlly.MABottomSheet | 1.3.0 | net9.0-ios18.0 |
| MarketAlly.MALayout | 3.6.4 | net9.0-ios18.0 |
| MarketAlly.MAToolbar | 1.9.9 | net9.0-ios18.0 |
| MarketAlly.TouchEffect.Maui | 1.0.0 | net9.0-ios18.0 |
| MarketAlly.ViewEngine | 2.5.1 | net9.0-ios18.0 |
| Microsoft.Extensions.Logging.Abstractions | 9.0.10 | net9.0-ios18.0 |
| Microsoft.Maui.Controls | 9.0.120 | net9.0-ios18.0 |
| Microsoft.Maui.Controls.Compatibility | 9.0.120 | net9.0-ios18.0 |
| SkiaSharp | 2.88.8 | net9.0-ios18.0 |
| SkiaSharp.Views.Maui.Controls | 2.88.8 | net9.0-ios18.0 |
| Syncfusion.Maui.Core | 31.2.5 | net9.0-ios18.0 |
| Syncfusion.Maui.DataSource | 31.2.5 | net9.0-ios18.0 |
| Syncfusion.Maui.ListView | 31.2.5 | net9.0-ios18.0 |
| UnifiedRag.Maui | 1.1.3 | net9.0-windows10.0.19041 |
| CommunityToolkit.Maui | 12.3.0 | net9.0-windows10.0.19041 |
| CommunityToolkit.Mvvm | 8.4.0 | net9.0-windows10.0.19041 |
| Markdig | 0.43.0 | net9.0-windows10.0.19041 |
| MarketAlly.Dialogs.Maui | 1.5.0 | net9.0-windows10.0.19041 |
| MarketAlly.MABottomSheet | 1.3.0 | net9.0-windows10.0.19041 |
| MarketAlly.MALayout | 3.6.4 | net9.0-windows10.0.19041 |
| MarketAlly.MAToolbar | 1.9.9 | net9.0-windows10.0.19041 |
| MarketAlly.TouchEffect.Maui | 1.0.0 | net9.0-windows10.0.19041 |
| MarketAlly.ViewEngine | 2.5.1 | net9.0-windows10.0.19041 |
| Microsoft.Extensions.Logging.Abstractions | 9.0.10 | net9.0-windows10.0.19041 |
| Microsoft.Maui.Controls | 9.0.120 | net9.0-windows10.0.19041 |
| Microsoft.Maui.Controls.Compatibility | 9.0.120 | net9.0-windows10.0.19041 |
| SkiaSharp | 2.88.8 | net9.0-windows10.0.19041 |
| SkiaSharp.Views.Maui.Controls | 2.88.8 | net9.0-windows10.0.19041 |
| Syncfusion.Maui.Core | 31.2.5 | net9.0-windows10.0.19041 |
| Syncfusion.Maui.DataSource | 31.2.5 | net9.0-windows10.0.19041 |
| Syncfusion.Maui.ListView | 31.2.5 | net9.0-windows10.0.19041 |