Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/Helpers/InteractiveHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.Threading.Tasks;
using Microsoft.Playwright;
using System.Collections.Generic;

public static class InteractiveHelpers
{
public static readonly Dictionary<string, string> KeyboardShortcuts = new()
{
{ "ESC", "Exit interactive mode" },
{ "n", "Go to next page" },
{ "p", "Go to previous page" },
{ "j", "Scroll down" },
{ "k", "Scroll up" },
{ "y", "Copy text under cursor to clipboard" },
{ "h", "Show this help" },
{ "q", "Close browser" }
};

public static void ShowKeyboardShortcuts()
{
Console.WriteLine("\nKeyboard shortcuts in interactive mode:");
Console.WriteLine("------------------------------------");
foreach (var (key, description) in KeyboardShortcuts)
{
Console.WriteLine($"{key,-4} : {description}");
}
Console.WriteLine("\nMouse controls:");
Console.WriteLine("- Click and drag to select text");
Console.WriteLine("- Double click to select word");
Console.WriteLine("- Triple click to select line");
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey(true);
}

public static async Task HandleKeyboardAndMouseEvents(IPage page)
{
// Monitor keyboard events
await page.Keyboard.DownAsync("Control");
await page.Keyboard.PressAsync("Home"); // Scroll to top
await page.Keyboard.UpAsync("Control");

// Example keyboard shortcuts
ConsoleKeyInfo key;
bool exitRequested = false;

while (!exitRequested)
{
if (Console.KeyAvailable)
{
key = Console.ReadKey(true);
switch (key.KeyChar)
{
case 'q':
exitRequested = true;
break;
case 'n':
await page.EvaluateAsync("window.scrollBy(0, window.innerHeight)");
break;
case 'p':
await page.EvaluateAsync("window.scrollBy(0, -window.innerHeight)");
break;
case 'j':
await page.EvaluateAsync("window.scrollBy(0, 100)");
break;
case 'k':
await page.EvaluateAsync("window.scrollBy(0, -100)");
break;
case 'y':
var selectedText = await page.EvaluateAsync<string>(@"() => {
const selection = window.getSelection();
return selection ? selection.toString() : '';
}");
if (!string.IsNullOrEmpty(selectedText))
{
Console.WriteLine($"\nCopied: {selectedText}");
}
break;
case 'h':
ShowKeyboardShortcuts();
break;
case (char)27: // ESC key
exitRequested = true;
break;
}
}

// Short delay to prevent high CPU usage
await Task.Delay(50);
}
}

public static async Task<string> GetTextUnderCursor(IPage page, string selector)
{
var element = await page.QuerySelectorAsync(selector);
if (element != null)
{
return await element.TextContentAsync() ?? string.Empty;
}
return string.Empty;
}
}
27 changes: 23 additions & 4 deletions src/Helpers/PlaywrightHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public static async Task<List<string>> GetWebSearchResultUrlsAsync(string search
// Navigate to the URL
await page.GotoAsync(url);

// If in interactive mode, allow keyboard/mouse interaction
if (interactive)
{
await InteractiveHelpers.HandleKeyboardAndMouseEvents(page);
}

// Fetch the page content and title
var content = await FetchPageContent(page, url, stripHtml, saveToFolder);
var title = await page.TitleAsync();
Expand Down Expand Up @@ -223,13 +229,26 @@ private static async Task<IBrowser> GetBrowser(BrowserType browserType, bool int
{
try
{
return browserType switch
var launchOptions = new BrowserTypeLaunchOptions
{
Headless = !interactive,
Args = interactive ? new[] { "--start-maximized" } : Array.Empty<string>()
};

var browser = browserType switch
{
BrowserType.Chromium => await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = !interactive }),
BrowserType.Firefox => await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions { Headless = !interactive }),
BrowserType.Webkit => await playwright.Webkit.LaunchAsync(new BrowserTypeLaunchOptions { Headless = !interactive }),
BrowserType.Chromium => await playwright.Chromium.LaunchAsync(launchOptions),
BrowserType.Firefox => await playwright.Firefox.LaunchAsync(launchOptions),
BrowserType.Webkit => await playwright.Webkit.LaunchAsync(launchOptions),
_ => throw new ArgumentOutOfRangeException(nameof(browserType), browserType, null)
};

if (interactive)
{
Console.WriteLine("\nEntering interactive mode. Press 'h' for help on keyboard shortcuts.");
}

return browser;
}
catch (Exception)
{
Expand Down
23 changes: 23 additions & 0 deletions src/assets/help/interactive.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Interactive Mode

The interactive mode allows you to navigate web pages using keyboard shortcuts and mouse controls.

Keyboard Shortcuts:
-----------------
ESC : Exit interactive mode
n : Go to next page
p : Go to previous page
j : Scroll down
k : Scroll up
y : Copy text under cursor to clipboard
h : Show keyboard shortcut help
q : Close browser

Mouse Controls:
-------------
- Click and drag to select text
- Double click to select word
- Triple click to select line

To enable interactive mode, use the --interactive flag when running web commands.
Example: mdx web --interactive "your search query"