/// <summary> /// Register the Webview with the specified runime identity. /// If the webview is already registered, it will just /// add an additional identity to the current webview identity list /// </summary> /// <param name="webview"></param> /// <param name="extraIdentity"></param> internal static void RegisterWebView(IBlazorWebView webview, int extraIdentity) { IWebViewIdentity webviewIdentity = WebViewRequirementCheck(webview); try { Tuple <IWebViewIdentity, List <int> > foundTuple = _webviewList.FirstOrDefault(p => p.Item1.GetWebViewIdentity() == webviewIdentity.GetWebViewIdentity()); if (foundTuple == null) { foundTuple = new Tuple <IWebViewIdentity, List <int> >(webviewIdentity, new List <int>()); _webviewList.Add(foundTuple); } if (!foundTuple.Item2.Contains(extraIdentity)) { foundTuple.Item2.Add(extraIdentity); } } catch (Exception) { //Silently ignore //But enforce IWebViewIdentity throwing } }
internal static void InternalLaunchBlazorApp(IBlazorWebView webview) { webview.Source = new UrlWebViewSource() { Url = WebApplicationFactory.GetBaseURL() }; }
private static void LaunchBlazorAppUri(IBlazorWebView webView, int delayedMilliseconds) { Task.Run(async() => { await Task.Delay(delayedMilliseconds); Device.BeginInvokeOnMainThread(() => LaunchBlazorAppUri(webView)); }); }
/// <summary> /// Initializes a new instance of the <see cref="BlazorWebView"/> class. /// </summary> public BlazorWebView() { this.innerBlazorWebView = new BlazorNewEdgeWebView(); this.grid = new Grid(); this.grid.Children.Add((BlazorNewEdgeWebView)this.innerBlazorWebView); this.Content = this.grid; }
internal static IWebViewIdentity WebViewRequirementCheck(IBlazorWebView webview) { if (webview == null) { throw new ArgumentNullException(nameof(webview)); } else if (webview is IWebViewIdentity webIdentity) { return(webIdentity); } else { throw new InvalidOperationException($"{nameof(webview)} must inherit from {nameof(IBlazorWebView)} and {nameof(IWebViewIdentity)}"); } }
public MainPage() { InitializeComponent(); //Blazor WebView agnostic contoller logic IBlazorWebView webview = BlazorWebViewFactory.Create(); //WebView rendering customization on page View webviewView = webview.GetView(); webviewView.VerticalOptions = LayoutOptions.FillAndExpand; webviewView.HorizontalOptions = LayoutOptions.FillAndExpand; webview.LaunchBlazorApp(); content.Children.Add(webviewView); }
internal static void RegisterWebView(IBlazorWebView webview) { IWebViewIdentity identity = WebViewRequirementCheck(webview); try { if (!_webviewList.Any(p => p.Item1.GetWebViewIdentity() == identity.GetWebViewIdentity())) { _webviewList.Add(new Tuple <IWebViewIdentity, List <int> >(identity, new List <int>())); } } catch (Exception) { //Silently ignore //But enforce IWebViewIdentity throwing } }
/// <summary> /// Initialize the BlazorWebView. /// </summary> /// <param name="configure">A delegate that is executed to configure the webview.</param> public void Initialize(Action <WebViewOptions> configure) { try { this.innerBlazorWebView.Initialize(configure); } catch (InvalidOperationException) { this.grid.Children.Remove((BlazorNewEdgeWebView)this.innerBlazorWebView); ((BlazorNewEdgeWebView)this.innerBlazorWebView).Dispose(); // init old edge control. this.innerBlazorWebView = new BlazorOldEdgeWebView(); this.grid.Children.Add((BlazorOldEdgeWebView)this.innerBlazorWebView); this.innerBlazorWebView.Initialize(configure); } }
internal static void LaunchBlazorApp(IBlazorWebView webView) { var webViewService = DependencyService.Get <IWebViewService>(); webViewService.ClearCookies(); switch (Device.RuntimePlatform) { case Device.UWP: //Giving some time on UWP, as it seem to fail to launch the new uri if called too soon LaunchBlazorAppUri(webView, 1000); break; default: LaunchBlazorAppUri(webView); break; } }
internal static void InternalLaunchBlazorApp(IBlazorWebView webview, bool isReload) { webview.Source = new UrlWebViewSource() { Url = WebApplicationFactory.GetBaseURL() }; if (isReload) { var webIdentity = webview as IWebViewIdentity; if (webIdentity != null) { webIdentity.BlazorAppLaunched = false; } webview.Reload(); } }
internal static void InternalLaunchBlazorApp(IBlazorWebView webview, bool isReload) { webview.Source = new UrlWebViewSource() { Url = WebApplicationFactory.GetBaseURL() }; if (isReload) { var webIdentity = webview as IWebViewIdentity; if (webIdentity != null) { webIdentity.BlazorAppLaunched = false; } //May cause some strange behavior if we force Reload, as it can try to reload the current WebView URI instead of the one we just affected here //webview.Reload(); } }
/// <summary> /// Unregister the Webview instance. This must be mainly used at disposal time of the webview /// </summary> /// <param name="webview"></param> internal static void UnregisterWebView(IBlazorWebView webview) { IWebViewIdentity identity = WebViewRequirementCheck(webview); try { int index = _webviewList.FindIndex(p => p.Item1.GetWebViewIdentity() == identity.GetWebViewIdentity()); if (index < 0) { return; } _webviewList.RemoveAt(index); } catch (Exception) { //Silently ignore //But enforce IWebViewIdentity throwing } }
public MainPage() { InitializeComponent(); //Blazor WebView agnostic contoller logic webview = BlazorWebViewFactory.Create(); //WebView rendering customization on page View webviewView = webview.GetView(); webviewView.VerticalOptions = LayoutOptions.FillAndExpand; webviewView.HorizontalOptions = LayoutOptions.FillAndExpand; //Manage your native application behavior when an external resource is requested in your Blazor web application //Customize your app behavior in BlazorMobile.Sample.Handler.OnBlazorWebViewNavigationHandler.cs file or create your own! webview.Navigating += OnBlazorWebViewNavigationHandler.OnBlazorWebViewNavigating; webview.LaunchBlazorApp(); content.Children.Add(webviewView); }
private static void LaunchBlazorAppUri(IBlazorWebView webView) { InternalLaunchBlazorApp(webView, false); }
/// <summary> /// Runs Blazor using the specified <see cref="IBlazorWebView"/> implementation, /// using the path to the index.html host file and optionally a delegate to /// resolve the normal (non framework) resources. /// </summary> /// <typeparam name="TStartup">A startup class.</typeparam> /// <param name="blazorWebView">An <see cref="IBlazorWebView"/> implementation.</param> /// <param name="hostHtmlPath">The specified oath to the index.html file.</param> /// <param name="defaultResolveDelegate">An optional delegate to resolve non framework resources.</param> /// <returns>An <see cref="IDisposable "/> instance that can be used to cleanup Blazor.</returns> public static IDisposable Run <TStartup>(IBlazorWebView blazorWebView, string hostHtmlPath, ResolveWebResourceDelegate defaultResolveDelegate = null) { if (defaultResolveDelegate == null) { var contentRootAbsolute = Path.GetDirectoryName(Path.GetFullPath(hostHtmlPath)); defaultResolveDelegate = (string url, out string contentType, out Encoding encoding) => { // TODO: Only intercept for the hostname 'app' and passthrough for others // TODO: Prevent directory traversal? var appFile = Path.Combine(contentRootAbsolute, new Uri(url).AbsolutePath.Substring(1)); if (appFile == contentRootAbsolute) { appFile = hostHtmlPath; } contentType = GetContentType(appFile); if (!File.Exists(appFile)) { encoding = Encoding.Default; return(null); } return(GetEncodingAndOpen(appFile, out encoding)); }; } BlazorWebView = blazorWebView; BlazorWebView.Initialize(options => { options.SchemeHandlers.Add(BlazorAppScheme, defaultResolveDelegate); // framework:// is resolved as embedded resources options.SchemeHandlers.Add("framework", (string url, out string contentType, out Encoding encoding) => { contentType = GetContentType(url); encoding = Encoding.UTF8; return(SupplyFrameworkFile(url)); }); }); CancellationTokenSource appLifetimeCts = new CancellationTokenSource(); Task.Factory.StartNew(async() => { try { var ipc = new IPC(BlazorWebView); await RunAsync <TStartup>(ipc, appLifetimeCts.Token); } catch (Exception ex) { UnhandledException(ex); throw; } }); try { BlazorWebView.NavigateToUrl(BlazorAppScheme + "://app/"); } catch { appLifetimeCts.Cancel(); throw; } return(new DelegateDisposable(() => appLifetimeCts.Cancel())); }
/// <summary> /// Initializes a new instance of the <see cref="IPC"/> class. /// </summary> /// <param name="blazorWebView">The <see cref="IBlazorWebView"/> to communicate with.</param> public IPC(IBlazorWebView blazorWebView) { this.blazorWebView = blazorWebView ?? throw new ArgumentNullException(nameof(blazorWebView)); this.blazorWebView.OnWebMessageReceived += this.HandleScriptNotify; }