committed by
GitHub
44 changed files with 481 additions and 301 deletions
@ -0,0 +1,83 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Browser.Interop; |
||||
|
|
||||
|
namespace Avalonia.Browser; |
||||
|
|
||||
|
public class BrowserPlatformOptions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines paths where avalonia modules and service locator should be resolved.
|
||||
|
/// If null, default path resolved depending on the backend (browser or blazor) is used.
|
||||
|
/// </summary>
|
||||
|
public Func<string, string>? FrameworkAssetPathResolver { get; set; } |
||||
|
} |
||||
|
|
||||
|
public static class BrowserAppBuilder |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Configures browser backend, loads avalonia javascript modules and creates a single view lifetime from the passed <see cref="mainDivId"/> parameter.
|
||||
|
/// </summary>
|
||||
|
/// <param name="builder">Application builder.</param>
|
||||
|
/// <param name="mainDivId">ID of the html element where avalonia content should be rendered.</param>
|
||||
|
/// <param name="options">Browser backend specific options.</param>
|
||||
|
public static async Task StartBrowserAppAsync(this AppBuilder builder, string mainDivId, BrowserPlatformOptions? options = null) |
||||
|
{ |
||||
|
if (mainDivId is null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(mainDivId)); |
||||
|
} |
||||
|
|
||||
|
builder = await PreSetupBrowser(builder, options); |
||||
|
|
||||
|
var lifetime = new BrowserSingleViewLifetime(); |
||||
|
builder |
||||
|
.AfterSetup(_ => |
||||
|
{ |
||||
|
lifetime.View = new AvaloniaView(mainDivId); |
||||
|
}) |
||||
|
.SetupWithLifetime(lifetime); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Loads avalonia javascript modules and configures browser backend.
|
||||
|
/// </summary>
|
||||
|
/// <param name="builder">Application builder.</param>
|
||||
|
/// <param name="options">Browser backend specific options.</param>
|
||||
|
/// <remarks>
|
||||
|
/// This method doesn't creates any avalonia views to be rendered. To do so create an <see cref="AvaloniaView"/> object.
|
||||
|
/// Alternatively, you can call <see cref="StartBrowserAppAsync"/> method instead of <see cref="SetupBrowserAppAsync"/>.
|
||||
|
/// </remarks>
|
||||
|
public static async Task SetupBrowserAppAsync(this AppBuilder builder, BrowserPlatformOptions? options = null) |
||||
|
{ |
||||
|
builder = await PreSetupBrowser(builder, options); |
||||
|
|
||||
|
builder |
||||
|
.SetupWithoutStarting(); |
||||
|
} |
||||
|
|
||||
|
internal static async Task<AppBuilder> PreSetupBrowser(AppBuilder builder, BrowserPlatformOptions? options) |
||||
|
{ |
||||
|
options ??= new BrowserPlatformOptions(); |
||||
|
options.FrameworkAssetPathResolver ??= fileName => $"./{fileName}"; |
||||
|
|
||||
|
AvaloniaLocator.CurrentMutable.Bind<BrowserPlatformOptions>().ToConstant(options); |
||||
|
|
||||
|
await AvaloniaModule.ImportMain(); |
||||
|
|
||||
|
if (builder.WindowingSubsystemInitializer is null) |
||||
|
{ |
||||
|
builder = builder.UseBrowser(); |
||||
|
} |
||||
|
|
||||
|
return builder; |
||||
|
} |
||||
|
|
||||
|
public static AppBuilder UseBrowser( |
||||
|
this AppBuilder builder) |
||||
|
{ |
||||
|
return builder |
||||
|
.UseWindowingSubsystem(BrowserWindowingPlatform.Register) |
||||
|
.UseSkia(); |
||||
|
} |
||||
|
} |
||||
@ -1,47 +1,36 @@ |
|||||
using System; |
using System; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
using Avalonia.Controls; |
using Avalonia.Controls; |
||||
using Avalonia.Controls.ApplicationLifetimes; |
using Avalonia.Controls.ApplicationLifetimes; |
||||
using System.Runtime.Versioning; |
using System.Runtime.Versioning; |
||||
|
using Avalonia.Browser; |
||||
|
|
||||
namespace Avalonia.Browser; |
namespace Avalonia; |
||||
|
|
||||
public class BrowserSingleViewLifetime : ISingleViewApplicationLifetime |
internal class BrowserSingleViewLifetime : ISingleViewApplicationLifetime |
||||
{ |
{ |
||||
public AvaloniaView? View; |
public AvaloniaView? View; |
||||
|
|
||||
public Control? MainView |
public Control? MainView |
||||
{ |
{ |
||||
get => View!.Content; |
get |
||||
set => View!.Content = value; |
{ |
||||
} |
EnsureView(); |
||||
} |
return View.Content; |
||||
|
} |
||||
public class BrowserPlatformOptions |
set |
||||
{ |
{ |
||||
public Func<string, string> FrameworkAssetPathResolver { get; set; } = new(fileName => $"./{fileName}"); |
EnsureView(); |
||||
} |
View.Content = value; |
||||
|
} |
||||
public static class WebAppBuilder |
|
||||
{ |
|
||||
public static AppBuilder SetupBrowserApp( |
|
||||
this AppBuilder builder, string mainDivId) |
|
||||
{ |
|
||||
var lifetime = new BrowserSingleViewLifetime(); |
|
||||
|
|
||||
return builder |
|
||||
.UseBrowser() |
|
||||
.AfterSetup(b => |
|
||||
{ |
|
||||
lifetime.View = new AvaloniaView(mainDivId); |
|
||||
}) |
|
||||
.SetupWithLifetime(lifetime); |
|
||||
} |
} |
||||
|
|
||||
public static AppBuilder UseBrowser( |
[MemberNotNull(nameof(View))] |
||||
this AppBuilder builder) |
private void EnsureView() |
||||
{ |
{ |
||||
return builder |
if (View is null) |
||||
.UseWindowingSubsystem(BrowserWindowingPlatform.Register) |
{ |
||||
.UseSkia(); |
throw new InvalidOperationException("Browser lifetime was not initialized. Make sure AppBuilder.StartBrowserApp was called."); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue