Skip to content
Closed
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
85 changes: 85 additions & 0 deletions .github/workflows/trailing-whitespace-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Trailing Whitespace Check

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
check-trailing-whitespace:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check for trailing whitespace
run: |
echo "Checking for trailing whitespace in changed files..."

# Get the base branch
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"

# Get list of changed files (excluding deleted files)
CHANGED_FILES=$(git diff --name-only --diff-filter=d "$BASE_SHA" "$HEAD_SHA")

if [ -z "$CHANGED_FILES" ]; then
echo "No files to check."
exit 0
fi

# File patterns to check (text files)
PATTERNS="\.cs$|\.csproj$|\.sln$|\.ts$|\.html$|\.css$|\.scss$"

# Directories and file patterns to exclude
EXCLUDE_PATTERNS="(^|\/)(\.|node_modules|bin|obj|artifacts|packages|\.vs|\.nuke\/temp)($|\/)"

ERRORS_FOUND=0
TEMP_FILE=$(mktemp)

while IFS= read -r file; do
# Skip if file doesn't exist (shouldn't happen with --diff-filter=d, but just in case)
if [ ! -f "$file" ]; then
continue
fi

# Check if file matches patterns to check
if ! echo "$file" | grep -qE "$PATTERNS"; then
continue
fi

# Check if file should be excluded
if echo "$file" | grep -qE "$EXCLUDE_PATTERNS"; then
continue
fi

# Find trailing whitespace lines, excluding XML doc placeholder lines that are exactly "/// " (one space)
MATCHES=$(grep -n '[[:space:]]$' "$file" | grep -vE '^[0-9]+:[[:space:]]*/// $' || true)

if [ -n "$MATCHES" ]; then
echo "❌ Trailing whitespace found in: $file"
echo "$MATCHES" | head -10
TOTAL=$(echo "$MATCHES" | wc -l)
if [ "$TOTAL" -gt 10 ]; then
echo " ... and $(($TOTAL - 10)) more lines"
fi
echo "1" >> "$TEMP_FILE"
fi
done <<< "$CHANGED_FILES"

ERRORS_FOUND=$(wc -l < "$TEMP_FILE" 2>/dev/null || echo "0")
rm -f "$TEMP_FILE"

if [ "$ERRORS_FOUND" -gt 0 ]; then
echo ""
echo "❌ Found trailing whitespace in $ERRORS_FOUND file(s)."
echo "Please remove trailing whitespace from the files listed above."
exit 1
else
echo "✅ No trailing whitespace found in changed files."
exit 0
fi
6 changes: 6 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.2.0

## ElectronNET.Core

- Added `IsRunningBlazor` option to `BrowserWindowOptions` (#926)

# 0.1.0

## ElectronNET.Core
Expand Down
82 changes: 66 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,22 @@ To do so, use the `UseElectron` extension method on a `WebApplicationBuilder`, a
using ElectronNET.API;
using ElectronNET.API.Entities;

public static void Main(string[] args)
{
WebHost.CreateDefaultBuilder(args)
.UseElectron(args, ElectronAppReady)
.UseStartup<Startup>()
.Build()
.Run();
}

public static async Task ElectronAppReady()
{
var browserWindow = await Electron.WindowManager.CreateWindowAsync(
new BrowserWindowOptions { Show = false });

browserWindow.OnReadyToShow += () => browserWindow.Show();
}
public static void Main(string[] args)
{
WebHost.CreateDefaultBuilder(args)
.UseElectron(args, ElectronAppReady)
.UseStartup<Startup>()
.Build()
.Run();
}

public static async Task ElectronAppReady()
{
var browserWindow = await Electron.WindowManager.CreateWindowAsync(
new BrowserWindowOptions { Show = false });

browserWindow.OnReadyToShow += () => browserWindow.Show();
}
```

### Minimal API Example
Expand Down Expand Up @@ -113,6 +113,56 @@ app.MapRazorPages();
app.Run();
```

### Blazor

For a project with Blazor you can use:

```cs
using ElectronNET.API;
using ElectronNET.API.Entities;

var builder = WebApplication.CreateBuilder(args);

builder.Services
.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();

builder.Services.AddElectron(); // <-- might be useful to set up DI

builder.UseElectron(args, async () =>
{
var options = new BrowserWindowOptions {
Show = false,
AutoHideMenuBar = true,
IsRunningBlazor = true, // <-- crucial
};
var browserWindow = await Electron.WindowManager.CreateWindowAsync(options);
browserWindow.OnReadyToShow += () => browserWindow.Show();
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
}

app.UseStaticFiles();
app.UseAntiforgery();

app.MapRazorComponents<BlazorApp.Components.App>()
.AddInteractiveWebAssemblyRenderMode();

app.Run();
```

The `IsRunningBlazor` option makes sure to set up the renderer in a way that Blazor can just run without any interference. This includes things such as HMR for development.

## 🚀 Starting and Debugging the Application

Just press `F5` in Visual Studio or use dotnet for debugging.
Expand Down
2 changes: 1 addition & 1 deletion docs/GettingStarted/Console-App.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Add the Electron.NET configuration to your `.csproj` file:
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ElectronNET.Core" Version="0.1.0" />
<PackageReference Include="ElectronNET.Core" Version="0.2.0" />
</ItemGroup>
```

Expand Down
2 changes: 1 addition & 1 deletion nuke/ReleaseNotesParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private IReadOnlyList<ReleaseNotes> ParseComplexFormat(string[] lines)

// Parse content.
var notes = new List<string>();

while (true)
{
// Sanity checks.
Expand Down
26 changes: 14 additions & 12 deletions src/ElectronNET.API/API/ApiBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ReSharper disable InconsistentNaming

namespace ElectronNET.API
{
using Common;
Expand All @@ -17,6 +18,7 @@ protected enum SocketTaskEventNameTypes
DashesLowerFirst,
NoDashUpperFirst
}

protected enum SocketTaskMessageNameTypes
{
DashesLowerFirst,
Expand Down Expand Up @@ -135,12 +137,12 @@ protected Task<T> GetPropertyAsync<T>(object arg = null, [CallerMemberName] stri
}).Task<T>();
}
}

protected void AddEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");
var eventName = EventName(callerName);

var eventKey = EventKey(eventName, id);

lock (objLock)
Expand All @@ -156,7 +158,7 @@ protected void AddEvent(Action value, int? id = null, [CallerMemberName] string
container.Register(value);
}
}

protected void RemoveEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");
Expand All @@ -172,11 +174,11 @@ protected void RemoveEvent(Action value, int? id = null, [CallerMemberName] stri
}
}
}

protected void AddEvent<T>(Action<T> value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");

var eventName = EventName(callerName);
var eventKey = EventKey(eventName, id);

Expand Down Expand Up @@ -222,7 +224,7 @@ private string EventName(string callerName)
throw new ArgumentOutOfRangeException();
}
}

private string EventKey(string eventName, int? id)
{
return string.Format(CultureInfo.InvariantCulture, "{0}{1:D}", eventName, id);
Expand Down Expand Up @@ -257,7 +259,7 @@ public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object
default:
throw new ArgumentOutOfRangeException();
}

switch (apiBase.SocketTaskMessageNameType)
{
case SocketTaskMessageNameTypes.DashesLowerFirst:
Expand Down Expand Up @@ -289,14 +291,14 @@ public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object
}
}
});

if (arg != null)
{
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg);
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg);
}
else
{
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName);
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName);
}

System.Threading.Tasks.Task.Delay(PropertyTimeout).ContinueWith(_ =>
Expand All @@ -321,7 +323,7 @@ public override Task<T1> Task<T1>()
return this.tcsTask as Task<T1>;
}
}

[SuppressMessage("ReSharper", "InconsistentlySynchronizedField")]
private class EventContainer
{
Expand Down Expand Up @@ -370,4 +372,4 @@ public bool Unregister<T>(Action<T> receiver)
}
}
}
}
}
9 changes: 4 additions & 5 deletions src/ElectronNET.API/API/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public event Action WindowAllClosed
private event Action _windowAllClosed;

/// <summary>
/// Emitted before the application starts closing its windows.
/// Emitted before the application starts closing its windows.
/// <para/>
/// Note: If application quit was initiated by <see cref="AutoUpdater.QuitAndInstall"/> then <see cref="BeforeQuit"/>
/// is emitted after emitting close event on all windows and closing them.
Expand Down Expand Up @@ -399,7 +399,6 @@ internal static App Instance
private static object _syncRoot = new object();



/// <summary>
/// Try to close all windows. The <see cref="BeforeQuit"/> event will be emitted first. If all windows are successfully
/// closed, the <see cref="WillQuit"/> event will be emitted and by default the application will terminate. This method
Expand Down Expand Up @@ -558,7 +557,7 @@ public void SetPath(PathName name, string path)
}

/// <summary>
/// The version of the loaded application. If no version is found in the application’s package.json file,
/// The version of the loaded application. If no version is found in the application’s package.json file,
/// the version of the current bundle or executable is returned.
/// </summary>
/// <returns>The version of the loaded application.</returns>
Expand Down Expand Up @@ -1245,7 +1244,7 @@ public Task<string> UserAgentFallbackAsync
return Task.Run(() =>
{
var taskCompletionSource = new TaskCompletionSource<string>();

BridgeConnector.Socket.Once<string>("appGetUserAgentFallbackCompleted", taskCompletionSource.SetResult);
BridgeConnector.Socket.Emit("appGetUserAgentFallback");

Expand Down Expand Up @@ -1295,4 +1294,4 @@ public void Once(string eventName, Action action)
public async Task Once(string eventName, Action<object> action)
=> await Events.Instance.Once(ModuleName, eventName, action).ConfigureAwait(false);
}
}
}
Loading