using System; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace Wabbajack.Lib.WebAutomation { public enum DisplayMode { Visible, Hidden } public class Driver : IDisposable { private WebAutomationWindow _window; private WebAutomationWindowViewModel _ctx; private Task _windowTask; private Driver(DisplayMode displayMode = DisplayMode.Hidden) { var windowTask = new TaskCompletionSource(); var t = new Thread(() => { _window = new WebAutomationWindow(); _ctx = (WebAutomationWindowViewModel)_window.DataContext; // Initiates the dispatcher thread shutdown when the window closes _window.Closed += (s, e) => _window.Dispatcher.InvokeShutdown(); if (displayMode == DisplayMode.Hidden) { _window.WindowState = WindowState.Minimized; _window.ShowInTaskbar = false; } _window.Show(); windowTask.SetResult(_window); // Makes the thread support message pumping System.Windows.Threading.Dispatcher.Run(); }); _windowTask = windowTask.Task; t.SetApartmentState(ApartmentState.STA); t.Start(); } public static async Task Create() { var driver = new Driver(); driver._window = await driver._windowTask; driver._ctx = (WebAutomationWindowViewModel) driver._window.DataContext; return driver; } public Task NavigateTo(Uri uri) { return _ctx.NavigateTo(uri); } public Task GetLocation() { var tcs = new TaskCompletionSource(); _window.Dispatcher.Invoke(() => tcs.SetResult(_window.WebView.Source)); return tcs.Task; } public Task GetAttr(string selector, string attr) { var tcs = new TaskCompletionSource(); _window.Dispatcher.Invoke(() => { try { var script = $"document.querySelector(\"{selector}\").{attr}"; var result = _window.WebView.InvokeScript("eval", script); tcs.SetResult(result); } catch (Exception ex) { tcs.SetException(ex); } }); return tcs.Task; } public void Dispose() { _window.Dispatcher.Invoke(_window.Close); } } }