Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ healthchecksdb
/tests/InfiniFrameTests.Playwright.WebApp.Vue/wwwroot/
#/tests/InfiniFrameTests.Playwright.BlazorWebView.MudBlazor/wwwroot/ This needs to be included for Blazor to work

/docs/.docusaurus
/docs/build/
/docs/node_modules/

# Local test/runner virtualenv
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ dotnet tool run infiniframe-pack publish src/MyApp/MyApp.csproj --rid win-x64

### Migration

- [Breaking Changes vs Photino.NET](https://docs.infiniframe.dev/migration/breaking-changes-from-photino) —
- [Breaking Changes vs Photino.NET](https://docs.infiniframe.dev/migration/photino-breaking-changes) —
API, namespace, event system, and behavioral differences from the original Photino projects

### Build Docs Locally
Expand Down
3 changes: 0 additions & 3 deletions docs/.gitignore

This file was deleted.

34 changes: 17 additions & 17 deletions docs/docs/guides/blazor-webview.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Blazor WebView Guide

`InfiniLore.InfiniFrame.BlazorWebView` integrates a full Blazor WebAssembly-style application into a native window with no HTTP server required — the Blazor runtime runs entirely in-process
`InfiniLore.InfiniFrame.BlazorWebView` integrates a full Blazor WebAssembly-style application into a native window with no HTTP server required. The Blazor runtime runs entirely in-process.

## Contents

Expand All @@ -18,8 +18,8 @@

## How It Works

InfiniFrame serves Blazor resources from an internal origin (`app://localhost/`) and handles requests inside the native hostBlazor component files, JavaScript, and CSS are served from an `IFileProvider` backed by your `wwwroot/` folder
There is no external ASP.NET server required; all communication happens through the native browser bridge
InfiniFrame serves Blazor resources from an internal origin (`app://localhost/`) and handles requests inside the native host. Blazor component files, JavaScript, and CSS are served from an `IFileProvider` backed by your `wwwroot/` folder.
There is no external ASP.NET server required; all communication happens through the native browser bridge.

Platform notes:
- Windows uses WebView2 and requires custom-scheme registration support (`ICoreWebView2EnvironmentOptions4`) to allow top-level `app://localhost/...` navigation.
Expand Down Expand Up @@ -61,7 +61,7 @@ A minimal host page:
<div id="blazor-error-ui" style="display:none">
An unhandled error has occurred.
</div>
<script src="_framework/blazor.webview.js" autostart="false"></script>
<script src="_framework/blazor.webview.js"></script>
</body>
</html>
```
Expand All @@ -79,28 +79,28 @@ var builder = InfiniFrameBlazorAppBuilder.CreateDefault(args, w => w
.SetChromeless(true) // Optional: remove native title bar
);

// Register services same as a standard Blazor or ASP.NET Core app
// Register services (same as a standard Blazor or ASP.NET Core app)
builder.Services.AddSingleton<MyDataService>();
builder.Services.AddScoped<IMyRepository, MyRepository>();

// Register root components these map to elements in index.html
// Register root components (these map to elements in index.html)
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Build().Run();
```

`Run()` blocks until the window is closed and then disposes all services
`Run()` blocks until the window is closed and then disposes all services.

## Available Builder API

`InfiniFrameBlazorAppBuilder` exposes three properties for configuration:

| Property | Type | Description |
|------------------|-----------------------------|-------------------------------------------------------------------------------|
| `WindowBuilder` | `IInfiniFrameWindowBuilder` | Fluent window configuration all options from the generated C# API reference |
| `Services` | `IServiceCollection` | Standard .NET DI container |
| `RootComponents` | `RootComponentList` | Maps Blazor components to CSS selectors in index.html |
| Property | Type | Description |
|------------------|-----------------------------|------------------------------------------------------------------------------|
| `WindowBuilder` | `IInfiniFrameWindowBuilder` | Fluent window configuration; all options from the generated C# API reference |
| `Services` | `IServiceCollection` | Standard .NET DI container |
| `RootComponents` | `RootComponentList` | Maps Blazor components to CSS selectors in index.html |

### Configuring the window separately

Expand Down Expand Up @@ -140,7 +140,7 @@ The following services are automatically registered and available for injection:

## Custom File Provider

By default, files are served from `{AppBaseDirectory}/wwwroot/`
By default, files are served from `{AppBaseDirectory}/wwwroot/`.
You can supply a custom `IFileProvider` for embedded resources, encrypted assets, or virtual file systems:

```csharp
Expand Down Expand Up @@ -204,7 +204,7 @@ AppDomain.CurrentDomain.UnhandledException += (_, e) => {

## HttpClient

An `HttpClient` is registered automatically with `BaseAddress` set to the internal app base URI
An `HttpClient` is registered automatically with `BaseAddress` set to the internal app base URI.
This lets you make in-process requests to your static assets or call external APIs:

```razor
Expand Down Expand Up @@ -233,11 +233,11 @@ DisposeAsync() ← Disposes all services

## Custom Window Chrome

Combine with `InfiniLore.InfiniFrame.Blazor` for a fully custom title bar
Combine with `InfiniLore.InfiniFrame.Blazor` for a fully custom title bar.

See the [Custom Window Chrome Guide](custom-window-chrome.md) for details
See the [Custom Window Chrome Guide](custom-window-chrome.md) for details.

## Examples

- `InfiniFrameExample.BlazorWebView` (`examples/InfiniFrameExample.BlazorWebView`) - minimal Blazor app with window configuration and Serilog
- `InfiniFrameExample.BlazorWebView.MultiWindowSample` (`examples/InfiniFrameExample.BlazorWebView.MultiWindowSample`) - multiple windows each hosting a different Blazor component
- `InfiniFrameExample.BlazorWebView.MultiWindowSample` (`examples/InfiniFrameExample.BlazorWebView.MultiWindowSample`) - multiple windows each hosting a different Blazor component
64 changes: 32 additions & 32 deletions docs/docs/guides/core-window.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Core Window Guide

This guide covers everything available through the `InfiniLore.InfiniFrame` packagethe foundation of all InfiniFrame integrations
This guide covers everything available through the `InfiniLore.InfiniFrame` package, the foundation of all InfiniFrame integrations.

## Contents

Expand All @@ -18,7 +18,7 @@ This guide covers everything available through the `InfiniLore.InfiniFrame` pack

## Building a Window

All windows are created through `InfiniFrameWindowBuilder` using a fluent API
All windows are created through `InfiniFrameWindowBuilder` using a fluent API.

```csharp
using InfiniFrame;
Expand All @@ -33,8 +33,8 @@ var window = InfiniFrameWindowBuilder.Create()
window.WaitForClose();
```

`Build()` creates and displays the native window immediately on the calling thread
The returned `IInfiniFrameWindow` gives you full control over the window at runtime
`Build()` creates and displays the native window immediately on the calling thread.
The returned `IInfiniFrameWindow` gives you full control over the window at runtime.

## Single-File Native Packaging

Expand Down Expand Up @@ -65,7 +65,7 @@ Use it for packaged deployments created by `InfiniLore.InfiniFrame.Tools.Pack` (

## Window Configuration

All configuration methods are chainable and must be called before `Build()`
All configuration methods are chainable and must be called before `Build()`.

### Title and Icon

Expand All @@ -79,7 +79,7 @@ builder

```csharp
builder
.SetSize(1280, 720) // Width × Height
.SetSize(1280, 720) // Width x Height
.SetMinSize(800, 600)
.SetMaxSize(1920, 1080)
.SetLocation(100, 100) // Left, Top in screen coordinates
Expand All @@ -88,7 +88,7 @@ builder
.SetUseOsDefaultLocation(true)
```

Calling `SetSize` or `SetLocation` disables the corresponding OS default and centering behavior
Calling `SetSize` or `SetLocation` disables the corresponding OS default and centering behavior.

### Window State

Expand All @@ -103,7 +103,7 @@ builder
.SetTransparent(true) // Enable window transparency
```

On Windows, enabling `SetChromeless` automatically disables `UseOsDefaultLocation`, `UseOsDefaultSize`, and `Resizable` since they are incompatible
On Windows, enabling `SetChromeless` automatically disables `UseOsDefaultLocation`, `UseOsDefaultSize`, and `Resizable` since they are incompatible.

### Content

Expand All @@ -114,7 +114,7 @@ builder
.SetStartString("<html><body>Hello</body></html>") // Render HTML directly
```

`SetStartUrl` and `SetStartString` are mutually exclusivethe last one set wins
`SetStartUrl` and `SetStartString` are mutually exclusive; the last one set wins.

## Browser Features

Expand Down Expand Up @@ -171,19 +171,19 @@ builder
The `SetBrowserControlInitParameters` method passes raw flags to the underlying browser engine:

```csharp
// Windows space-separated Chromium flags
// Windows: space-separated Chromium flags
builder.SetBrowserControlInitParameters("--disable-gpu --no-sandbox")

// Linux JSON object matching WebKit2GTK settings
// Linux: JSON object matching WebKit2GTK settings
builder.SetBrowserControlInitParameters("{ \"enable_developer_extras\": true }")

// macOS JSON object matching WKPreferences keys
// macOS: JSON object matching WKPreferences keys
builder.SetBrowserControlInitParameters("{ \"minimumFontSize\": 12 }")
```

## Runtime Window Control

Once a window is built, `IInfiniFrameWindow` provides methods to control it at runtime
Once a window is built, `IInfiniFrameWindow` provides methods to control it at runtime.

### State and properties

Expand All @@ -196,7 +196,7 @@ window.Focused // Whether the window currently has focus
window.Maximized // (via events, not a direct property at runtime)
window.ScreenDpi // Current DPI

window.Monitors // ImmutableArray<InfiniMonitor> all connected monitors
window.Monitors // ImmutableArray<InfiniMonitor>; all connected monitors
window.MainMonitor // The monitor the window is currently on
```

Expand All @@ -210,7 +210,7 @@ await window.WaitForCloseAsync()

### STA requirement (Windows)

WebView2 is COM-based and requires the thread that calls `Build()` to be STA. Without `[STAThread]`, the window opens but the browser control renders as a black screen, and `Build()` now throws `InvalidOperationException` to surface this early
WebView2 is COM-based and requires the thread that calls `Build()` to be STA. Without `[STAThread]`, the window opens but the browser control renders as a black screen, and `Build()` now throws `InvalidOperationException` to surface this early.

```csharp
// Required for all InfiniFrame apps on Windows
Expand All @@ -226,13 +226,13 @@ internal class Program {
}
```

Top-level statements cannot carry `[STAThread]` so use an explicit `static void Main()` as shown above
Top-level statements cannot carry `[STAThread]` so use an explicit `static void Main()` as shown above.

> **Note:** `[STAThread]` is silently ignored on `async Task Main`. The async continuation runs on thread pool threads (MTA). Never use `async Task Main` as the entry point for an InfiniFrame application. **Linux does not have this restriction** because GTK has no COM apartment model. The native constructor calls `gtk_init()` itself and implicitly claims whichever thread calls `Build()` as the GTK main thread
> **Note:** `[STAThread]` is silently ignored on `async Task Main`. The async continuation runs on thread pool threads (MTA). Never use `async Task Main` as the entry point for an InfiniFrame application. **Linux does not have this restriction** because GTK has no COM apartment model. The native constructor calls `gtk_init()` itself and implicitly claims whichever thread calls `Build()` as the GTK main thread.

### Cross-thread invocation

All UI operations must run on the window's thread — use `Invoke` to marshal work from a background thread:
All UI operations must run on the window's thread. Use `Invoke` to marshal work from a background thread:

```csharp
Task.Run(() => {
Expand All @@ -246,7 +246,7 @@ Task.Run(() => {

## Events

Events are available through `IInfiniFrameWindowEvents`, accessible via `IInfiniFrameWindowBuilder.Events`
Events are available through `IInfiniFrameWindowEvents`, accessible via `IInfiniFrameWindowBuilder.Events`.

```csharp
var builder = InfiniFrameWindowBuilder.Create();
Expand Down Expand Up @@ -281,17 +281,17 @@ Use `WindowClosing` to run cleanup before the window is destroyed:
```csharp
builder.Events.WindowClosing.Add((window, cancel) => {
SaveAppState();
return false; // returning false here does not cancel use WindowClosingRequested for that
return false; // returning false here does not cancel; use WindowClosingRequested for that
});
```

See the generated C# API reference for the full event system documentation
See the generated C# API reference for the full event system documentation.

## Web Messaging

InfiniFrame provides a two-way messaging channel between JavaScript running in the browser control and your C# code
InfiniFrame provides a two-way messaging channel between JavaScript running in the browser control and your C# code.

### C# JavaScript
### C# to JavaScript

```csharp
window.SendWebMessage("hello from C#");
Expand All @@ -306,7 +306,7 @@ window.infiniframe.host.receiveCallback(function(message) {
});
```

### JavaScript C#
### JavaScript to C#

In JavaScript, send with:

Expand All @@ -332,7 +332,7 @@ builder.MessageHandlers.RegisterMessageHandler("ping", (window, _) => {

## Custom URL Schemes

You can intercept requests for custom URL schemes (e.g. `app://`) and serve content from C# codeuseful for loading local assets or implementing a virtual file system
You can intercept requests for custom URL schemes (e.g. `app://`) and serve content from C# code. This is useful for loading local assets or implementing a virtual file system.

```csharp
builder.RegisterCustomSchemeHandler("app", (sender, scheme, url, out string? contentType) => {
Expand All @@ -342,13 +342,13 @@ builder.RegisterCustomSchemeHandler("app", (sender, scheme, url, out string? con
});
```

- Up to 16 custom schemes can be registered before `Build()` is called
- Additional handlers can be added after `Build()` via `window.RegisterCustomSchemeHandler(...)`
- Scheme names are lowercased automatically
- Up to 16 custom schemes can be registered before `Build()` is called.
- Additional handlers can be added after `Build()` via `window.RegisterCustomSchemeHandler(...)`.
- Scheme names are lowercased automatically.

## Dialogs

InfiniFrame exposes the native OS dialog system
InfiniFrame exposes the native OS dialog system.

### Message box

Expand Down Expand Up @@ -395,7 +395,7 @@ All dialogs also have async overloads (`ShowOpenFileAsync`, `ShowSaveFileAsync`,
window.SendNotification("Update available", "A new version is ready to install");
```

Requires `SetNotificationsEnabled()` and `SetNotificationRegistrationId(...)` to be set during configuration
Requires `SetNotificationsEnabled()` and `SetNotificationRegistrationId(...)` to be set during configuration.

## Monitor Information

Expand Down Expand Up @@ -430,10 +430,10 @@ Pass the provider to `Build`:
var window = builder.Build(serviceProvider);
```

`IInfiniFrameWindow` will then be resolvable from the container if registered
`IInfiniFrameWindow` will then be resolvable from the container if registered.

## Examples

- `InfiniFrameExample.WebApp.React` (`examples/InfiniFrameExample.WebApp.React`) - custom URL scheme handler and web messaging with DI-resolved services
- `InfiniFrameExample.BlazorWebView` (`examples/InfiniFrameExample.BlazorWebView`) - window builder configuration with size, position, and icon
- `InfiniFrameExample.SingleFileExe` (`examples/InfiniFrameExample.SingleFileExe`) - embedded static assets and single-file native bootstrap
- `InfiniFrameExample.SingleFileExe` (`examples/InfiniFrameExample.SingleFileExe`) - embedded static assets and single-file native bootstrap
Loading