diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 093dc5f7..74608323 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ env: jobs: linux: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -26,6 +27,7 @@ jobs: windows: runs-on: windows-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 diff --git a/src/ElectronNET.API/API/ApiBase.cs b/src/ElectronNET.API/API/ApiBase.cs index 1019d7b7..ec63c743 100644 --- a/src/ElectronNET.API/API/ApiBase.cs +++ b/src/ElectronNET.API/API/ApiBase.cs @@ -1,37 +1,49 @@ -namespace ElectronNET.API +// ReSharper disable InconsistentNaming +namespace ElectronNET.API { - using ElectronNET.API.Serialization; - using ElectronNET.Common; + using Common; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Runtime.CompilerServices; - using System.Text.Json; using System.Threading.Tasks; public abstract class ApiBase { - protected enum SocketEventNameTypes + protected enum SocketTaskEventNameTypes + { + DashesLowerFirst, + NoDashUpperFirst + } + protected enum SocketTaskMessageNameTypes { DashesLowerFirst, - NoDashUpperFirst, + NoDashUpperFirst } - internal const int PropertyTimeout = 1000; + protected enum SocketEventNameTypes + { + DashedLower, + CamelCase, + } + + private const int PropertyTimeout = 1000; private readonly string objectName; - private readonly ConcurrentDictionary propertyGetters = new ConcurrentDictionary(); - private readonly ConcurrentDictionary propertyEventNames = new ConcurrentDictionary(); - private readonly ConcurrentDictionary propertyMessageNames = new ConcurrentDictionary(); - private readonly ConcurrentDictionary methodMessageNames = new ConcurrentDictionary(); + private readonly ConcurrentDictionary propertyGetters; + private readonly ConcurrentDictionary propertyEventNames = new(); + private readonly ConcurrentDictionary propertyMessageNames = new(); + private readonly ConcurrentDictionary methodMessageNames = new(); + private static readonly ConcurrentDictionary eventContainers = new(); + private static readonly ConcurrentDictionary> AllPropertyGetters = new(); + private readonly object objLock = new object(); public virtual int Id { - get - { - return -1; - } + get => -1; // ReSharper disable once ValueParameterNotUsed protected set @@ -39,11 +51,14 @@ protected set } } - protected abstract SocketEventNameTypes SocketEventNameType { get; } + protected abstract SocketTaskEventNameTypes SocketTaskEventNameType { get; } + protected virtual SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.NoDashUpperFirst; + protected virtual SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; protected ApiBase() { this.objectName = this.GetType().Name.LowerFirst(); + propertyGetters = AllPropertyGetters.GetOrAdd(objectName, _ => new ConcurrentDictionary()); } protected void CallMethod0([CallerMemberName] string callerName = null) @@ -98,7 +113,7 @@ protected void CallMethod3(object val1, object val2, object val3, [CallerMemberN } } - protected Task GetPropertyAsync([CallerMemberName] string callerName = null) + protected Task GetPropertyAsync(object arg = null, [CallerMemberName] string callerName = null) { Debug.Assert(callerName != null, nameof(callerName) + " != null"); @@ -106,7 +121,7 @@ protected Task GetPropertyAsync([CallerMemberName] string callerName = nul { return this.propertyGetters.GetOrAdd(callerName, _ => { - var getter = new PropertyGetter(this, callerName, PropertyTimeout); + var getter = new PropertyGetter(this, callerName, PropertyTimeout, arg); getter.Task().ContinueWith(_ => { @@ -120,6 +135,98 @@ protected Task GetPropertyAsync([CallerMemberName] string callerName = nul }).Task(); } } + + 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) + { + var container = eventContainers.GetOrAdd(eventKey, _ => + { + var container = new EventContainer(); + BridgeConnector.Socket.On(eventKey, container.OnEventAction); + BridgeConnector.Socket.Emit($"register-{eventName}", id); + return container; + }); + + container.Register(value); + } + } + + protected void RemoveEvent(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) + { + if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value)) + { + BridgeConnector.Socket.Off(eventKey); + eventContainers.TryRemove(eventKey, out _); + } + } + } + + 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) + { + var container = eventContainers.GetOrAdd(eventKey, _ => + { + var container = new EventContainer(); + BridgeConnector.Socket.On(eventKey, container.OnEventActionT); + BridgeConnector.Socket.Emit($"register-{eventName}", id); + return container; + }); + + container.Register(value); + } + } + + protected void RemoveEvent(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) + { + if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value)) + { + BridgeConnector.Socket.Off(eventKey); + eventContainers.TryRemove(eventKey, out _); + } + } + } + + private string EventName(string callerName) + { + switch (SocketEventNameType) + { + case SocketEventNameTypes.DashedLower: + return $"{objectName}-{callerName.ToDashedEventName()}"; + case SocketEventNameTypes.CamelCase: + return $"{objectName}-{callerName.ToCamelCaseEventName()}"; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private string EventKey(string eventName, int? id) + { + return string.Format(CultureInfo.InvariantCulture, "{0}{1:D}", eventName, id); + } internal abstract class PropertyGetter { @@ -131,26 +238,37 @@ internal class PropertyGetter : PropertyGetter private readonly Task tcsTask; private TaskCompletionSource tcs; - public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs) + public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object arg = null) { this.tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); this.tcsTask = this.tcs.Task; string eventName; + string messageName; - switch (apiBase.SocketEventNameType) + switch (apiBase.SocketTaskEventNameType) { - case SocketEventNameTypes.DashesLowerFirst: + case SocketTaskEventNameTypes.DashesLowerFirst: eventName = apiBase.propertyEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}-completed"); break; - case SocketEventNameTypes.NoDashUpperFirst: + case SocketTaskEventNameTypes.NoDashUpperFirst: eventName = apiBase.propertyEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}{s.StripAsync()}Completed"); break; default: throw new ArgumentOutOfRangeException(); } - - var messageName = apiBase.propertyMessageNames.GetOrAdd(callerName, s => apiBase.objectName + s.StripAsync()); + + switch (apiBase.SocketTaskMessageNameType) + { + case SocketTaskMessageNameTypes.DashesLowerFirst: + messageName = apiBase.propertyMessageNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}"); + break; + case SocketTaskMessageNameTypes.NoDashUpperFirst: + messageName = apiBase.propertyMessageNames.GetOrAdd(callerName, s => apiBase.objectName + s.StripAsync()); + break; + default: + throw new ArgumentOutOfRangeException(); + } BridgeConnector.Socket.Once(eventName, (result) => { @@ -171,14 +289,14 @@ public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs) } } }); - - if (apiBase.Id >= 0) + + if (arg != null) { - BridgeConnector.Socket.Emit(messageName, apiBase.Id); + _ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg); } else { - BridgeConnector.Socket.Emit(messageName); + _ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName); } System.Threading.Tasks.Task.Delay(PropertyTimeout).ContinueWith(_ => @@ -203,5 +321,53 @@ public override Task Task() return this.tcsTask as Task; } } + + [SuppressMessage("ReSharper", "InconsistentlySynchronizedField")] + private class EventContainer + { + private Action eventAction; + private Delegate eventActionT; + + private Action GetEventActionT() + { + return (Action)eventActionT; + } + + private void SetEventActionT(Action actionT) + { + eventActionT = actionT; + } + + public void OnEventAction() => eventAction?.Invoke(); + + public void OnEventActionT(T p) => GetEventActionT()?.Invoke(p); + + public void Register(Action receiver) + { + eventAction += receiver; + } + + public void Register(Action receiver) + { + var actionT = GetEventActionT(); + actionT += receiver; + SetEventActionT(actionT); + } + + public bool Unregister(Action receiver) + { + eventAction -= receiver; + return this.eventAction != null; + } + + public bool Unregister(Action receiver) + { + var actionT = GetEventActionT(); + actionT -= receiver; + SetEventActionT(actionT); + + return actionT != null; + } + } } } diff --git a/src/ElectronNET.API/API/App.cs b/src/ElectronNET.API/API/App.cs index 7749c414..5a27e758 100644 --- a/src/ElectronNET.API/API/App.cs +++ b/src/ElectronNET.API/API/App.cs @@ -1,7 +1,5 @@ using ElectronNET.API.Entities; using ElectronNET.API.Extensions; -using ElectronNET.API.Serialization; -using ElectronNET.Common; using System; using System.Runtime.InteropServices; using System.Text.Json; @@ -17,7 +15,8 @@ namespace ElectronNET.API /// public sealed class App : ApiBase { - protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.NoDashUpperFirst; + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.NoDashUpperFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; /// /// Emitted when all windows have been closed. @@ -224,45 +223,37 @@ public event Func Quitting /// public event Action BrowserWindowBlur { - add => ApiEventManager.AddEvent("app-browser-window-blur", GetHashCode(), _browserWindowBlur, value); - remove => ApiEventManager.RemoveEvent("app-browser-window-blur", GetHashCode(), _browserWindowBlur, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _browserWindowBlur; - /// /// Emitted when a gets focused. /// public event Action BrowserWindowFocus { - add => ApiEventManager.AddEvent("app-browser-window-focus", GetHashCode(), _browserWindowFocus, value); - remove => ApiEventManager.RemoveEvent("app-browser-window-focus", GetHashCode(), _browserWindowFocus, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _browserWindowFocus; - /// /// Emitted when a new is created. /// public event Action BrowserWindowCreated { - add => ApiEventManager.AddEvent("app-browser-window-created", GetHashCode(), _browserWindowCreated, value); - remove => ApiEventManager.RemoveEvent("app-browser-window-created", GetHashCode(), _browserWindowCreated, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _browserWindowCreated; - /// /// Emitted when a new is created. /// public event Action WebContentsCreated { - add => ApiEventManager.AddEvent("app-web-contents-created", GetHashCode(), _webContentsCreated, value); - remove => ApiEventManager.RemoveEvent("app-web-contents-created", GetHashCode(), _webContentsCreated, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _webContentsCreated; - /// /// Emitted when Chrome’s accessibility support changes. This event fires when assistive technologies, such as /// screen readers, are enabled or disabled. See https://www.chromium.org/developers/design-documents/accessibility for more details. @@ -270,12 +261,10 @@ public event Action WebContentsCreated /// when Chrome's accessibility support is enabled, otherwise. public event Action AccessibilitySupportChanged { - add => ApiEventManager.AddEvent("app-accessibility-support-changed", GetHashCode(), _accessibilitySupportChanged, value, (args) => args.GetBoolean()); - remove => ApiEventManager.RemoveEvent("app-accessibility-support-changed", GetHashCode(), _accessibilitySupportChanged, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _accessibilitySupportChanged; - /// /// Emitted when the application has finished basic startup. /// @@ -329,12 +318,10 @@ internal set /// public event Action OpenFile { - add => ApiEventManager.AddEvent("app-open-file", GetHashCode(), _openFile, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("app-open-file", GetHashCode(), _openFile, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _openFile; - /// /// Emitted when a MacOS user wants to open a URL with the application. Your application's Info.plist file must @@ -342,12 +329,10 @@ public event Action OpenFile /// public event Action OpenUrl { - add => ApiEventManager.AddEvent("app-open-url", GetHashCode(), _openUrl, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("app-open-url", GetHashCode(), _openUrl, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _openUrl; - /// /// A property that indicates the current application's name, which is the name in the /// application's package.json file. diff --git a/src/ElectronNET.API/API/AutoUpdater.cs b/src/ElectronNET.API/API/AutoUpdater.cs index ebe0c9b4..0b5fd75f 100644 --- a/src/ElectronNET.API/API/AutoUpdater.cs +++ b/src/ElectronNET.API/API/AutoUpdater.cs @@ -1,9 +1,6 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; -using ElectronNET.Common; using System; using System.Collections.Generic; -using System.Text.Json; using System.Threading.Tasks; // ReSharper disable InconsistentNaming @@ -13,8 +10,12 @@ namespace ElectronNET.API /// /// Enable apps to automatically update themselves. Based on electron-updater. /// - public sealed class AutoUpdater + public sealed class AutoUpdater: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; + /// /// Whether to automatically download an update when it is found. (Default is true) /// @@ -22,15 +23,7 @@ public bool AutoDownload { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-autoDownload-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-autoDownload-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } set { @@ -47,15 +40,7 @@ public bool AutoInstallOnAppQuit { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-autoInstallOnAppQuit-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } set { @@ -73,15 +58,7 @@ public bool AllowPrerelease { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-allowPrerelease-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } set { @@ -97,15 +74,7 @@ public bool FullChangelog { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-fullChangelog-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } set { @@ -122,15 +91,7 @@ public bool AllowDowngrade { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-allowDowngrade-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } set { @@ -145,15 +106,7 @@ public string UpdateConfigPath { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-updateConfigPath-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-updateConfigPath-get"); - - return tcs.Task; - }).Result; + return Task.Run(() => GetPropertyAsync()).Result; } } @@ -164,15 +117,7 @@ public Task CurrentVersionAsync { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-currentVersion-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-currentVersion-get"); - - return tcs.Task; - }); + return Task.Run(() => GetPropertyAsync()); } } @@ -197,15 +142,18 @@ public Task ChannelAsync { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("autoUpdater-channel-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-channel-get"); + return Task.Run(() => GetPropertyAsync()); + } + } - return tcs.Task; - }); + /// + /// Set the update channel. Not applicable for GitHub. + /// + public string SetChannel + { + set + { + BridgeConnector.Socket.Emit("autoUpdater-channel-set", value); } } @@ -217,15 +165,7 @@ public Task> RequestHeadersAsync { get { - return Task.Run(() => - { - var tcs = new TaskCompletionSource>(); - - BridgeConnector.Socket.Once>("autoUpdater-requestHeaders-get-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-get"); - - return tcs.Task; - }); + return Task.Run(() => GetPropertyAsync>()); } } @@ -245,68 +185,56 @@ public Dictionary RequestHeaders /// public event Action OnError { - add => ApiEventManager.AddEvent("autoUpdater-error", GetHashCode(), _error, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("autoUpdater-error", GetHashCode(), _error, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _error; - /// /// Emitted when checking if an update has started. /// public event Action OnCheckingForUpdate { - add => ApiEventManager.AddEvent("autoUpdater-checking-for-update", GetHashCode(), _checkingForUpdate, value); - remove => ApiEventManager.RemoveEvent("autoUpdater-checking-for-update", GetHashCode(), _checkingForUpdate, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _checkingForUpdate; - /// /// Emitted when there is an available update. /// The update is downloaded automatically if AutoDownload is true. /// public event Action OnUpdateAvailable { - add => ApiEventManager.AddEvent("autoUpdater-update-available", GetHashCode(), _updateAvailable, value, (args) => args.Deserialize(ElectronJsonContext.Default.UpdateInfo)); - remove => ApiEventManager.RemoveEvent("autoUpdater-update-available", GetHashCode(), _updateAvailable, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _updateAvailable; - /// /// Emitted when there is no available update. /// public event Action OnUpdateNotAvailable { - add => ApiEventManager.AddEvent("autoUpdater-update-not-available", GetHashCode(), _updateNotAvailable, value, (args) => args.Deserialize(ElectronJsonContext.Default.UpdateInfo)); - remove => ApiEventManager.RemoveEvent("autoUpdater-update-not-available", GetHashCode(), _updateNotAvailable, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _updateNotAvailable; - /// /// Emitted on download progress. /// public event Action OnDownloadProgress { - add => ApiEventManager.AddEvent("autoUpdater-download-progress", GetHashCode(), _downloadProgress, value, (args) => args.Deserialize(ElectronJsonContext.Default.ProgressInfo)); - remove => ApiEventManager.RemoveEvent("autoUpdater-download-progress", GetHashCode(), _downloadProgress, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _downloadProgress; - /// /// Emitted on download complete. /// public event Action OnUpdateDownloaded { - add => ApiEventManager.AddEvent("autoUpdater-update-downloaded", GetHashCode(), _updateDownloaded, value, (args) => args.Deserialize(ElectronJsonContext.Default.UpdateInfo)); - remove => ApiEventManager.RemoveEvent("autoUpdater-update-downloaded", GetHashCode(), _updateDownloaded, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _updateDownloaded; - private static AutoUpdater _autoUpdater; private static object _syncRoot = new object(); @@ -342,11 +270,11 @@ public Task CheckForUpdatesAsync() var taskCompletionSource = new TaskCompletionSource(); string guid = Guid.NewGuid().ToString(); - BridgeConnector.Socket.Once("autoUpdaterCheckForUpdatesComplete" + guid, (result) => + BridgeConnector.Socket.Once("autoUpdater-checkForUpdates-completed" + guid, (result) => { try { - BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid); + BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesError" + guid); taskCompletionSource.SetResult(result); } catch (Exception ex) @@ -354,15 +282,15 @@ public Task CheckForUpdatesAsync() taskCompletionSource.SetException(ex); } }); - BridgeConnector.Socket.Once("autoUpdaterCheckForUpdatesError" + guid, (result) => + BridgeConnector.Socket.Once("autoUpdater-checkForUpdatesError" + guid, (result) => { - BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid); + BridgeConnector.Socket.Off("autoUpdater-checkForUpdates-completed" + guid); string message = "An error occurred in CheckForUpdatesAsync"; if (!string.IsNullOrEmpty(result)) message = result; taskCompletionSource.SetException(new Exception(message)); }); - BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid); + BridgeConnector.Socket.Emit("autoUpdater-checkForUpdates", guid); return taskCompletionSource.Task; } @@ -378,11 +306,11 @@ public Task CheckForUpdatesAndNotifyAsync() var taskCompletionSource = new TaskCompletionSource(); string guid = Guid.NewGuid().ToString(); - BridgeConnector.Socket.Once("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (result) => + BridgeConnector.Socket.Once("autoUpdater-checkForUpdatesAndNotify-completed" + guid, (result) => { try { - BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid); + BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesAndNotifyError" + guid); taskCompletionSource.SetResult(result); } catch (Exception ex) @@ -390,15 +318,15 @@ public Task CheckForUpdatesAndNotifyAsync() taskCompletionSource.SetException(ex); } }); - BridgeConnector.Socket.Once("autoUpdaterCheckForUpdatesAndNotifyError" + guid, (result) => + BridgeConnector.Socket.Once("autoUpdater-checkForUpdatesAndNotifyError" + guid, (result) => { - BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid); - string message = "An error occurred in autoUpdaterCheckForUpdatesAndNotify"; + BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesAndNotify-completed" + guid); + string message = "An error occurred in CheckForUpdatesAndNotifyAsync"; if (!string.IsNullOrEmpty(result)) message = result; taskCompletionSource.SetException(new Exception(message)); }); - BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid); + BridgeConnector.Socket.Emit("autoUpdater-checkForUpdatesAndNotify", guid); return taskCompletionSource.Task; } @@ -414,7 +342,7 @@ public Task CheckForUpdatesAndNotifyAsync() /// Run the app after finish even on silent install. Not applicable for macOS. Ignored if `isSilent` is set to `false`. public void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false) { - BridgeConnector.Socket.Emit("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter); + BridgeConnector.Socket.Emit("autoUpdater-quitAndInstall", isSilent, isForceRunAfter); } /// @@ -426,8 +354,8 @@ public Task DownloadUpdateAsync() var tcs = new TaskCompletionSource(); string guid = Guid.NewGuid().ToString(); - BridgeConnector.Socket.Once("autoUpdaterDownloadUpdateComplete" + guid, tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdaterDownloadUpdate", guid); + BridgeConnector.Socket.Once("autoUpdater-downloadUpdate-completed" + guid, tcs.SetResult); + BridgeConnector.Socket.Emit("autoUpdater-downloadUpdate", guid); return tcs.Task; } @@ -441,8 +369,8 @@ public Task GetFeedURLAsync() var tcs = new TaskCompletionSource(); string guid = Guid.NewGuid().ToString(); - BridgeConnector.Socket.Once("autoUpdaterGetFeedURLComplete" + guid, tcs.SetResult); - BridgeConnector.Socket.Emit("autoUpdaterGetFeedURL", guid); + BridgeConnector.Socket.Once("autoUpdater-getFeedURL-completed" + guid, tcs.SetResult); + BridgeConnector.Socket.Emit("autoUpdater-getFeedURL", guid); return tcs.Task; } diff --git a/src/ElectronNET.API/API/BrowserView.cs b/src/ElectronNET.API/API/BrowserView.cs index 131221e8..479d9712 100644 --- a/src/ElectronNET.API/API/BrowserView.cs +++ b/src/ElectronNET.API/API/BrowserView.cs @@ -1,6 +1,4 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; -using System.Text.Json; using System.Threading.Tasks; namespace ElectronNET.API @@ -10,12 +8,14 @@ namespace ElectronNET.API /// It is like a child window, except that it is positioned relative to its owning window. /// It is meant to be an alternative to the webview tag. /// - public class BrowserView + public class BrowserView: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; /// /// Gets the identifier. /// - public int Id { get; internal set; } + public override int Id { get; protected set; } /// /// Render and control web pages. @@ -30,19 +30,11 @@ public Rectangle Bounds { get { - var tcs = new TaskCompletionSource(); - - Task.Run(() => - { - BridgeConnector.Socket.Once("browserView-getBounds-reply", tcs.SetResult); - BridgeConnector.Socket.Emit("browserView-getBounds", Id); - }); - - return tcs.Task.GetAwaiter().GetResult(); + return Task.Run(() => GetPropertyAsync()).Result; } set { - BridgeConnector.Socket.Emit("browserView-setBounds", Id, value); + BridgeConnector.Socket.Emit("browserView-bounds-set", Id, value); } } diff --git a/src/ElectronNET.API/API/BrowserWindow.cs b/src/ElectronNET.API/API/BrowserWindow.cs index 5bd6217b..f4e7529f 100644 --- a/src/ElectronNET.API/API/BrowserWindow.cs +++ b/src/ElectronNET.API/API/BrowserWindow.cs @@ -10,15 +10,13 @@ namespace ElectronNET.API; -using ElectronNET.Common; -using System.Text.Json; - /// /// Create and control browser windows. /// public class BrowserWindow : ApiBase { - protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashesLowerFirst; + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; /// /// Gets the identifier. @@ -34,34 +32,28 @@ public class BrowserWindow : ApiBase /// public event Action OnReadyToShow { - add => ApiEventManager.AddEvent("browserWindow-ready-to-show", Id, _readyToShow, value); - remove => ApiEventManager.RemoveEvent("browserWindow-ready-to-show", Id, _readyToShow, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _readyToShow; - /// /// Emitted when the document changed its title. /// public event Action OnPageTitleUpdated { - add => ApiEventManager.AddEvent("browserWindow-page-title-updated", Id, _pageTitleUpdated, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("browserWindow-page-title-updated", Id, _pageTitleUpdated, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _pageTitleUpdated; - /// /// Emitted when the window is going to be closed. /// public event Action OnClose { - add => ApiEventManager.AddEvent("browserWindow-close", Id, _close, value); - remove => ApiEventManager.RemoveEvent("browserWindow-close", Id, _close, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _close; - /// /// Emitted when the window is closed. /// After you have received this event you should remove the @@ -69,144 +61,118 @@ public event Action OnClose /// public event Action OnClosed { - add => ApiEventManager.AddEvent("browserWindow-closed", Id, _closed, value); - remove => ApiEventManager.RemoveEvent("browserWindow-closed", Id, _closed, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _closed; - /// /// Emitted when window session is going to end due to force shutdown or machine restart or session log off. /// public event Action OnSessionEnd { - add => ApiEventManager.AddEvent("browserWindow-session-end", Id, _sessionEnd, value); - remove => ApiEventManager.RemoveEvent("browserWindow-session-end", Id, _sessionEnd, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _sessionEnd; - /// /// Emitted when the web page becomes unresponsive. /// public event Action OnUnresponsive { - add => ApiEventManager.AddEvent("browserWindow-unresponsive", Id, _unresponsive, value); - remove => ApiEventManager.RemoveEvent("browserWindow-unresponsive", Id, _unresponsive, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _unresponsive; - /// /// Emitted when the unresponsive web page becomes responsive again. /// public event Action OnResponsive { - add => ApiEventManager.AddEvent("browserWindow-responsive", Id, _responsive, value); - remove => ApiEventManager.RemoveEvent("browserWindow-responsive", Id, _responsive, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _responsive; - /// /// Emitted when the window loses focus. /// public event Action OnBlur { - add => ApiEventManager.AddEvent("browserWindow-blur", Id, _blur, value); - remove => ApiEventManager.RemoveEvent("browserWindow-blur", Id, _blur, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _blur; - /// /// Emitted when the window gains focus. /// public event Action OnFocus { - add => ApiEventManager.AddEvent("browserWindow-focus", Id, _focus, value); - remove => ApiEventManager.RemoveEvent("browserWindow-focus", Id, _focus, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _focus; - /// /// Emitted when the window is shown. /// public event Action OnShow { - add => ApiEventManager.AddEvent("browserWindow-show", Id, _show, value); - remove => ApiEventManager.RemoveEvent("browserWindow-show", Id, _show, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _show; - /// /// Emitted when the window is hidden. /// public event Action OnHide { - add => ApiEventManager.AddEvent("browserWindow-hide", Id, _hide, value); - remove => ApiEventManager.RemoveEvent("browserWindow-hide", Id, _hide, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _hide; - /// /// Emitted when window is maximized. /// public event Action OnMaximize { - add => ApiEventManager.AddEvent("browserWindow-maximize", Id, _maximize, value); - remove => ApiEventManager.RemoveEvent("browserWindow-maximize", Id, _maximize, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _maximize; - /// /// Emitted when the window exits from a maximized state. /// public event Action OnUnmaximize { - add => ApiEventManager.AddEvent("browserWindow-unmaximize", Id, _unmaximize, value); - remove => ApiEventManager.RemoveEvent("browserWindow-unmaximize", Id, _unmaximize, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _unmaximize; - /// /// Emitted when the window is minimized. /// public event Action OnMinimize { - add => ApiEventManager.AddEvent("browserWindow-minimize", Id, _minimize, value); - remove => ApiEventManager.RemoveEvent("browserWindow-minimize", Id, _minimize, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _minimize; - /// /// Emitted when the window is restored from a minimized state. /// public event Action OnRestore { - add => ApiEventManager.AddEvent("browserWindow-restore", Id, _restore, value); - remove => ApiEventManager.RemoveEvent("browserWindow-restore", Id, _restore, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _restore; - /// /// Emitted when the window is being resized. /// public event Action OnResize { - add => ApiEventManager.AddEvent("browserWindow-resize", Id, _resize, value); - remove => ApiEventManager.RemoveEvent("browserWindow-resize", Id, _resize, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _resize; - /// /// Emitted when the window is being moved to a new position. /// @@ -214,67 +180,55 @@ public event Action OnResize /// public event Action OnMove { - add => ApiEventManager.AddEvent("browserWindow-move", Id, _move, value); - remove => ApiEventManager.RemoveEvent("browserWindow-move", Id, _move, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _move; - /// /// macOS: Emitted once when the window is moved to a new position. /// public event Action OnMoved { - add => ApiEventManager.AddEvent("browserWindow-moved", Id, _moved, value); - remove => ApiEventManager.RemoveEvent("browserWindow-moved", Id, _moved, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _moved; - /// /// Emitted when the window enters a full-screen state. /// public event Action OnEnterFullScreen { - add => ApiEventManager.AddEvent("browserWindow-enter-full-screen", Id, _enterFullScreen, value); - remove => ApiEventManager.RemoveEvent("browserWindow-enter-full-screen", Id, _enterFullScreen, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _enterFullScreen; - /// /// Emitted when the window leaves a full-screen state. /// public event Action OnLeaveFullScreen { - add => ApiEventManager.AddEvent("browserWindow-leave-full-screen", Id, _leaveFullScreen, value); - remove => ApiEventManager.RemoveEvent("browserWindow-leave-full-screen", Id, _leaveFullScreen, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _leaveFullScreen; - /// /// Emitted when the window enters a full-screen state triggered by HTML API. /// public event Action OnEnterHtmlFullScreen { - add => ApiEventManager.AddEvent("browserWindow-enter-html-full-screen", Id, _enterHtmlFullScreen, value); - remove => ApiEventManager.RemoveEvent("browserWindow-enter-html-full-screen", Id, _enterHtmlFullScreen, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _enterHtmlFullScreen; - /// /// Emitted when the window leaves a full-screen state triggered by HTML API. /// public event Action OnLeaveHtmlFullScreen { - add => ApiEventManager.AddEvent("browserWindow-leave-html-full-screen", Id, _leaveHtmlFullScreen, value); - remove => ApiEventManager.RemoveEvent("browserWindow-leave-html-full-screen", Id, _leaveHtmlFullScreen, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _leaveHtmlFullScreen; - /// /// Emitted when an App Command is invoked. These are typically related to /// keyboard media keys or browser commands, as well as the “Back” button @@ -286,56 +240,46 @@ public event Action OnLeaveHtmlFullScreen /// public event Action OnAppCommand { - add => ApiEventManager.AddEvent("browserWindow-app-command", Id, _appCommand, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("browserWindow-app-command", Id, _appCommand, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _appCommand; - /// /// Emitted on 3-finger swipe. Possible directions are up, right, down, left. /// public event Action OnSwipe { - add => ApiEventManager.AddEvent("browserWindow-swipe", Id, _swipe, value, (args) => args.ToString()); - remove => ApiEventManager.RemoveEvent("browserWindow-swipe", Id, _swipe, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _swipe; - /// /// Emitted when the window opens a sheet. /// public event Action OnSheetBegin { - add => ApiEventManager.AddEvent("browserWindow-sheet-begin", Id, _sheetBegin, value); - remove => ApiEventManager.RemoveEvent("browserWindow-sheet-begin", Id, _sheetBegin, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _sheetBegin; - /// /// Emitted when the window has closed a sheet. /// public event Action OnSheetEnd { - add => ApiEventManager.AddEvent("browserWindow-sheet-end", Id, _sheetEnd, value); - remove => ApiEventManager.RemoveEvent("browserWindow-sheet-end", Id, _sheetEnd, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _sheetEnd; - /// /// Emitted when the native new tab button is clicked. /// public event Action OnNewWindowForTab { - add => ApiEventManager.AddEvent("browserWindow-new-window-for-tab", Id, _newWindowForTab, value); - remove => ApiEventManager.RemoveEvent("browserWindow-new-window-for-tab", Id, _newWindowForTab, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _newWindowForTab; - internal BrowserWindow(int id) { Id = id; diff --git a/src/ElectronNET.API/API/Clipboard.cs b/src/ElectronNET.API/API/Clipboard.cs index 15c66daa..5d067f6a 100644 --- a/src/ElectronNET.API/API/Clipboard.cs +++ b/src/ElectronNET.API/API/Clipboard.cs @@ -2,14 +2,18 @@ using ElectronNET.API.Serialization; using System.Text.Json; using System.Threading.Tasks; +// ReSharper disable InconsistentNaming namespace ElectronNET.API { /// /// Perform copy and paste operations on the system clipboard. /// - public sealed class Clipboard + public sealed class Clipboard: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; + private static Clipboard _clipboard; private static object _syncRoot = new object(); @@ -41,15 +45,7 @@ internal static Clipboard Instance /// /// /// The content in the clipboard as plain text. - public Task ReadTextAsync(string type = "") - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readText-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readText", type); - - return tcs.Task; - } + public Task ReadTextAsync(string type = "") => GetPropertyAsync(type); /// /// Writes the text into the clipboard as plain text. @@ -66,15 +62,7 @@ public void WriteText(string text, string type = "") /// /// /// - public Task ReadHTMLAsync(string type = "") - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readHTML-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readHTML", type); - - return tcs.Task; - } + public Task ReadHTMLAsync(string type = "") => GetPropertyAsync(type); /// /// Writes markup to the clipboard. @@ -91,15 +79,7 @@ public void WriteHTML(string markup, string type = "") /// /// /// - public Task ReadRTFAsync(string type = "") - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readRTF-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readRTF", type); - - return tcs.Task; - } + public Task ReadRTFAsync(string type = "") => GetPropertyAsync(type); /// /// Writes the text into the clipboard in RTF. @@ -108,7 +88,7 @@ public Task ReadRTFAsync(string type = "") /// public void WriteRTF(string text, string type = "") { - BridgeConnector.Socket.Emit("clipboard-writeHTML", text, type); + BridgeConnector.Socket.Emit("clipboard-writeRTF", text, type); } /// @@ -117,15 +97,7 @@ public void WriteRTF(string text, string type = "") /// be empty strings when the bookmark is unavailable. /// /// - public Task ReadBookmarkAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readBookmark-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readBookmark"); - - return tcs.Task; - } + public Task ReadBookmarkAsync() => GetPropertyAsync(); /// /// Writes the title and url into the clipboard as a bookmark. @@ -148,15 +120,7 @@ public void WriteBookmark(string title, string url, string type = "") /// find pasteboard whenever the application is activated. /// /// - public Task ReadFindTextAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readFindText-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readFindText"); - - return tcs.Task; - } + public Task ReadFindTextAsync() => GetPropertyAsync(); /// /// macOS: Writes the text into the find pasteboard as plain text. This method uses @@ -182,15 +146,7 @@ public void Clear(string type = "") /// /// /// - public Task AvailableFormatsAsync(string type = "") - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-availableFormats-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-availableFormats", type); - - return tcs.Task; - } + public Task AvailableFormatsAsync(string type = "") => GetPropertyAsync(type); /// /// Writes data to the clipboard. @@ -207,15 +163,7 @@ public void Write(Data data, string type = "") /// /// /// - public Task ReadImageAsync(string type = "") - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("clipboard-readImage-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("clipboard-readImage", type); - - return tcs.Task; - } + public Task ReadImageAsync(string type = "") => GetPropertyAsync(type); /// /// Writes an image to the clipboard. diff --git a/src/ElectronNET.API/API/CommandLine.cs b/src/ElectronNET.API/API/CommandLine.cs index 94a7ef39..6f47438a 100644 --- a/src/ElectronNET.API/API/CommandLine.cs +++ b/src/ElectronNET.API/API/CommandLine.cs @@ -1,5 +1,4 @@ -using System.Text.Json; -using System.Threading; +using System.Threading; using System.Threading.Tasks; namespace ElectronNET.API diff --git a/src/ElectronNET.API/API/Dialog.cs b/src/ElectronNET.API/API/Dialog.cs index 2ce4d9be..933c6ea4 100644 --- a/src/ElectronNET.API/API/Dialog.cs +++ b/src/ElectronNET.API/API/Dialog.cs @@ -1,5 +1,4 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; using System; using System.Text.Json; using System.Threading.Tasks; diff --git a/src/ElectronNET.API/API/NativeTheme.cs b/src/ElectronNET.API/API/NativeTheme.cs index daec8135..c817b9d8 100644 --- a/src/ElectronNET.API/API/NativeTheme.cs +++ b/src/ElectronNET.API/API/NativeTheme.cs @@ -1,17 +1,19 @@ -using ElectronNET.API.Entities; -using ElectronNET.API.Extensions; -using ElectronNET.Common; -using System; -using System.Text.Json; +using System; using System.Threading.Tasks; +using ElectronNET.API.Entities; +using ElectronNET.API.Extensions; namespace ElectronNET.API { /// /// Read and respond to changes in Chromium's native color theme. /// - public sealed class NativeTheme + public sealed class NativeTheme: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; + private static NativeTheme _nativeTheme; private static object _syncRoot = new object(); @@ -105,58 +107,26 @@ public void SetThemeSource(ThemeSourceMode themeSourceMode) /// A property that can be , or . It is used to override () and /// supercede the value that Chromium has chosen to use internally. /// - public Task GetThemeSourceAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("nativeTheme-themeSource-getCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("nativeTheme-themeSource-get"); - - return tcs.Task; - } + public Task GetThemeSourceAsync() => GetPropertyAsync(); /// /// A for if the OS / Chromium currently has a dark mode enabled or is /// being instructed to show a dark-style UI. If you want to modify this value you /// should use . /// - public Task ShouldUseDarkColorsAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("nativeTheme-shouldUseDarkColors-completed", tcs.SetResult); - BridgeConnector.Socket.Emit("nativeTheme-shouldUseDarkColors"); - - return tcs.Task; - } + public Task ShouldUseDarkColorsAsync() => GetPropertyAsync(); /// /// A for if the OS / Chromium currently has high-contrast mode enabled or is /// being instructed to show a high-contrast UI. /// - public Task ShouldUseHighContrastColorsAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("nativeTheme-shouldUseHighContrastColors-completed", tcs.SetResult); - BridgeConnector.Socket.Emit("nativeTheme-shouldUseHighContrastColors"); - - return tcs.Task; - } + public Task ShouldUseHighContrastColorsAsync() => GetPropertyAsync(); /// /// A for if the OS / Chromium currently has an inverted color scheme or is /// being instructed to use an inverted color scheme. /// - public Task ShouldUseInvertedColorSchemeAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("nativeTheme-shouldUseInvertedColorScheme-completed", tcs.SetResult); - BridgeConnector.Socket.Emit("nativeTheme-shouldUseInvertedColorScheme"); - - return tcs.Task; - } + public Task ShouldUseInvertedColorSchemeAsync() => GetPropertyAsync(); /// /// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of , @@ -164,10 +134,8 @@ public Task ShouldUseInvertedColorSchemeAsync() /// public event Action Updated { - add => ApiEventManager.AddEvent("nativeTheme-updated", GetHashCode(), _updated, value); - remove => ApiEventManager.RemoveEvent("nativeTheme-updated", GetHashCode(), _updated, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - - private event Action _updated; } } \ No newline at end of file diff --git a/src/ElectronNET.API/API/Notification.cs b/src/ElectronNET.API/API/Notification.cs index 1ed5ddd8..aaa0c479 100644 --- a/src/ElectronNET.API/API/Notification.cs +++ b/src/ElectronNET.API/API/Notification.cs @@ -1,9 +1,7 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; using System; using System.Collections.Generic; using System.Linq; -using System.Text.Json; using System.Threading.Tasks; namespace ElectronNET.API @@ -11,8 +9,9 @@ namespace ElectronNET.API /// /// Create OS desktop notifications /// - public sealed class Notification + public sealed class Notification: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.NoDashUpperFirst; private static Notification _notification; private static object _syncRoot = new object(); @@ -117,16 +116,6 @@ private static void GenerateIDsForDefinedActions(NotificationOptions notificatio /// Whether or not desktop notifications are supported on the current system. /// /// - public Task IsSupportedAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("notificationIsSupportedComplete", tcs.SetResult); - BridgeConnector.Socket.Emit("notificationIsSupported"); - - return tcs.Task; - } - - + public Task IsSupportedAsync() => GetPropertyAsync(); } } diff --git a/src/ElectronNET.API/API/PowerMonitor.cs b/src/ElectronNET.API/API/PowerMonitor.cs index aefefee6..51ae2818 100644 --- a/src/ElectronNET.API/API/PowerMonitor.cs +++ b/src/ElectronNET.API/API/PowerMonitor.cs @@ -1,5 +1,4 @@ -using ElectronNET.Common; -using System; +using System; // ReSharper disable InconsistentNaming @@ -8,74 +7,65 @@ namespace ElectronNET.API /// /// Monitor power state changes.. /// - public sealed class PowerMonitor + public sealed class PowerMonitor: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; + /// /// Emitted when the system is about to lock the screen. /// public event Action OnLockScreen { - add => ApiEventManager.AddEvent("pm-lock-screen", string.Empty, _lockScreen, value); - remove => ApiEventManager.RemoveEvent("pm-lock-screen", string.Empty, _lockScreen, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _lockScreen; - /// /// Emitted when the system is about to unlock the screen. /// public event Action OnUnLockScreen { - add => ApiEventManager.AddEvent("pm-unlock-screen", string.Empty, _unlockScreen, value); - remove => ApiEventManager.RemoveEvent("pm-unlock-screen", string.Empty, _unlockScreen, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _unlockScreen; - /// /// Emitted when the system is suspending. /// public event Action OnSuspend { - add => ApiEventManager.AddEvent("pm-suspend", string.Empty, _suspend, value); - remove => ApiEventManager.RemoveEvent("pm-suspend", string.Empty, _suspend, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _suspend; - /// /// Emitted when system is resuming. /// public event Action OnResume { - add => ApiEventManager.AddEvent("pm-resume", string.Empty, _resume, value); - remove => ApiEventManager.RemoveEvent("pm-resume", string.Empty, _resume, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _resume; - /// /// Emitted when the system changes to AC power. /// public event Action OnAC { - add => ApiEventManager.AddEvent("pm-on-ac", string.Empty, _onAC, value); - remove => ApiEventManager.RemoveEvent("pm-on-ac", string.Empty, _onAC, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _onAC; - /// /// Emitted when system changes to battery power. /// public event Action OnBattery { - add => ApiEventManager.AddEvent("pm-on-battery", string.Empty, _onBattery, value); - remove => ApiEventManager.RemoveEvent("pm-on-battery", string.Empty, _onBattery, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _onBattery; - /// /// Emitted when the system is about to reboot or shut down. If the event handler /// invokes `e.preventDefault()`, Electron will attempt to delay system shutdown in @@ -84,12 +74,10 @@ public event Action OnBattery /// public event Action OnShutdown { - add => ApiEventManager.AddEvent("pm-shutdown", string.Empty, _shutdown, value); - remove => ApiEventManager.RemoveEvent("pm-shutdown", string.Empty, _shutdown, value); + add => AddEvent(value); + remove => RemoveEvent(value); } - private event Action _shutdown; - private static PowerMonitor _powerMonitor; private static object _syncRoot = new object(); diff --git a/src/ElectronNET.API/API/Process.cs b/src/ElectronNET.API/API/Process.cs index be2e46a8..328b0074 100644 --- a/src/ElectronNET.API/API/Process.cs +++ b/src/ElectronNET.API/API/Process.cs @@ -9,8 +9,10 @@ namespace ElectronNET.API /// Electron's process object is extended from the Node.js process object. It adds the /// events, properties, and methods. /// - public sealed class Process + public sealed class Process: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; internal Process() { } @@ -42,18 +44,7 @@ internal static Process Instance /// The process.execPath property returns the absolute pathname of the executable that /// started the Node.js process. Symbolic links, if any, are resolved. /// - public Task ExecPathAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-execPath-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-execPath"); - - return tcs.Task; - } - } + public Task ExecPathAsync => GetPropertyAsync(); /// /// The process.argv property returns an array containing the command-line arguments passed @@ -62,169 +53,56 @@ public Task ExecPathAsync /// will be the path to the JavaScript file being executed. The remaining elements will be /// any additional command-line arguments /// - public Task ArgvAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-argv-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-argv"); - - return tcs.Task; - } - } + public Task ArgvAsync => GetPropertyAsync(); /// /// The process.execPath property returns the absolute pathname of the executable that /// started the Node.js process. Symbolic links, if any, are resolved. /// - public Task TypeAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-type-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-type"); - - return tcs.Task; - } - } - + public Task TypeAsync => GetPropertyAsync(); /// /// The process.versions property returns an object listing the version strings of /// chrome and electron. /// - public Task VersionsAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-versions-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-versions"); - - return tcs.Task; - } - } - + public Task VersionsAsync => GetPropertyAsync(); /// /// A Boolean. When app is started by being passed as parameter to the default app, this /// property is true in the main process, otherwise it is false. /// - public Task DefaultAppAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-defaultApp-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-defaultApp"); - - return tcs.Task; - } - } + public Task DefaultAppAsync => GetPropertyAsync(); /// /// A Boolean, true when the current renderer context is the "main" renderer frame. If you /// want the ID of the current frame you should use webFrame.routingId /// - public Task IsMainFrameAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-isMainFrame-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-isMainFrame"); - - return tcs.Task; - } - } + public Task IsMainFrameAsync => GetPropertyAsync(); /// /// A String representing the path to the resources directory. /// - public Task ResourcesPathAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-resourcesPath-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-resourcesPath"); - - return tcs.Task; - } - } + public Task ResourcesPathAsync => GetPropertyAsync(); /// /// The number of seconds the current Node.js process has been running. The return value /// includes fractions of a second. Use Math.floor() to get whole seconds. /// - public Task UpTimeAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-uptime-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-uptime"); - - return tcs.Task; - } - } + public Task UpTimeAsync => GetPropertyAsync(); /// /// The PID of the electron process /// - public Task PidAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-pid-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-pid"); - - return tcs.Task; - } - } - + public Task PidAsync => GetPropertyAsync(); /// /// The operating system CPU architecture for which the Node.js binary was compiled /// - public Task ArchAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-arch-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-arch"); - - return tcs.Task; - } - } + public Task ArchAsync => GetPropertyAsync(); /// /// A string identifying the operating system platform on which the Node.js process is running /// - public Task PlatformAsync - { - get - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("process-platform-Completed", tcs.SetResult); - BridgeConnector.Socket.Emit("process-platform"); - - return tcs.Task; - } - } + public Task PlatformAsync => GetPropertyAsync(); } } diff --git a/src/ElectronNET.API/API/Screen.cs b/src/ElectronNET.API/API/Screen.cs index 03fd5762..8c2b5cb0 100644 --- a/src/ElectronNET.API/API/Screen.cs +++ b/src/ElectronNET.API/API/Screen.cs @@ -1,39 +1,39 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; -using ElectronNET.Common; using System; +using System.Linq; using System.Text.Json; using System.Threading.Tasks; +using ElectronNET.API.Serialization; namespace ElectronNET.API { /// /// Retrieve information about screen size, displays, cursor position, etc. /// - public sealed class Screen + public sealed class Screen: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; + /// /// Emitted when an new Display has been added. /// public event Action OnDisplayAdded { - add => ApiEventManager.AddEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value, (args) => args.Deserialize(ElectronJsonContext.Default.Display)); - remove => ApiEventManager.RemoveEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _onDisplayAdded; - /// /// Emitted when oldDisplay has been removed. /// public event Action OnDisplayRemoved { - add => ApiEventManager.AddEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value, (args) => args.Deserialize(ElectronJsonContext.Default.Display)); - remove => ApiEventManager.RemoveEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _onDisplayRemoved; - /// /// Emitted when one or more metrics change in a display. /// The changedMetrics is an array of strings that describe the changes. @@ -41,8 +41,32 @@ public event Action OnDisplayRemoved /// public event Action OnDisplayMetricsChanged { - add => ApiEventManager.AddScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value); - remove => ApiEventManager.RemoveScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value); + add + { + if (_onDisplayMetricsChanged == null) + { + BridgeConnector.Socket.On("screen-display-metrics-changed" + GetHashCode(), (args) => + { + var arr = args.EnumerateArray().ToArray(); + var display = arr[0].Deserialize(ElectronJsonContext.Default.Display); + var metrics = arr[1].Deserialize(ElectronJson.Options); + + _onDisplayMetricsChanged(display, metrics); + }); + + BridgeConnector.Socket.Emit("register-screen-display-metrics-changed", GetHashCode()); + } + _onDisplayMetricsChanged += value; + } + remove + { + _onDisplayMetricsChanged -= value; + + if (_onDisplayMetricsChanged == null) + { + BridgeConnector.Socket.Off("screen-display-metrics-changed" + GetHashCode()); + } + } } private event Action _onDisplayMetricsChanged; @@ -77,87 +101,37 @@ internal static Screen Instance /// The current absolute position of the mouse pointer. /// /// - public Task GetCursorScreenPointAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getCursorScreenPointCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getCursorScreenPoint"); - - return tcs.Task; - } + public Task GetCursorScreenPointAsync() => GetPropertyAsync(); /// /// macOS: The height of the menu bar in pixels. /// /// The height of the menu bar in pixels. - public Task GetMenuBarHeightAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getMenuBarHeightCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getMenuBarHeight"); - - return tcs.Task; - } + public Task GetMenuBarWorkAreaAsync() => GetPropertyAsync(); /// /// The primary display. /// /// - public Task GetPrimaryDisplayAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getPrimaryDisplayCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getPrimaryDisplay"); - - return tcs.Task; - } + public Task GetPrimaryDisplayAsync() => GetPropertyAsync(); /// /// An array of displays that are currently available. /// /// An array of displays that are currently available. - public Task GetAllDisplaysAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getAllDisplaysCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getAllDisplays"); - - return tcs.Task; - } + public Task GetAllDisplaysAsync() => GetPropertyAsync(); /// /// The display nearest the specified point. /// /// The display nearest the specified point. - public Task GetDisplayNearestPointAsync(Point point) - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getDisplayNearestPointCompleted", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getDisplayNearestPoint", point); - - return tcs.Task; - } + public Task GetDisplayNearestPointAsync(Point point) => GetPropertyAsync(point); /// /// The display that most closely intersects the provided bounds. /// /// /// The display that most closely intersects the provided bounds. - public Task GetDisplayMatchingAsync(Rectangle rectangle) - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("screen-getDisplayMatching", tcs.SetResult); - BridgeConnector.Socket.Emit("screen-getDisplayMatching", rectangle); - - return tcs.Task; - } - - + public Task GetDisplayMatchingAsync(Rectangle rectangle) => GetPropertyAsync(rectangle); } } diff --git a/src/ElectronNET.API/API/Session.cs b/src/ElectronNET.API/API/Session.cs index 8f66fadd..bee7566c 100644 --- a/src/ElectronNET.API/API/Session.cs +++ b/src/ElectronNET.API/API/Session.cs @@ -1,7 +1,5 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; using System; -using System.Text.Json; using System.Threading.Tasks; namespace ElectronNET.API diff --git a/src/ElectronNET.API/API/Tray.cs b/src/ElectronNET.API/API/Tray.cs index bc3b49e6..a18b178e 100644 --- a/src/ElectronNET.API/API/Tray.cs +++ b/src/ElectronNET.API/API/Tray.cs @@ -1,9 +1,11 @@ using ElectronNET.API.Entities; using ElectronNET.API.Extensions; -using ElectronNET.Common; using System; using System.Collections.Generic; +using System.Linq; +using System.Text.Json; using System.Threading.Tasks; +using ElectronNET.API.Serialization; // ReSharper disable InconsistentNaming @@ -12,15 +14,41 @@ namespace ElectronNET.API /// /// Add icons and context menus to the system's notification area. /// - public sealed class Tray + public sealed class Tray: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower; + /// /// Emitted when the tray icon is clicked. /// public event Action OnClick { - add => ApiEventManager.AddTrayEvent("tray-click", GetHashCode(), _click, value); - remove => ApiEventManager.RemoveTrayEvent("tray-click", GetHashCode(), _click, value); + add + { + if (_click == null) + { + BridgeConnector.Socket.On("tray-click" + GetHashCode(), (result) => + { + var array = result.EnumerateArray().ToArray(); + var trayClickEventArgs = array[0].Deserialize(ElectronJsonContext.Default.TrayClickEventArgs); + var bounds = array[1].Deserialize(ElectronJsonContext.Default.Rectangle); + _click(trayClickEventArgs, bounds); + }); + + BridgeConnector.Socket.Emit("register-tray-click", GetHashCode()); + } + _click += value; + } + remove + { + _click -= value; + + if (_click == null) + { + BridgeConnector.Socket.Off("tray-click" + GetHashCode()); + } + } } private event Action _click; @@ -30,8 +58,31 @@ public event Action OnClick /// public event Action OnRightClick { - add => ApiEventManager.AddTrayEvent("tray-right-click", GetHashCode(), _rightClick, value); - remove => ApiEventManager.RemoveTrayEvent("tray-right-click", GetHashCode(), _rightClick, value); + add + { + if (_rightClick == null) + { + BridgeConnector.Socket.On("tray-right-click" + GetHashCode(), (result) => + { + var array = result.EnumerateArray().ToArray(); + var trayClickEventArgs = array[0].Deserialize(ElectronJsonContext.Default.TrayClickEventArgs); + var bounds = array[1].Deserialize(ElectronJsonContext.Default.Rectangle); + _rightClick(trayClickEventArgs, bounds); + }); + + BridgeConnector.Socket.Emit("register-tray-right-click", GetHashCode()); + } + _rightClick += value; + } + remove + { + _rightClick -= value; + + if (_rightClick == null) + { + BridgeConnector.Socket.Off("tray-right-click" + GetHashCode()); + } + } } private event Action _rightClick; @@ -41,8 +92,31 @@ public event Action OnRightClick /// public event Action OnDoubleClick { - add => ApiEventManager.AddTrayEvent("tray-double-click", GetHashCode(), _doubleClick, value); - remove => ApiEventManager.RemoveTrayEvent("tray-double-click", GetHashCode(), _doubleClick, value); + add + { + if (_doubleClick == null) + { + BridgeConnector.Socket.On("tray-double-click" + GetHashCode(), (result) => + { + var array = result.EnumerateArray().ToArray(); + var trayClickEventArgs = array[0].Deserialize(ElectronJsonContext.Default.TrayClickEventArgs); + var bounds = array[1].Deserialize(ElectronJsonContext.Default.Rectangle); + _doubleClick(trayClickEventArgs, bounds); + }); + + BridgeConnector.Socket.Emit("register-tray-double-click", GetHashCode()); + } + _doubleClick += value; + } + remove + { + _doubleClick -= value; + + if (_doubleClick == null) + { + BridgeConnector.Socket.Off("tray-double-click" + GetHashCode()); + } + } } private event Action _doubleClick; @@ -52,35 +126,29 @@ public event Action OnDoubleClick /// public event Action OnBalloonShow { - add => ApiEventManager.AddEvent("tray-balloon-show", GetHashCode(), _balloonShow, value); - remove => ApiEventManager.RemoveEvent("tray-balloon-show", GetHashCode(), _balloonShow, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _balloonShow; - /// /// Windows: Emitted when the tray balloon is clicked. /// public event Action OnBalloonClick { - add => ApiEventManager.AddEvent("tray-balloon-click", GetHashCode(), _balloonClick, value); - remove => ApiEventManager.RemoveEvent("tray-balloon-click", GetHashCode(), _balloonClick, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _balloonClick; - /// /// Windows: Emitted when the tray balloon is closed /// because of timeout or user manually closes it. /// public event Action OnBalloonClosed { - add => ApiEventManager.AddEvent("tray-balloon-closed", GetHashCode(), _balloonClosed, value); - remove => ApiEventManager.RemoveEvent("tray-balloon-closed", GetHashCode(), _balloonClosed, value); + add => AddEvent(value, GetHashCode()); + remove => RemoveEvent(value, GetHashCode()); } - private event Action _balloonClosed; - // TODO: Implement macOS Events private static Tray _tray; diff --git a/src/ElectronNET.API/API/WebContents.cs b/src/ElectronNET.API/API/WebContents.cs index 28a8430e..761bfed4 100644 --- a/src/ElectronNET.API/API/WebContents.cs +++ b/src/ElectronNET.API/API/WebContents.cs @@ -1,8 +1,5 @@ using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; -using ElectronNET.Common; using System; -using System.Text.Json; using System.Threading.Tasks; // ReSharper disable InconsistentNaming @@ -12,15 +9,19 @@ namespace ElectronNET.API; /// /// Render and control web pages. /// -public class WebContents +public class WebContents: ApiBase { + protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst; + protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst; + protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.CamelCase; + /// /// Gets the identifier. /// /// /// The identifier. /// - public int Id { get; private set; } + public override int Id { get; protected set; } /// /// Manage browser sessions, cookies, cache, proxy settings, etc. @@ -32,103 +33,85 @@ public class WebContents /// public event Action OnCrashed { - add => ApiEventManager.AddEvent("webContents-crashed", Id, _crashed, value, (args) => args.GetBoolean()); - remove => ApiEventManager.RemoveEvent("webContents-crashed", Id, _crashed, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _crashed; - /// /// Emitted when the navigation is done, i.e. the spinner of the tab has /// stopped spinning, and the onload event was dispatched. /// public event Action OnDidFinishLoad { - add => ApiEventManager.AddEvent("webContents-didFinishLoad", Id, _didFinishLoad, value); - remove => ApiEventManager.RemoveEvent("webContents-didFinishLoad", Id, _didFinishLoad, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _didFinishLoad; - /// /// Emitted when any frame (including main) starts navigating. /// public event Action OnDidStartNavigation { - add => ApiEventManager.AddEvent("webContents-didStartNavigation", Id, _didStartNavigation, value); - remove => ApiEventManager.RemoveEvent("webContents-didStartNavigation", Id, _didStartNavigation, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _didStartNavigation; - /// /// Emitted when a main frame navigation is done. /// This event is not emitted for in-page navigations, such as clicking anchor links or updating the window.location.hash. Use did-navigate-in-page event for this purpose. /// public event Action OnDidNavigate { - add => ApiEventManager.AddEvent("webContents-didNavigate", Id, _didNavigate, value); - remove => ApiEventManager.RemoveEvent("webContents-didNavigate", Id, _didNavigate, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _didNavigate; - /// /// Emitted when a server side redirect occurs during navigation. For example a 302 redirect. /// This event will be emitted after OnDidStartNavigation and always before the OnDidRedirectNavigation event for the same navigation. /// public event Action OnWillRedirect { - add => ApiEventManager.AddEvent("webContents-willRedirect", Id, _willRedirect, value); - remove => ApiEventManager.RemoveEvent("webContents-willRedirect", Id, _willRedirect, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _willRedirect; - /// /// Emitted after a server side redirect occurs during navigation. For example a 302 redirect. /// public event Action OnDidRedirectNavigation { - add => ApiEventManager.AddEvent("webContents-didRedirectNavigation", Id, _didRedirectNavigation, value); - remove => ApiEventManager.RemoveEvent("webContents-didRedirectNavigation", Id, _didRedirectNavigation, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _didRedirectNavigation; - /// /// This event is like OnDidFinishLoad but emitted when the load failed. /// public event Action OnDidFailLoad { - add => ApiEventManager.AddEvent("webContents-didFailLoad", Id, _didFailLoad, value, (args) => args.Deserialize(ElectronJson.Options)); - remove => ApiEventManager.RemoveEvent("webContents-didFailLoad", Id, _didFailLoad, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _didFailLoad; - /// /// Emitted when an input event is sent to the WebContents. /// public event Action InputEvent { - add => ApiEventManager.AddEvent("webContents-input-event", Id, _inputEvent, value, (args) => args.Deserialize(ElectronJson.Options)); - remove => ApiEventManager.RemoveEvent("webContents-input-event", Id, _inputEvent, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _inputEvent; - /// /// Emitted when the document in the top-level frame is loaded. /// public event Action OnDomReady { - add => ApiEventManager.AddEvent("webContents-domReady", Id, _domReady, value); - remove => ApiEventManager.RemoveEvent("webContents-domReady", Id, _domReady, value); + add => AddEvent(value, Id); + remove => RemoveEvent(value, Id); } - private event Action _domReady; - internal WebContents(int id) { Id = id; @@ -156,38 +139,19 @@ public void OpenDevTools(OpenDevToolsOptions openDevToolsOptions) /// Get system printers. /// /// printers - public Task GetPrintersAsync() - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("webContents-getPrinters-completed", tcs.SetResult); - BridgeConnector.Socket.Emit("webContents-getPrinters", Id); - - return tcs.Task; - } + public Task GetPrintersAsync() => GetPropertyAsync(); /// /// Prints window's web page. /// /// /// success - public Task PrintAsync(PrintOptions options = null) - { - var tcs = new TaskCompletionSource(); - - BridgeConnector.Socket.Once("webContents-print-completed", tcs.SetResult); - - if (options == null) - { - BridgeConnector.Socket.Emit("webContents-print", Id, ""); - } - else - { - BridgeConnector.Socket.Emit("webContents-print", Id, options); - } - - return tcs.Task; - } + public Task PrintAsync(PrintOptions options) => GetPropertyAsync(options); + /// + /// Prints window's web page. + /// + /// success + public Task PrintAsync() => GetPropertyAsync(string.Empty); /// /// Prints window's web page as PDF with Chromium's preview printing custom @@ -251,7 +215,7 @@ public Task GetUrl() { var tcs = new TaskCompletionSource(); - BridgeConnector.Socket.Once("webContents-getUrl", tcs.SetResult); + BridgeConnector.Socket.Once("webContents-getUrl" + Id, tcs.SetResult); BridgeConnector.Socket.Emit("webContents-getUrl", Id); return tcs.Task; diff --git a/src/ElectronNET.API/Common/ApiEventManager.cs b/src/ElectronNET.API/Common/ApiEventManager.cs deleted file mode 100644 index 1db069eb..00000000 --- a/src/ElectronNET.API/Common/ApiEventManager.cs +++ /dev/null @@ -1,105 +0,0 @@ -using ElectronNET.API; -using ElectronNET.API.Entities; -using ElectronNET.API.Serialization; -using System; -using System.Linq; -using System.Text.Json; - -namespace ElectronNET.Common; - -internal static class ApiEventManager -{ - internal static void AddEvent(string eventName, object id, Action callback, Action value, string suffix = "") - { - if (callback == null) - { - BridgeConnector.Socket.On(eventName + id, () => { callback(); }); - BridgeConnector.Socket.Emit($"register-{eventName}{suffix}", id); - } - - callback += value; - } - - internal static void RemoveEvent(string eventName, object id, Action callback, Action value) - { - callback -= value; - if (callback == null) BridgeConnector.Socket.Off(eventName + id); - } - - internal static void AddEvent(string eventName, object id, Action callback, Action value, Func converter, string suffix = "") - { - if (callback == null) - { - BridgeConnector.Socket.On(eventName + id, (args) => - { - var converted = converter.Invoke(args); - callback(converted); - }); - BridgeConnector.Socket.Emit($"register-{eventName}{suffix}", id); - } - - callback += value; - } - - internal static void AddEvent(string eventName, object id, Action callback, Action value) - { - if (callback == null) - { - BridgeConnector.Socket.On(eventName + id, (args) => callback(args)); - BridgeConnector.Socket.Emit($"register-{eventName}", id); - } - - callback += value; - } - - internal static void RemoveEvent(string eventName, object id, Action callback, Action value) - { - callback -= value; - if (callback == null) BridgeConnector.Socket.Off(eventName + id); - } - - internal static void AddTrayEvent(string eventName, object id, Action callback, Action value) - { - if (callback == null) - { - BridgeConnector.Socket.On(eventName + id, (result) => - { - var array = result.EnumerateArray().ToArray(); - var trayClickEventArgs = array[0].Deserialize(ElectronJsonContext.Default.TrayClickEventArgs); - var bounds = array[1].Deserialize(ElectronJsonContext.Default.Rectangle); - callback(trayClickEventArgs, bounds); - }); - BridgeConnector.Socket.Emit($"register-{eventName}", id); - callback += value; - } - } - - internal static void RemoveTrayEvent(string eventName, object id, Action callback, Action value) - { - callback -= value; - if (callback == null) BridgeConnector.Socket.Off(eventName + id); - } - - internal static void AddScreenEvent(string eventName, object id, Action callback, Action value) - { - if (callback == null) - { - BridgeConnector.Socket.On(eventName + id, (args) => - { - var arr = args.EnumerateArray().ToArray(); - var display = arr[0].Deserialize(ElectronJsonContext.Default.Display); - var metrics = arr[1].Deserialize(ElectronJson.Options); - callback(display, metrics); - }); - BridgeConnector.Socket.Emit($"register-{eventName}", id); - callback += value; - } - } - - internal static void RemoveScreenEvent(string eventName, object id, Action callback, Action value) - { - callback -= value; - if (callback == null) BridgeConnector.Socket.Off(eventName + id); - } -} - diff --git a/src/ElectronNET.API/Common/Extensions.cs b/src/ElectronNET.API/Common/Extensions.cs index 03a74de3..515488b0 100644 --- a/src/ElectronNET.API/Common/Extensions.cs +++ b/src/ElectronNET.API/Common/Extensions.cs @@ -1,9 +1,11 @@ -namespace ElectronNET.Common -{ - using ElectronNET.Runtime.Data; - using ElectronNET.Runtime.Services; - using System; +using System.Globalization; +using System.Text.RegularExpressions; +using System; +using ElectronNET.Runtime.Data; +using ElectronNET.Runtime.Services; +namespace ElectronNET.Common +{ internal static class Extensions { public static bool IsUnpackaged(this StartupMethod method) @@ -49,6 +51,26 @@ public static string StripAsync(this string str) return str; } + + public static string StripOn(this string str) + { + if (string.IsNullOrWhiteSpace(str) || !str.StartsWith("On", StringComparison.Ordinal)) + { + return str; + } + + return str.Substring(2); + } + + public static string ToDashedEventName(this string str) + { + return string.Join("-", Regex.Split(str.StripOn(), "(? { }); }); // Properties ***** - socket.on('autoUpdater-autoDownload-get', () => { - electronSocket.emit('autoUpdater-autoDownload-get-reply', electron_updater_1.autoUpdater.autoDownload); + socket.on('autoUpdater-autoDownload', () => { + electronSocket.emit('autoUpdater-autoDownload-completed', electron_updater_1.autoUpdater.autoDownload); }); socket.on('autoUpdater-autoDownload-set', (value) => { electron_updater_1.autoUpdater.autoDownload = value; }); - socket.on('autoUpdater-autoInstallOnAppQuit-get', () => { - electronSocket.emit('autoUpdater-autoInstallOnAppQuit-get-reply', electron_updater_1.autoUpdater.autoInstallOnAppQuit); + socket.on('autoUpdater-autoInstallOnAppQuit', () => { + electronSocket.emit('autoUpdater-autoInstallOnAppQuit-completed', electron_updater_1.autoUpdater.autoInstallOnAppQuit); }); socket.on('autoUpdater-autoInstallOnAppQuit-set', (value) => { electron_updater_1.autoUpdater.autoInstallOnAppQuit = value; }); - socket.on('autoUpdater-allowPrerelease-get', () => { - electronSocket.emit('autoUpdater-allowPrerelease-get-reply', electron_updater_1.autoUpdater.allowPrerelease); + socket.on('autoUpdater-allowPrerelease', () => { + electronSocket.emit('autoUpdater-allowPrerelease-completed', electron_updater_1.autoUpdater.allowPrerelease); }); socket.on('autoUpdater-allowPrerelease-set', (value) => { electron_updater_1.autoUpdater.allowPrerelease = value; }); - socket.on('autoUpdater-fullChangelog-get', () => { - electronSocket.emit('autoUpdater-fullChangelog-get-reply', electron_updater_1.autoUpdater.fullChangelog); + socket.on('autoUpdater-fullChangelog', () => { + electronSocket.emit('autoUpdater-fullChangelog-completed', electron_updater_1.autoUpdater.fullChangelog); }); socket.on('autoUpdater-fullChangelog-set', (value) => { electron_updater_1.autoUpdater.fullChangelog = value; }); - socket.on('autoUpdater-allowDowngrade-get', () => { - electronSocket.emit('autoUpdater-allowDowngrade-get-reply', electron_updater_1.autoUpdater.allowDowngrade); + socket.on('autoUpdater-allowDowngrade', () => { + electronSocket.emit('autoUpdater-allowDowngrade-completed', electron_updater_1.autoUpdater.allowDowngrade); }); socket.on('autoUpdater-allowDowngrade-set', (value) => { electron_updater_1.autoUpdater.allowDowngrade = value; }); - socket.on('autoUpdater-updateConfigPath-get', () => { - electronSocket.emit('autoUpdater-updateConfigPath-get-reply', electron_updater_1.autoUpdater.updateConfigPath || ''); + socket.on('autoUpdater-updateConfigPath', () => { + electronSocket.emit('autoUpdater-updateConfigPath-completed', electron_updater_1.autoUpdater.updateConfigPath || ''); }); socket.on('autoUpdater-updateConfigPath-set', (value) => { electron_updater_1.autoUpdater.updateConfigPath = value; }); - socket.on('autoUpdater-currentVersion-get', () => { - electronSocket.emit('autoUpdater-currentVersion-get-reply', electron_updater_1.autoUpdater.currentVersion); + socket.on('autoUpdater-currentVersion', () => { + electronSocket.emit('autoUpdater-currentVersion-completed', electron_updater_1.autoUpdater.currentVersion); }); - socket.on('autoUpdater-channel-get', () => { - electronSocket.emit('autoUpdater-channel-get-reply', electron_updater_1.autoUpdater.channel || ''); + socket.on('autoUpdater-channel', () => { + electronSocket.emit('autoUpdater-channel-completed', electron_updater_1.autoUpdater.channel || ''); }); socket.on('autoUpdater-channel-set', (value) => { electron_updater_1.autoUpdater.channel = value; }); - socket.on('autoUpdater-requestHeaders-get', () => { - electronSocket.emit('autoUpdater-requestHeaders-get-reply', electron_updater_1.autoUpdater.requestHeaders); + socket.on('autoUpdater-requestHeaders', () => { + electronSocket.emit('autoUpdater-requestHeaders-completed', electron_updater_1.autoUpdater.requestHeaders); }); socket.on('autoUpdater-requestHeaders-set', (value) => { electron_updater_1.autoUpdater.requestHeaders = value; }); - socket.on('autoUpdaterCheckForUpdatesAndNotify', async (guid) => { + socket.on('autoUpdater-checkForUpdatesAndNotify', async (guid) => { electron_updater_1.autoUpdater.checkForUpdatesAndNotify().then((updateCheckResult) => { - electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult); + electronSocket.emit('autoUpdater-checkForUpdatesAndNotify-completed' + guid, updateCheckResult); }).catch((error) => { - electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyError' + guid, error); + electronSocket.emit('autoUpdater-checkForUpdatesAndNotifyError' + guid, error); }); }); - socket.on('autoUpdaterCheckForUpdates', async (guid) => { + socket.on('autoUpdater-checkForUpdates', async (guid) => { electron_updater_1.autoUpdater.checkForUpdates().then((updateCheckResult) => { - electronSocket.emit('autoUpdaterCheckForUpdatesComplete' + guid, updateCheckResult); + electronSocket.emit('autoUpdater-checkForUpdates-completed' + guid, updateCheckResult); }).catch((error) => { - electronSocket.emit('autoUpdaterCheckForUpdatesError' + guid, error); + electronSocket.emit('autoUpdater-checkForUpdatesError' + guid, error); }); }); - socket.on('autoUpdaterQuitAndInstall', async (isSilent, isForceRunAfter) => { + socket.on('autoUpdater-quitAndInstall', async (isSilent, isForceRunAfter) => { electron_updater_1.autoUpdater.quitAndInstall(isSilent, isForceRunAfter); }); - socket.on('autoUpdaterDownloadUpdate', async (guid) => { + socket.on('autoUpdater-downloadUpdate', async (guid) => { const downloadedPath = await electron_updater_1.autoUpdater.downloadUpdate(); - electronSocket.emit('autoUpdaterDownloadUpdateComplete' + guid, downloadedPath); + electronSocket.emit('autoUpdater-downloadUpdate-completed' + guid, downloadedPath); }); - socket.on('autoUpdaterGetFeedURL', async (guid) => { + socket.on('autoUpdater-getFeedURL', async (guid) => { const feedUrl = await electron_updater_1.autoUpdater.getFeedURL(); - electronSocket.emit('autoUpdaterGetFeedURLComplete' + guid, feedUrl || ''); + electronSocket.emit('autoUpdater-getFeedURL-completed' + guid, feedUrl || ''); }); }; //# sourceMappingURL=autoUpdater.js.map \ No newline at end of file diff --git a/src/ElectronNET.Host/api/autoUpdater.ts b/src/ElectronNET.Host/api/autoUpdater.ts index 14ddfc83..c1ebb5eb 100644 --- a/src/ElectronNET.Host/api/autoUpdater.ts +++ b/src/ElectronNET.Host/api/autoUpdater.ts @@ -43,101 +43,101 @@ export = (socket: Socket) => { // Properties ***** - socket.on('autoUpdater-autoDownload-get', () => { - electronSocket.emit('autoUpdater-autoDownload-get-reply', autoUpdater.autoDownload); + socket.on('autoUpdater-autoDownload', () => { + electronSocket.emit('autoUpdater-autoDownload-completed', autoUpdater.autoDownload); }); socket.on('autoUpdater-autoDownload-set', (value) => { autoUpdater.autoDownload = value; }); - socket.on('autoUpdater-autoInstallOnAppQuit-get', () => { - electronSocket.emit('autoUpdater-autoInstallOnAppQuit-get-reply', autoUpdater.autoInstallOnAppQuit); + socket.on('autoUpdater-autoInstallOnAppQuit', () => { + electronSocket.emit('autoUpdater-autoInstallOnAppQuit-completed', autoUpdater.autoInstallOnAppQuit); }); socket.on('autoUpdater-autoInstallOnAppQuit-set', (value) => { autoUpdater.autoInstallOnAppQuit = value; }); - socket.on('autoUpdater-allowPrerelease-get', () => { - electronSocket.emit('autoUpdater-allowPrerelease-get-reply', autoUpdater.allowPrerelease); + socket.on('autoUpdater-allowPrerelease', () => { + electronSocket.emit('autoUpdater-allowPrerelease-completed', autoUpdater.allowPrerelease); }); socket.on('autoUpdater-allowPrerelease-set', (value) => { autoUpdater.allowPrerelease = value; }); - socket.on('autoUpdater-fullChangelog-get', () => { - electronSocket.emit('autoUpdater-fullChangelog-get-reply', autoUpdater.fullChangelog); + socket.on('autoUpdater-fullChangelog', () => { + electronSocket.emit('autoUpdater-fullChangelog-completed', autoUpdater.fullChangelog); }); socket.on('autoUpdater-fullChangelog-set', (value) => { autoUpdater.fullChangelog = value; }); - socket.on('autoUpdater-allowDowngrade-get', () => { - electronSocket.emit('autoUpdater-allowDowngrade-get-reply', autoUpdater.allowDowngrade); + socket.on('autoUpdater-allowDowngrade', () => { + electronSocket.emit('autoUpdater-allowDowngrade-completed', autoUpdater.allowDowngrade); }); socket.on('autoUpdater-allowDowngrade-set', (value) => { autoUpdater.allowDowngrade = value; }); - socket.on('autoUpdater-updateConfigPath-get', () => { - electronSocket.emit('autoUpdater-updateConfigPath-get-reply', autoUpdater.updateConfigPath || ''); + socket.on('autoUpdater-updateConfigPath', () => { + electronSocket.emit('autoUpdater-updateConfigPath-completed', autoUpdater.updateConfigPath || ''); }); socket.on('autoUpdater-updateConfigPath-set', (value) => { autoUpdater.updateConfigPath = value; }); - socket.on('autoUpdater-currentVersion-get', () => { - electronSocket.emit('autoUpdater-currentVersion-get-reply', autoUpdater.currentVersion); + socket.on('autoUpdater-currentVersion', () => { + electronSocket.emit('autoUpdater-currentVersion-completed', autoUpdater.currentVersion); }); - socket.on('autoUpdater-channel-get', () => { - electronSocket.emit('autoUpdater-channel-get-reply', autoUpdater.channel || ''); + socket.on('autoUpdater-channel', () => { + electronSocket.emit('autoUpdater-channel-completed', autoUpdater.channel || ''); }); socket.on('autoUpdater-channel-set', (value) => { autoUpdater.channel = value; }); - socket.on('autoUpdater-requestHeaders-get', () => { - electronSocket.emit('autoUpdater-requestHeaders-get-reply', autoUpdater.requestHeaders); + socket.on('autoUpdater-requestHeaders', () => { + electronSocket.emit('autoUpdater-requestHeaders-completed', autoUpdater.requestHeaders); }); socket.on('autoUpdater-requestHeaders-set', (value) => { autoUpdater.requestHeaders = value; }); - socket.on('autoUpdaterCheckForUpdatesAndNotify', async (guid) => { + socket.on('autoUpdater-checkForUpdatesAndNotify', async (guid) => { autoUpdater.checkForUpdatesAndNotify().then((updateCheckResult) => { - electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult); + electronSocket.emit('autoUpdater-checkForUpdatesAndNotify-completed' + guid, updateCheckResult); }).catch((error) => { - electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyError' + guid, error); + electronSocket.emit('autoUpdater-checkForUpdatesAndNotifyError' + guid, error); }); }); - socket.on('autoUpdaterCheckForUpdates', async (guid) => { + socket.on('autoUpdater-checkForUpdates', async (guid) => { autoUpdater.checkForUpdates().then((updateCheckResult) => { - electronSocket.emit('autoUpdaterCheckForUpdatesComplete' + guid, updateCheckResult); + electronSocket.emit('autoUpdater-checkForUpdates-completed' + guid, updateCheckResult); }).catch((error) => { - electronSocket.emit('autoUpdaterCheckForUpdatesError' + guid, error); + electronSocket.emit('autoUpdater-checkForUpdatesError' + guid, error); }); }); - socket.on('autoUpdaterQuitAndInstall', async (isSilent, isForceRunAfter) => { + socket.on('autoUpdater-quitAndInstall', async (isSilent, isForceRunAfter) => { autoUpdater.quitAndInstall(isSilent, isForceRunAfter); }); - socket.on('autoUpdaterDownloadUpdate', async (guid) => { + socket.on('autoUpdater-downloadUpdate', async (guid) => { const downloadedPath = await autoUpdater.downloadUpdate(); - electronSocket.emit('autoUpdaterDownloadUpdateComplete' + guid, downloadedPath); + electronSocket.emit('autoUpdater-downloadUpdate-completed' + guid, downloadedPath); }); - socket.on('autoUpdaterGetFeedURL', async (guid) => { + socket.on('autoUpdater-getFeedURL', async (guid) => { const feedUrl = await autoUpdater.getFeedURL(); - electronSocket.emit('autoUpdaterGetFeedURLComplete' + guid, feedUrl || ''); + electronSocket.emit('autoUpdater-getFeedURL-completed' + guid, feedUrl || ''); }); }; diff --git a/src/ElectronNET.Host/api/browserView.js b/src/ElectronNET.Host/api/browserView.js index 17e01897..98575f01 100644 --- a/src/ElectronNET.Host/api/browserView.js +++ b/src/ElectronNET.Host/api/browserView.js @@ -22,11 +22,11 @@ const browserViewApi = (socket) => { browserViews.push(browserView); electronSocket.emit('BrowserViewCreated', browserView['id']); }); - socket.on('browserView-getBounds', (id) => { + socket.on('browserView-bounds', (id) => { const bounds = getBrowserViewById(id).getBounds(); - electronSocket.emit('browserView-getBounds-reply', bounds); + electronSocket.emit('browserView-bounds-completed', bounds); }); - socket.on('browserView-setBounds', (id, bounds) => { + socket.on('browserView-bounds-set', (id, bounds) => { getBrowserViewById(id).setBounds(bounds); }); socket.on('browserView-setAutoResize', (id, options) => { diff --git a/src/ElectronNET.Host/api/browserView.ts b/src/ElectronNET.Host/api/browserView.ts index 5d7a314b..81c36f88 100644 --- a/src/ElectronNET.Host/api/browserView.ts +++ b/src/ElectronNET.Host/api/browserView.ts @@ -28,13 +28,13 @@ const browserViewApi = (socket: Socket) => { electronSocket.emit('BrowserViewCreated', browserView['id']); }); - socket.on('browserView-getBounds', (id) => { + socket.on('browserView-bounds', (id) => { const bounds = getBrowserViewById(id).getBounds(); - electronSocket.emit('browserView-getBounds-reply', bounds); + electronSocket.emit('browserView-bounds-completed', bounds); }); - socket.on('browserView-setBounds', (id, bounds) => { + socket.on('browserView-bounds-set', (id, bounds) => { getBrowserViewById(id).setBounds(bounds); }); diff --git a/src/ElectronNET.Host/api/clipboard.js b/src/ElectronNET.Host/api/clipboard.js index f7e7ef10..545e152c 100644 --- a/src/ElectronNET.Host/api/clipboard.js +++ b/src/ElectronNET.Host/api/clipboard.js @@ -5,35 +5,35 @@ module.exports = (socket) => { electronSocket = socket; socket.on('clipboard-readText', (type) => { const text = electron_1.clipboard.readText(type); - electronSocket.emit('clipboard-readText-Completed', text); + electronSocket.emit('clipboard-readText-completed', text); }); socket.on('clipboard-writeText', (text, type) => { electron_1.clipboard.writeText(text, type); }); socket.on('clipboard-readHTML', (type) => { const content = electron_1.clipboard.readHTML(type); - electronSocket.emit('clipboard-readHTML-Completed', content); + electronSocket.emit('clipboard-readHTML-completed', content); }); socket.on('clipboard-writeHTML', (markup, type) => { electron_1.clipboard.writeHTML(markup, type); }); socket.on('clipboard-readRTF', (type) => { const content = electron_1.clipboard.readRTF(type); - electronSocket.emit('clipboard-readRTF-Completed', content); + electronSocket.emit('clipboard-readRTF-completed', content); }); socket.on('clipboard-writeRTF', (text, type) => { electron_1.clipboard.writeHTML(text, type); }); socket.on('clipboard-readBookmark', () => { const bookmark = electron_1.clipboard.readBookmark(); - electronSocket.emit('clipboard-readBookmark-Completed', bookmark); + electronSocket.emit('clipboard-readBookmark-completed', bookmark); }); socket.on('clipboard-writeBookmark', (title, url, type) => { electron_1.clipboard.writeBookmark(title, url, type); }); socket.on('clipboard-readFindText', () => { const content = electron_1.clipboard.readFindText(); - electronSocket.emit('clipboard-readFindText-Completed', content); + electronSocket.emit('clipboard-readFindText-completed', content); }); socket.on('clipboard-writeFindText', (text) => { electron_1.clipboard.writeFindText(text); @@ -43,14 +43,14 @@ module.exports = (socket) => { }); socket.on('clipboard-availableFormats', (type) => { const formats = electron_1.clipboard.availableFormats(type); - electronSocket.emit('clipboard-availableFormats-Completed', formats); + electronSocket.emit('clipboard-availableFormats-completed', formats); }); socket.on('clipboard-write', (data, type) => { electron_1.clipboard.write(data, type); }); socket.on('clipboard-readImage', (type) => { const image = electron_1.clipboard.readImage(type); - electronSocket.emit('clipboard-readImage-Completed', { 1: image.toPNG().toString('base64') }); + electronSocket.emit('clipboard-readImage-completed', { 1: image.toPNG().toString('base64') }); }); socket.on('clipboard-writeImage', (data, type) => { const dataContent = JSON.parse(data); diff --git a/src/ElectronNET.Host/api/clipboard.ts b/src/ElectronNET.Host/api/clipboard.ts index 6a172299..7f4f3289 100644 --- a/src/ElectronNET.Host/api/clipboard.ts +++ b/src/ElectronNET.Host/api/clipboard.ts @@ -6,7 +6,7 @@ export = (socket: Socket) => { electronSocket = socket; socket.on('clipboard-readText', (type) => { const text = clipboard.readText(type); - electronSocket.emit('clipboard-readText-Completed', text); + electronSocket.emit('clipboard-readText-completed', text); }); socket.on('clipboard-writeText', (text, type) => { @@ -15,7 +15,7 @@ export = (socket: Socket) => { socket.on('clipboard-readHTML', (type) => { const content = clipboard.readHTML(type); - electronSocket.emit('clipboard-readHTML-Completed', content); + electronSocket.emit('clipboard-readHTML-completed', content); }); socket.on('clipboard-writeHTML', (markup, type) => { @@ -24,7 +24,7 @@ export = (socket: Socket) => { socket.on('clipboard-readRTF', (type) => { const content = clipboard.readRTF(type); - electronSocket.emit('clipboard-readRTF-Completed', content); + electronSocket.emit('clipboard-readRTF-completed', content); }); socket.on('clipboard-writeRTF', (text, type) => { @@ -33,7 +33,7 @@ export = (socket: Socket) => { socket.on('clipboard-readBookmark', () => { const bookmark = clipboard.readBookmark(); - electronSocket.emit('clipboard-readBookmark-Completed', bookmark); + electronSocket.emit('clipboard-readBookmark-completed', bookmark); }); socket.on('clipboard-writeBookmark', (title, url, type) => { @@ -42,7 +42,7 @@ export = (socket: Socket) => { socket.on('clipboard-readFindText', () => { const content = clipboard.readFindText(); - electronSocket.emit('clipboard-readFindText-Completed', content); + electronSocket.emit('clipboard-readFindText-completed', content); }); socket.on('clipboard-writeFindText', (text) => { @@ -55,7 +55,7 @@ export = (socket: Socket) => { socket.on('clipboard-availableFormats', (type) => { const formats = clipboard.availableFormats(type); - electronSocket.emit('clipboard-availableFormats-Completed', formats); + electronSocket.emit('clipboard-availableFormats-completed', formats); }); socket.on('clipboard-write', (data, type) => { @@ -64,7 +64,7 @@ export = (socket: Socket) => { socket.on('clipboard-readImage', (type) => { const image = clipboard.readImage(type); - electronSocket.emit('clipboard-readImage-Completed', { 1: image.toPNG().toString('base64') }); + electronSocket.emit('clipboard-readImage-completed', { 1: image.toPNG().toString('base64') }); }); socket.on('clipboard-writeImage', (data, type) => { diff --git a/src/ElectronNET.Host/api/nativeTheme.js b/src/ElectronNET.Host/api/nativeTheme.js index 0864a4e5..26bfb037 100644 --- a/src/ElectronNET.Host/api/nativeTheme.js +++ b/src/ElectronNET.Host/api/nativeTheme.js @@ -15,9 +15,9 @@ module.exports = (socket) => { const shouldUseInvertedColorScheme = electron_1.nativeTheme.shouldUseInvertedColorScheme; electronSocket.emit('nativeTheme-shouldUseInvertedColorScheme-completed', shouldUseInvertedColorScheme); }); - socket.on('nativeTheme-themeSource-get', () => { + socket.on('nativeTheme-getThemeSource', () => { const themeSource = electron_1.nativeTheme.themeSource; - electronSocket.emit('nativeTheme-themeSource-getCompleted', themeSource); + electronSocket.emit('nativeTheme-getThemeSource-completed', themeSource); }); socket.on('nativeTheme-themeSource', (themeSource) => { electron_1.nativeTheme.themeSource = themeSource; diff --git a/src/ElectronNET.Host/api/nativeTheme.ts b/src/ElectronNET.Host/api/nativeTheme.ts index 333fbc90..c0dda774 100644 --- a/src/ElectronNET.Host/api/nativeTheme.ts +++ b/src/ElectronNET.Host/api/nativeTheme.ts @@ -23,10 +23,10 @@ export = (socket: Socket) => { electronSocket.emit('nativeTheme-shouldUseInvertedColorScheme-completed', shouldUseInvertedColorScheme); }); - socket.on('nativeTheme-themeSource-get', () => { + socket.on('nativeTheme-getThemeSource', () => { const themeSource = nativeTheme.themeSource; - electronSocket.emit('nativeTheme-themeSource-getCompleted', themeSource); + electronSocket.emit('nativeTheme-getThemeSource-completed', themeSource); }); socket.on('nativeTheme-themeSource', (themeSource) => { diff --git a/src/ElectronNET.Host/api/notification.js b/src/ElectronNET.Host/api/notification.js index 2af6d2c8..214b3995 100644 --- a/src/ElectronNET.Host/api/notification.js +++ b/src/ElectronNET.Host/api/notification.js @@ -44,7 +44,7 @@ module.exports = (socket) => { }); socket.on('notificationIsSupported', () => { const isSupported = electron_1.Notification.isSupported(); - electronSocket.emit('notificationIsSupportedComplete', isSupported); + electronSocket.emit('notificationIsSupportedCompleted', isSupported); }); }; //# sourceMappingURL=notification.js.map \ No newline at end of file diff --git a/src/ElectronNET.Host/api/notification.ts b/src/ElectronNET.Host/api/notification.ts index 188aed06..45bc3af8 100644 --- a/src/ElectronNET.Host/api/notification.ts +++ b/src/ElectronNET.Host/api/notification.ts @@ -53,6 +53,6 @@ export = (socket: Socket) => { socket.on('notificationIsSupported', () => { const isSupported = Notification.isSupported(); - electronSocket.emit('notificationIsSupportedComplete', isSupported); + electronSocket.emit('notificationIsSupportedCompleted', isSupported); }); }; diff --git a/src/ElectronNET.Host/api/powerMonitor.js b/src/ElectronNET.Host/api/powerMonitor.js index 0b4dd7a6..c10aa2a2 100644 --- a/src/ElectronNET.Host/api/powerMonitor.js +++ b/src/ElectronNET.Host/api/powerMonitor.js @@ -3,39 +3,39 @@ const electron_1 = require("electron"); let electronSocket; module.exports = (socket) => { electronSocket = socket; - socket.on('register-pm-lock-screen', () => { + socket.on('register-powerMonitor-lock-screen', () => { electron_1.powerMonitor.on('lock-screen', () => { - electronSocket.emit('pm-lock-screen'); + electronSocket.emit('powerMonitor-lock-screen'); }); }); - socket.on('register-pm-unlock-screen', () => { + socket.on('register-powerMonitor-unlock-screen', () => { electron_1.powerMonitor.on('unlock-screen', () => { - electronSocket.emit('pm-unlock-screen'); + electronSocket.emit('powerMonitor-unlock-screen'); }); }); - socket.on('register-pm-suspend', () => { + socket.on('register-powerMonitor-suspend', () => { electron_1.powerMonitor.on('suspend', () => { - electronSocket.emit('pm-suspend'); + electronSocket.emit('powerMonitor-suspend'); }); }); - socket.on('register-pm-resume', () => { + socket.on('register-powerMonitor-resume', () => { electron_1.powerMonitor.on('resume', () => { - electronSocket.emit('pm-resume'); + electronSocket.emit('powerMonitor-resume'); }); }); - socket.on('register-pm-on-ac', () => { + socket.on('register-powerMonitor-ac', () => { electron_1.powerMonitor.on('on-ac', () => { - electronSocket.emit('pm-on-ac'); + electronSocket.emit('powerMonitor-ac'); }); }); - socket.on('register-pm-on-battery', () => { + socket.on('register-powerMonitor-battery', () => { electron_1.powerMonitor.on('on-battery', () => { - electronSocket.emit('pm-on-battery'); + electronSocket.emit('powerMonitor-battery'); }); }); - socket.on('register-pm-shutdown', () => { + socket.on('register-powerMonitor-shutdown', () => { electron_1.powerMonitor.on('shutdown', () => { - electronSocket.emit('pm-shutdown'); + electronSocket.emit('powerMonitor-shutdown'); }); }); }; diff --git a/src/ElectronNET.Host/api/powerMonitor.ts b/src/ElectronNET.Host/api/powerMonitor.ts index f4c1fd45..227ef0d7 100644 --- a/src/ElectronNET.Host/api/powerMonitor.ts +++ b/src/ElectronNET.Host/api/powerMonitor.ts @@ -4,39 +4,39 @@ let electronSocket; export = (socket: Socket) => { electronSocket = socket; - socket.on('register-pm-lock-screen', () => { + socket.on('register-powerMonitor-lock-screen', () => { powerMonitor.on('lock-screen', () => { - electronSocket.emit('pm-lock-screen'); + electronSocket.emit('powerMonitor-lock-screen'); }); }); - socket.on('register-pm-unlock-screen', () => { + socket.on('register-powerMonitor-unlock-screen', () => { powerMonitor.on('unlock-screen', () => { - electronSocket.emit('pm-unlock-screen'); + electronSocket.emit('powerMonitor-unlock-screen'); }); }); - socket.on('register-pm-suspend', () => { + socket.on('register-powerMonitor-suspend', () => { powerMonitor.on('suspend', () => { - electronSocket.emit('pm-suspend'); + electronSocket.emit('powerMonitor-suspend'); }); }); - socket.on('register-pm-resume', () => { + socket.on('register-powerMonitor-resume', () => { powerMonitor.on('resume', () => { - electronSocket.emit('pm-resume'); + electronSocket.emit('powerMonitor-resume'); }); }); - socket.on('register-pm-on-ac', () => { + socket.on('register-powerMonitor-ac', () => { powerMonitor.on('on-ac', () => { - electronSocket.emit('pm-on-ac'); + electronSocket.emit('powerMonitor-ac'); }); }); - socket.on('register-pm-on-battery', () => { + socket.on('register-powerMonitor-battery', () => { powerMonitor.on('on-battery', () => { - electronSocket.emit('pm-on-battery'); + electronSocket.emit('powerMonitor-battery'); }); }); - socket.on('register-pm-shutdown', () => { + socket.on('register-powerMonitor-shutdown', () => { powerMonitor.on('shutdown', () => { - electronSocket.emit('pm-shutdown'); + electronSocket.emit('powerMonitor-shutdown'); }); }); }; diff --git a/src/ElectronNET.Host/api/process.js b/src/ElectronNET.Host/api/process.js index 36c08b4a..5e370e90 100644 --- a/src/ElectronNET.Host/api/process.js +++ b/src/ElectronNET.Host/api/process.js @@ -4,59 +4,59 @@ module.exports = (socket) => { electronSocket = socket; socket.on('process-execPath', () => { const value = process.execPath; - electronSocket.emit('process-execPath-Completed', value); + electronSocket.emit('process-execPath-completed', value); }); socket.on('process-argv', () => { const value = process.argv; - electronSocket.emit('process-argv-Completed', value); + electronSocket.emit('process-argv-completed', value); }); socket.on('process-type', () => { const value = process.type; - electronSocket.emit('process-type-Completed', value); + electronSocket.emit('process-type-completed', value); }); socket.on('process-versions', () => { const value = process.versions; - electronSocket.emit('process-versions-Completed', value); + electronSocket.emit('process-versions-completed', value); }); socket.on('process-defaultApp', () => { if (process.defaultApp === undefined) { - electronSocket.emit('process-defaultApp-Completed', false); + electronSocket.emit('process-defaultApp-completed', false); return; } - electronSocket.emit('process-defaultApp-Completed', process.defaultApp); + electronSocket.emit('process-defaultApp-completed', process.defaultApp); }); socket.on('process-isMainFrame', () => { if (process.isMainFrame === undefined) { - electronSocket.emit('process-isMainFrame-Completed', false); + electronSocket.emit('process-isMainFrame-completed', false); return; } - electronSocket.emit('process-isMainFrame-Completed', process.isMainFrame); + electronSocket.emit('process-isMainFrame-completed', process.isMainFrame); }); socket.on('process-resourcesPath', () => { const value = process.resourcesPath; - electronSocket.emit('process-resourcesPath-Completed', value); + electronSocket.emit('process-resourcesPath-completed', value); }); - socket.on('process-uptime', () => { + socket.on('process-upTime', () => { let value = process.uptime(); if (value === undefined) { value = -1; } - electronSocket.emit('process-uptime-Completed', value); + electronSocket.emit('process-upTime-completed', value); }); socket.on('process-pid', () => { if (process.pid === undefined) { - electronSocket.emit('process-pid-Completed', -1); + electronSocket.emit('process-pid-completed', -1); return; } - electronSocket.emit('process-pid-Completed', process.pid); + electronSocket.emit('process-pid-completed', process.pid); }); socket.on('process-arch', () => { const value = process.arch; - electronSocket.emit('process-arch-Completed', value); + electronSocket.emit('process-arch-completed', value); }); socket.on('process-platform', () => { const value = process.platform; - electronSocket.emit('process-platform-Completed', value); + electronSocket.emit('process-platform-completed', value); }); }; //# sourceMappingURL=process.js.map \ No newline at end of file diff --git a/src/ElectronNET.Host/api/process.ts b/src/ElectronNET.Host/api/process.ts index ad04dbf2..e7a6b541 100644 --- a/src/ElectronNET.Host/api/process.ts +++ b/src/ElectronNET.Host/api/process.ts @@ -6,68 +6,68 @@ export = (socket: Socket) => { socket.on('process-execPath', () => { const value = process.execPath; - electronSocket.emit('process-execPath-Completed', value); + electronSocket.emit('process-execPath-completed', value); }); socket.on('process-argv', () => { const value = process.argv; - electronSocket.emit('process-argv-Completed', value); + electronSocket.emit('process-argv-completed', value); }); socket.on('process-type', () => { const value = process.type; - electronSocket.emit('process-type-Completed', value); + electronSocket.emit('process-type-completed', value); }); socket.on('process-versions', () => { const value = process.versions; - electronSocket.emit('process-versions-Completed', value); + electronSocket.emit('process-versions-completed', value); }); socket.on('process-defaultApp', () => { if (process.defaultApp === undefined) { - electronSocket.emit('process-defaultApp-Completed', false); + electronSocket.emit('process-defaultApp-completed', false); return; } - electronSocket.emit('process-defaultApp-Completed', process.defaultApp); + electronSocket.emit('process-defaultApp-completed', process.defaultApp); }); socket.on('process-isMainFrame', () => { if (process.isMainFrame === undefined) { - electronSocket.emit('process-isMainFrame-Completed', false); + electronSocket.emit('process-isMainFrame-completed', false); return; } - electronSocket.emit('process-isMainFrame-Completed', process.isMainFrame); + electronSocket.emit('process-isMainFrame-completed', process.isMainFrame); }); socket.on('process-resourcesPath', () => { const value = process.resourcesPath; - electronSocket.emit('process-resourcesPath-Completed', value); + electronSocket.emit('process-resourcesPath-completed', value); }); - socket.on('process-uptime', () => { + socket.on('process-upTime', () => { let value = process.uptime(); if (value === undefined) { value = -1; } - electronSocket.emit('process-uptime-Completed', value); + electronSocket.emit('process-upTime-completed', value); }); socket.on('process-pid', () => { if (process.pid === undefined) { - electronSocket.emit('process-pid-Completed', -1); + electronSocket.emit('process-pid-completed', -1); return; } - electronSocket.emit('process-pid-Completed', process.pid); + electronSocket.emit('process-pid-completed', process.pid); }); socket.on('process-arch', () => { const value = process.arch; - electronSocket.emit('process-arch-Completed', value); + electronSocket.emit('process-arch-completed', value); }); socket.on('process-platform', () => { const value = process.platform; - electronSocket.emit('process-platform-Completed', value); + electronSocket.emit('process-platform-completed', value); }) }; diff --git a/src/ElectronNET.Host/api/screen.js b/src/ElectronNET.Host/api/screen.js index f1525a79..1df6316b 100644 --- a/src/ElectronNET.Host/api/screen.js +++ b/src/ElectronNET.Host/api/screen.js @@ -20,27 +20,27 @@ module.exports = (socket) => { }); socket.on('screen-getCursorScreenPoint', () => { const point = electron_1.screen.getCursorScreenPoint(); - electronSocket.emit('screen-getCursorScreenPointCompleted', point); + electronSocket.emit('screen-getCursorScreenPoint-completed', point); }); - socket.on('screen-getMenuBarHeight', () => { + socket.on('screen-getMenuBarWorkArea', () => { const height = electron_1.screen.getPrimaryDisplay().workArea; - electronSocket.emit('screen-getMenuBarHeightCompleted', height); + electronSocket.emit('screen-getMenuBarWorkArea-completed', height); }); socket.on('screen-getPrimaryDisplay', () => { const display = electron_1.screen.getPrimaryDisplay(); - electronSocket.emit('screen-getPrimaryDisplayCompleted', display); + electronSocket.emit('screen-getPrimaryDisplay-completed', display); }); socket.on('screen-getAllDisplays', () => { const display = electron_1.screen.getAllDisplays(); - electronSocket.emit('screen-getAllDisplaysCompleted', display); + electronSocket.emit('screen-getAllDisplays-completed', display); }); socket.on('screen-getDisplayNearestPoint', (point) => { const display = electron_1.screen.getDisplayNearestPoint(point); - electronSocket.emit('screen-getDisplayNearestPointCompleted', display); + electronSocket.emit('screen-getDisplayNearestPoint-completed', display); }); socket.on('screen-getDisplayMatching', (rectangle) => { const display = electron_1.screen.getDisplayMatching(rectangle); - electronSocket.emit('screen-getDisplayMatchingCompleted', display); + electronSocket.emit('screen-getDisplayMatching-completed', display); }); }; //# sourceMappingURL=screen.js.map \ No newline at end of file diff --git a/src/ElectronNET.Host/api/screen.ts b/src/ElectronNET.Host/api/screen.ts index 1f8795f0..beac16a0 100644 --- a/src/ElectronNET.Host/api/screen.ts +++ b/src/ElectronNET.Host/api/screen.ts @@ -25,31 +25,31 @@ export = (socket: Socket) => { socket.on('screen-getCursorScreenPoint', () => { const point = screen.getCursorScreenPoint(); - electronSocket.emit('screen-getCursorScreenPointCompleted', point); + electronSocket.emit('screen-getCursorScreenPoint-completed', point); }); - socket.on('screen-getMenuBarHeight', () => { + socket.on('screen-getMenuBarWorkArea', () => { const height = screen.getPrimaryDisplay().workArea; - electronSocket.emit('screen-getMenuBarHeightCompleted', height); + electronSocket.emit('screen-getMenuBarWorkArea-completed', height); }); socket.on('screen-getPrimaryDisplay', () => { const display = screen.getPrimaryDisplay(); - electronSocket.emit('screen-getPrimaryDisplayCompleted', display); + electronSocket.emit('screen-getPrimaryDisplay-completed', display); }); socket.on('screen-getAllDisplays', () => { const display = screen.getAllDisplays(); - electronSocket.emit('screen-getAllDisplaysCompleted', display); + electronSocket.emit('screen-getAllDisplays-completed', display); }); socket.on('screen-getDisplayNearestPoint', (point) => { const display = screen.getDisplayNearestPoint(point); - electronSocket.emit('screen-getDisplayNearestPointCompleted', display); + electronSocket.emit('screen-getDisplayNearestPoint-completed', display); }); socket.on('screen-getDisplayMatching', (rectangle) => { const display = screen.getDisplayMatching(rectangle); - electronSocket.emit('screen-getDisplayMatchingCompleted', display); + electronSocket.emit('screen-getDisplayMatching-completed', display); }); }; diff --git a/src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj b/src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj index 0c3ac246..373440c2 100644 --- a/src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj +++ b/src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj @@ -24,6 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/ElectronNET.IntegrationTests/Tests/AppTests.cs b/src/ElectronNET.IntegrationTests/Tests/AppTests.cs index 3e77d27a..4512f6b9 100644 --- a/src/ElectronNET.IntegrationTests/Tests/AppTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/AppTests.cs @@ -17,7 +17,7 @@ public AppTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_app_path() { var path = await Electron.App.GetAppPathAsync(); @@ -25,7 +25,7 @@ public async Task Can_get_app_path() Directory.Exists(path).Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_version_and_locale() { var version = await Electron.App.GetVersionAsync(); @@ -34,7 +34,7 @@ public async Task Can_get_version_and_locale() locale.Should().NotBeNullOrWhiteSpace(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_special_paths() { var userData = await Electron.App.GetPathAsync(PathName.UserData); @@ -47,7 +47,7 @@ public async Task Can_get_special_paths() } - [Fact] + [Fact(Timeout = 20000)] public async Task Badge_count_roundtrip_where_supported() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) @@ -68,7 +68,7 @@ public async Task Badge_count_roundtrip_where_supported() } } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_app_metrics() { var metrics = await Electron.App.GetAppMetricsAsync(); @@ -76,29 +76,29 @@ public async Task Can_get_app_metrics() metrics.Length.Should().BeGreaterThan(0); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_gpu_feature_status() { var status = await Electron.App.GetGpuFeatureStatusAsync(); status.Should().NotBeNull(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_login_item_settings() { var settings = await Electron.App.GetLoginItemSettingsAsync(); settings.Should().NotBeNull(); } - [Fact] - public void Can_set_app_logs_path() + [Fact(Timeout = 20000)] + public async Task Can_set_app_logs_path() { var tempDir = Path.Combine(Path.GetTempPath(), "ElectronLogsTest" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempDir); Electron.App.SetAppLogsPath(tempDir); } - [Fact] + [Fact(Timeout = 20000)] public async Task CommandLine_append_and_query_switch() { var switchName = "integration-switch"; @@ -107,7 +107,7 @@ public async Task CommandLine_append_and_query_switch() (await Electron.App.CommandLine.GetSwitchValueAsync(switchName)).Should().Be("value123"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Accessibility_support_toggle() { Electron.App.SetAccessibilitySupportEnabled(true); @@ -116,7 +116,7 @@ public async Task Accessibility_support_toggle() Electron.App.SetAccessibilitySupportEnabled(false); } - [Fact] + [Fact(Timeout = 20000)] public async Task UserAgentFallback_roundtrip() { var original = await Electron.App.UserAgentFallbackAsync; @@ -126,7 +126,7 @@ public async Task UserAgentFallback_roundtrip() Electron.App.UserAgentFallback = original; // restore } - [Fact] + [Fact(Timeout = 20000)] public async Task BadgeCount_set_and_reset_where_supported() { await Electron.App.SetBadgeCountAsync(2); @@ -136,14 +136,14 @@ public async Task BadgeCount_set_and_reset_where_supported() await Electron.App.SetBadgeCountAsync(0); } - [Fact] + [Fact(Timeout = 20000)] public async Task App_metrics_have_cpu_info() { var metrics = await Electron.App.GetAppMetricsAsync(); metrics[0].Cpu.Should().NotBeNull(); } - [Fact] + [Fact(Timeout = 20000)] public async Task App_badge_count_roundtrip() { // Set then get (non-mac platforms treat as no-op but should return0 or set value) @@ -154,7 +154,7 @@ public async Task App_badge_count_roundtrip() (count ==3 || count ==0).Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task App_gpu_feature_status_has_some_fields() { var status = await Electron.App.GetGpuFeatureStatusAsync(); diff --git a/src/ElectronNET.IntegrationTests/Tests/AutoUpdaterTests.cs b/src/ElectronNET.IntegrationTests/Tests/AutoUpdaterTests.cs new file mode 100644 index 00000000..4da2734b --- /dev/null +++ b/src/ElectronNET.IntegrationTests/Tests/AutoUpdaterTests.cs @@ -0,0 +1,132 @@ +namespace ElectronNET.IntegrationTests.Tests +{ + using API; + using System.Threading.Tasks; + + [Collection("ElectronCollection")] + public class AutoUpdaterTests + { + private readonly ElectronFixture fx; + public AutoUpdaterTests(ElectronFixture fx) + { + this.fx = fx; + } + + [Fact(Timeout = 20000)] + public async Task AutoDownload_check() + { + Electron.AutoUpdater.AutoDownload = false; + var test1 = Electron.AutoUpdater.AutoDownload; + Electron.AutoUpdater.AutoDownload = true; + var test2 = Electron.AutoUpdater.AutoDownload; + test1.Should().BeFalse(); + test2.Should().BeTrue(); + } + + [Fact(Timeout = 20000)] + public async Task AutoInstallOnAppQuit_check() + { + Electron.AutoUpdater.AutoInstallOnAppQuit = false; + var test1 = Electron.AutoUpdater.AutoInstallOnAppQuit; + Electron.AutoUpdater.AutoInstallOnAppQuit = true; + var test2 = Electron.AutoUpdater.AutoInstallOnAppQuit; + test1.Should().BeFalse(); + test2.Should().BeTrue(); + } + + [Fact(Timeout = 20000)] + public async Task AllowPrerelease_check() + { + Electron.AutoUpdater.AllowPrerelease = false; + var test1 = Electron.AutoUpdater.AllowPrerelease; + Electron.AutoUpdater.AllowPrerelease = true; + var test2 = Electron.AutoUpdater.AllowPrerelease; + test1.Should().BeFalse(); + test2.Should().BeTrue(); + } + + [Fact(Timeout = 20000)] + public async Task FullChangelog_check() + { + Electron.AutoUpdater.FullChangelog = false; + var test1 = Electron.AutoUpdater.FullChangelog; + Electron.AutoUpdater.FullChangelog = true; + var test2 = Electron.AutoUpdater.FullChangelog; + test1.Should().BeFalse(); + test2.Should().BeTrue(); + } + + [Fact(Timeout = 20000)] + public async Task AllowDowngrade_check() + { + Electron.AutoUpdater.AllowDowngrade = false; + var test1 = Electron.AutoUpdater.AllowDowngrade; + Electron.AutoUpdater.AllowDowngrade = true; + var test2 = Electron.AutoUpdater.AllowDowngrade; + test1.Should().BeFalse(); + test2.Should().BeTrue(); + } + + [Fact(Timeout = 20000)] + public async Task UpdateConfigPath_check() + { + var test1 = Electron.AutoUpdater.UpdateConfigPath; + test1.Should().Be(string.Empty); + } + + [Fact(Timeout = 20000)] + public async Task CurrentVersionAsync_check() + { + var semver = await Electron.AutoUpdater.CurrentVersionAsync; + semver.Should().NotBeNull(); + semver.Major.Should().BeGreaterThan(0); + } + + [Fact(Timeout = 20000)] + public async Task ChannelAsync_check() + { + var test = await Electron.AutoUpdater.ChannelAsync; + test.Should().Be(string.Empty); + Electron.AutoUpdater.SetChannel = "beta"; + test = await Electron.AutoUpdater.ChannelAsync; + test.Should().Be("beta"); + } + + [Fact(Timeout = 20000)] + public async Task RequestHeadersAsync_check() + { + var headers = new Dictionary + { + { "key1", "value1" }, + }; + var test = await Electron.AutoUpdater.RequestHeadersAsync; + test.Should().BeNull(); + Electron.AutoUpdater.RequestHeaders = headers; + test = await Electron.AutoUpdater.RequestHeadersAsync; + test.Should().NotBeNull(); + test.Count.Should().Be(1); + test["key1"].Should().Be("value1"); + } + + [Fact(Timeout = 20000)] + public async Task CheckForUpdatesAsync_check() + { + var test = await Electron.AutoUpdater.CheckForUpdatesAsync(); + test.Should().BeNull(); + } + + [Fact(Timeout = 20000)] + public async Task CheckForUpdatesAndNotifyAsync_check() + { + var test = await Electron.AutoUpdater.CheckForUpdatesAsync(); + test.Should().BeNull(); + } + + [Fact(Timeout = 20000)] + public async Task GetFeedURLAsync_check() + { + var test = await Electron.AutoUpdater.GetFeedURLAsync(); + test.Should().Contain("Deprecated"); + } + } +} diff --git a/src/ElectronNET.IntegrationTests/Tests/BrowserViewTests.cs b/src/ElectronNET.IntegrationTests/Tests/BrowserViewTests.cs index 754c9b08..3e1b626f 100644 --- a/src/ElectronNET.IntegrationTests/Tests/BrowserViewTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/BrowserViewTests.cs @@ -12,7 +12,7 @@ public BrowserViewTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Create_browser_view_and_adjust_bounds() { var view = await Electron.WindowManager.CreateBrowserViewAsync(new BrowserViewConstructorOptions()); diff --git a/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs b/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs index 2d006963..e7e69021 100644 --- a/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs @@ -14,7 +14,7 @@ public BrowserWindowTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_set_and_get_title() { const string title = "Integration Test Title"; @@ -23,7 +23,7 @@ public async Task Can_set_and_get_title() roundTrip.Should().Be(title); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_resize_and_get_size() { this.fx.MainWindow.SetSize(643, 482); @@ -33,7 +33,7 @@ public async Task Can_resize_and_get_size() size[1].Should().Be(482); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_set_progress_bar_and_clear() { this.fx.MainWindow.SetProgressBar(0.5); @@ -42,7 +42,7 @@ public async Task Can_set_progress_bar_and_clear() await Task.Delay(50); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_set_and_get_position() { this.fx.MainWindow.SetPosition(134, 246); @@ -51,7 +51,7 @@ public async Task Can_set_and_get_position() pos.Should().BeEquivalentTo([134, 246]); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_set_and_get_bounds() { var bounds = new Rectangle { X = 10, Y = 20, Width = 400, Height = 300 }; @@ -63,7 +63,7 @@ public async Task Can_set_and_get_bounds() round.Height.Should().Be(300); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_set_and_get_content_bounds() { var bounds = new Rectangle { X = 0, Y = 0, Width = 300, Height = 200 }; @@ -73,7 +73,7 @@ public async Task Can_set_and_get_content_bounds() round.Height.Should().BeGreaterThan(0); } - [Fact] + [Fact(Timeout = 20000)] public async Task Show_hide_visibility_roundtrip() { this.fx.MainWindow.Show(); @@ -82,7 +82,7 @@ public async Task Show_hide_visibility_roundtrip() (await this.fx.MainWindow.IsVisibleAsync()).Should().BeFalse(); } - [Fact] + [Fact(Timeout = 20000)] public async Task AlwaysOnTop_toggle_and_query() { this.fx.MainWindow.SetAlwaysOnTop(true); @@ -91,7 +91,7 @@ public async Task AlwaysOnTop_toggle_and_query() (await this.fx.MainWindow.IsAlwaysOnTopAsync()).Should().BeFalse(); } - [Fact] + [Fact(Timeout = 20000)] public async Task MenuBar_auto_hide_and_visibility() { this.fx.MainWindow.SetAutoHideMenuBar(true); @@ -102,7 +102,7 @@ public async Task MenuBar_auto_hide_and_visibility() (await this.fx.MainWindow.IsMenuBarVisibleAsync()).Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task ReadyToShow_event_fires_after_content_ready() { var window = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { Show = false }); @@ -122,7 +122,7 @@ public async Task ReadyToShow_event_fires_after_content_ready() window.Show(); } - [Fact] + [Fact(Timeout = 20000)] public async Task PageTitleUpdated_event_fires_on_title_change() { var window = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { Show = true }); @@ -142,7 +142,7 @@ public async Task PageTitleUpdated_event_fires_on_title_change() (await tcs.Task).Should().Be("NewTitle"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Resize_event_fires_on_size_change() { var window = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { Show = false }); @@ -153,7 +153,7 @@ public async Task Resize_event_fires_on_size_change() resized.Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Progress_bar_and_always_on_top_toggle() { var win = this.fx.MainWindow; @@ -165,7 +165,7 @@ public async Task Progress_bar_and_always_on_top_toggle() (await win.IsAlwaysOnTopAsync()).Should().BeFalse(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Menu_bar_visibility_and_auto_hide() { var win = this.fx.MainWindow; @@ -175,7 +175,7 @@ public async Task Menu_bar_visibility_and_auto_hide() (await win.IsMenuBarVisibleAsync()).Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Parent_child_relationship_roundtrip() { var child = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { Show = false, Width = 300, Height = 200 }); @@ -188,7 +188,7 @@ public async Task Parent_child_relationship_roundtrip() child.Destroy(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Represented_filename_and_edited_flags() { var win = this.fx.MainWindow; diff --git a/src/ElectronNET.IntegrationTests/Tests/ClipboardTests.cs b/src/ElectronNET.IntegrationTests/Tests/ClipboardTests.cs index 1f7d74f7..b3bd2dd1 100644 --- a/src/ElectronNET.IntegrationTests/Tests/ClipboardTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/ClipboardTests.cs @@ -13,7 +13,7 @@ public ClipboardTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Clipboard_text_roundtrip() { var text = $"Hello Electron {Guid.NewGuid()}"; @@ -22,7 +22,7 @@ public async Task Clipboard_text_roundtrip() read.Should().Be(text); } - [Fact] + [Fact(Timeout = 20000)] public async Task Available_formats_contains_text_after_write() { var text = "FormatsTest"; @@ -31,7 +31,7 @@ public async Task Available_formats_contains_text_after_write() formats.Should().Contain(f => f.Contains("text") || f.Contains("TEXT") || f.Contains("plain")); } - [Fact] + [Fact(Timeout = 20000)] public async Task Bookmark_write_and_read() { var url = "https://electron-test.com"; diff --git a/src/ElectronNET.IntegrationTests/Tests/GlobalShortcutTests.cs b/src/ElectronNET.IntegrationTests/Tests/GlobalShortcutTests.cs index 32564260..625618f3 100644 --- a/src/ElectronNET.IntegrationTests/Tests/GlobalShortcutTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/GlobalShortcutTests.cs @@ -6,7 +6,7 @@ namespace ElectronNET.IntegrationTests.Tests [Collection("ElectronCollection")] public class GlobalShortcutTests { - [Fact] + [Fact(Timeout = 20000)] public async Task Can_register_and_unregister() { var accel = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "Cmd+Alt+G" : "Ctrl+Alt+G"; diff --git a/src/ElectronNET.IntegrationTests/Tests/IpcMainTests.cs b/src/ElectronNET.IntegrationTests/Tests/IpcMainTests.cs index 80b979bd..73901897 100644 --- a/src/ElectronNET.IntegrationTests/Tests/IpcMainTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/IpcMainTests.cs @@ -11,7 +11,7 @@ public IpcMainTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Ipc_On_receives_message_from_renderer() { var tcs = new TaskCompletionSource(); @@ -21,7 +21,7 @@ public async Task Ipc_On_receives_message_from_renderer() result.Should().Be("payload123"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Ipc_Once_only_fires_once() { var count = 0; @@ -31,7 +31,7 @@ public async Task Ipc_Once_only_fires_once() count.Should().Be(1); } - [Fact] + [Fact(Timeout = 20000)] public async Task Ipc_RemoveAllListeners_stops_receiving() { var fired = false; @@ -42,7 +42,7 @@ public async Task Ipc_RemoveAllListeners_stops_receiving() fired.Should().BeFalse(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Ipc_OnSync_returns_value() { Electron.IpcMain.OnSync("ipc-sync-test", (obj) => @@ -54,7 +54,7 @@ public async Task Ipc_OnSync_returns_value() ret.Should().Be("pong"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Ipc_Send_from_main_reaches_renderer() { // Listener: store raw arg; if Electron packs differently we will normalize later diff --git a/src/ElectronNET.IntegrationTests/Tests/MenuTests.cs b/src/ElectronNET.IntegrationTests/Tests/MenuTests.cs index 120f045b..d40d8984 100644 --- a/src/ElectronNET.IntegrationTests/Tests/MenuTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/MenuTests.cs @@ -12,7 +12,7 @@ public MenuTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task ApplicationMenu_click_invokes_handler() { var clicked = false; @@ -38,7 +38,7 @@ public async Task ApplicationMenu_click_invokes_handler() clicked.Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task ContextMenu_popup_registers_items() { var win = this.fx.MainWindow; diff --git a/src/ElectronNET.IntegrationTests/Tests/MultiEventRegistrationTests.cs b/src/ElectronNET.IntegrationTests/Tests/MultiEventRegistrationTests.cs index 2561aece..e00c8509 100644 --- a/src/ElectronNET.IntegrationTests/Tests/MultiEventRegistrationTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/MultiEventRegistrationTests.cs @@ -17,7 +17,7 @@ private static async Task WaitAllOrTimeout(TimeSpan timeout, params Task[] return ReferenceEquals(completed, all) && all.IsCompletedSuccessfully; } - [Fact] + [Fact(Timeout = 20000)] public async Task BrowserWindow_OnResize_multiple_handlers_called() { var win = this.fx.MainWindow; @@ -41,7 +41,7 @@ public async Task BrowserWindow_OnResize_multiple_handlers_called() } } - [Fact] + [Fact(Timeout = 20000)] public async Task WebContents_OnDomReady_multiple_handlers_called() { var wc = this.fx.MainWindow.WebContents; diff --git a/src/ElectronNET.IntegrationTests/Tests/NativeImageTests.cs b/src/ElectronNET.IntegrationTests/Tests/NativeImageTests.cs index 35d7825e..da59c925 100644 --- a/src/ElectronNET.IntegrationTests/Tests/NativeImageTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/NativeImageTests.cs @@ -1,14 +1,16 @@ +using System.Runtime.Versioning; using RectangleEntity = ElectronNET.API.Entities.Rectangle; namespace ElectronNET.IntegrationTests.Tests { using System.Drawing; using ElectronNET.API.Entities; - + + [SupportedOSPlatform("Windows")] public class NativeImageTests { - [Fact] - public void Create_from_bitmap_and_to_png() + [SkippableFact(Timeout = 20000)] + public async Task Create_from_bitmap_and_to_png() { using var bmp = new Bitmap(10, 10); using (var g = Graphics.FromImage(bmp)) @@ -25,8 +27,8 @@ public void Create_from_bitmap_and_to_png() png!.Length.Should().BeGreaterThan(0); } - [Fact] - public void Create_from_buffer_and_to_data_url() + [SkippableFact(Timeout = 20000)] + public async Task Create_from_buffer_and_to_data_url() { // Prepare PNG bytes using var bmp = new Bitmap(8, 8); @@ -44,8 +46,8 @@ public void Create_from_buffer_and_to_data_url() dataUrl!.StartsWith("data:image/", StringComparison.Ordinal).Should().BeTrue(); } - [Fact] - public void Resize_and_crop_produce_expected_sizes() + [SkippableFact(Timeout = 20000)] + public async Task Resize_and_crop_produce_expected_sizes() { using var bmp = new Bitmap(12, 10); using (var g = Graphics.FromImage(bmp)) @@ -64,8 +66,8 @@ public void Resize_and_crop_produce_expected_sizes() csize.Height.Should().Be(3); } - [Fact] - public void Add_representation_for_scale_factor() + [SkippableFact(Timeout = 20000)] + public async Task Add_representation_for_scale_factor() { using var bmp = new Bitmap(5, 5); using (var g = Graphics.FromImage(bmp)) diff --git a/src/ElectronNET.IntegrationTests/Tests/NativeThemeTests.cs b/src/ElectronNET.IntegrationTests/Tests/NativeThemeTests.cs index aeffee81..f6b8f5ce 100644 --- a/src/ElectronNET.IntegrationTests/Tests/NativeThemeTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/NativeThemeTests.cs @@ -6,7 +6,7 @@ namespace ElectronNET.IntegrationTests.Tests [Collection("ElectronCollection")] public class NativeThemeTests { - [Fact] + [Fact(Timeout = 20000)] public async Task ThemeSource_roundtrip() { // Capture initial @@ -14,17 +14,23 @@ public async Task ThemeSource_roundtrip() // Force light Electron.NativeTheme.SetThemeSource(ThemeSourceMode.Light); var useDarkAfterLight = await Electron.NativeTheme.ShouldUseDarkColorsAsync(); + var themeSourceLight = await Electron.NativeTheme.GetThemeSourceAsync(); // Force dark Electron.NativeTheme.SetThemeSource(ThemeSourceMode.Dark); var useDarkAfterDark = await Electron.NativeTheme.ShouldUseDarkColorsAsync(); + var themeSourceDark = await Electron.NativeTheme.GetThemeSourceAsync(); // Restore system Electron.NativeTheme.SetThemeSource(ThemeSourceMode.System); + var themeSourceSystem = await Electron.NativeTheme.GetThemeSourceAsync(); // Assertions are tolerant (platform dependent) useDarkAfterLight.Should().BeFalse("forcing Light should result in light colors"); useDarkAfterDark.Should().BeTrue("forcing Dark should result in dark colors"); + themeSourceLight.Should().Be(ThemeSourceMode.Light); + themeSourceDark.Should().Be(ThemeSourceMode.Dark); + themeSourceSystem.Should().Be(ThemeSourceMode.System); } - [Fact] + [Fact(Timeout = 20000)] public async Task Updated_event_fires_on_change() { var fired = false; @@ -39,5 +45,19 @@ public async Task Updated_event_fires_on_change() fired.Should().BeTrue(); } + + [Fact(Timeout = 20000)] + public async Task Should_use_high_contrast_colors_check() + { + var metrics = await Electron.NativeTheme.ShouldUseHighContrastColorsAsync(); + metrics.Should().Be(false); + } + + [Fact(Timeout = 20000)] + public async Task Should_use_inverted_colors_check() + { + var metrics = await Electron.NativeTheme.ShouldUseInvertedColorSchemeAsync(); + metrics.Should().Be(false); + } } } \ No newline at end of file diff --git a/src/ElectronNET.IntegrationTests/Tests/NotificationTests.cs b/src/ElectronNET.IntegrationTests/Tests/NotificationTests.cs index 5e3439bb..c192dcea 100644 --- a/src/ElectronNET.IntegrationTests/Tests/NotificationTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/NotificationTests.cs @@ -6,7 +6,7 @@ namespace ElectronNET.IntegrationTests.Tests [Collection("ElectronCollection")] public class NotificationTests { - [Fact] + [Fact(Timeout = 20000)] public async Task Notification_create_check() { var tcs = new TaskCompletionSource(); @@ -21,7 +21,7 @@ public async Task Notification_create_check() tcs.Task.IsCompletedSuccessfully.Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Notification_is_supported_check() { var supported = await Electron.Notification.IsSupportedAsync(); diff --git a/src/ElectronNET.IntegrationTests/Tests/ProcessTests.cs b/src/ElectronNET.IntegrationTests/Tests/ProcessTests.cs index 2c8ae098..d581c3b4 100644 --- a/src/ElectronNET.IntegrationTests/Tests/ProcessTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/ProcessTests.cs @@ -5,7 +5,7 @@ namespace ElectronNET.IntegrationTests.Tests [Collection("ElectronCollection")] public class ProcessTests { - [Fact] + [Fact(Timeout = 20000)] public async Task Process_info_is_accessible() { // Use renderer to fetch process info and round-trip @@ -14,15 +14,45 @@ public async Task Process_info_is_accessible() result.Should().Be("ok"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Process_properties_are_populated() { var execPath = await Electron.Process.ExecPathAsync; execPath.Should().NotBeNullOrWhiteSpace(); + var pid = await Electron.Process.PidAsync; pid.Should().BeGreaterThan(0); + var platform = await Electron.Process.PlatformAsync; platform.Should().NotBeNullOrWhiteSpace(); + + var argv = await Electron.Process.ArgvAsync; + argv.Should().NotBeNull(); + argv.Length.Should().BeGreaterThan(0); + + var type = await Electron.Process.TypeAsync; + type.Should().NotBeNullOrWhiteSpace(); + + var version = await Electron.Process.VersionsAsync; + version.Should().NotBeNull(); + version.Chrome.Should().NotBeNullOrWhiteSpace(); + version.Electron.Should().NotBeNullOrWhiteSpace(); + + var defaultApp = await Electron.Process.DefaultAppAsync; + defaultApp.Should().BeTrue(); + + var isMainFrame = await Electron.Process.IsMainFrameAsync; + isMainFrame.Should().BeFalse(); + + var resourcePath = await Electron.Process.ResourcesPathAsync; + resourcePath.Should().NotBeNullOrWhiteSpace(); + + var upTime = await Electron.Process.UpTimeAsync; + upTime.Should().BeGreaterThan(0); + + var arch = await Electron.Process.ArchAsync; + arch.Should().NotBeNullOrWhiteSpace(); + } } diff --git a/src/ElectronNET.IntegrationTests/Tests/ScreenTests.cs b/src/ElectronNET.IntegrationTests/Tests/ScreenTests.cs index 31521fdc..1cdb5347 100644 --- a/src/ElectronNET.IntegrationTests/Tests/ScreenTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/ScreenTests.cs @@ -1,3 +1,5 @@ +using ElectronNET.API.Entities; + namespace ElectronNET.IntegrationTests.Tests { using ElectronNET.API; @@ -13,7 +15,7 @@ public ScreenTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Primary_display_has_positive_dimensions() { var display = await Electron.Screen.GetPrimaryDisplayAsync(); @@ -21,12 +23,62 @@ public async Task Primary_display_has_positive_dimensions() display.Size.Height.Should().BeGreaterThan(0); } - [Fact] + [Fact(Timeout = 20000)] public async Task GetAllDisplays_returns_at_least_one() { var displays = await Electron.Screen.GetAllDisplaysAsync(); displays.Should().NotBeNull(); displays.Length.Should().BeGreaterThan(0); } + + [Fact(Timeout = 20000)] + public async Task GetCursorScreenPoint_check() + { + var point = await Electron.Screen.GetCursorScreenPointAsync(); + point.Should().NotBeNull(); + point.X.Should().BeGreaterThanOrEqualTo(0); + point.Y.Should().BeGreaterThanOrEqualTo(0); + } + + [Fact(Timeout = 20000)] + public async Task GetMenuBarWorkArea_check() + { + var area = await Electron.Screen.GetMenuBarWorkAreaAsync(); + area.Should().NotBeNull(); + area.X.Should().BeGreaterThanOrEqualTo(0); + area.Y.Should().BeGreaterThanOrEqualTo(0); + area.Height.Should().BeGreaterThan(0); + area.Width.Should().BeGreaterThan(0); + } + + [Fact(Timeout = 20000)] + public async Task GetDisplayNearestPoint_check() + { + var point = new Point + { + X = 100, + Y = 100 + }; + var display = await Electron.Screen.GetDisplayNearestPointAsync(point); + display.Should().NotBeNull(); + display.Size.Width.Should().BeGreaterThan(0); + display.Size.Height.Should().BeGreaterThan(0); + } + + [Fact(Timeout = 20000)] + public async Task GetDisplayMatching_check() + { + var rectangle = new Rectangle + { + X = 100, + Y = 100, + Width = 100, + Height = 100 + }; + var display = await Electron.Screen.GetDisplayMatchingAsync(rectangle); + display.Should().NotBeNull(); + display.Size.Width.Should().BeGreaterThan(0); + display.Size.Height.Should().BeGreaterThan(0); + } } } \ No newline at end of file diff --git a/src/ElectronNET.IntegrationTests/Tests/SessionTests.cs b/src/ElectronNET.IntegrationTests/Tests/SessionTests.cs index 3114087c..50243a97 100644 --- a/src/ElectronNET.IntegrationTests/Tests/SessionTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/SessionTests.cs @@ -12,7 +12,7 @@ public SessionTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Session_preloads_roundtrip() { var session = this.fx.MainWindow.WebContents.Session; @@ -23,7 +23,7 @@ public async Task Session_preloads_roundtrip() preloadsAfter.Should().Contain("/tmp/preload_dummy.js"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Session_proxy_set_and_resolve() { var session = this.fx.MainWindow.WebContents.Session; @@ -34,7 +34,7 @@ public async Task Session_proxy_set_and_resolve() } - [Fact] + [Fact(Timeout = 20000)] public async Task Session_clear_cache_and_storage_completes() { var session = this.fx.MainWindow.WebContents.Session; @@ -46,7 +46,7 @@ public async Task Session_clear_cache_and_storage_completes() ua.Should().NotBeNullOrWhiteSpace(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Session_preloads_set_multiple_and_clear() { var session = this.fx.MainWindow.WebContents.Session; @@ -59,7 +59,7 @@ public async Task Session_preloads_set_multiple_and_clear() empty.Should().NotContain("/tmp/a.js"); } - [Fact] + [Fact(Timeout = 20000)] public async Task Clear_auth_cache_overloads() { var session = this.fx.MainWindow.WebContents.Session; @@ -67,29 +67,29 @@ public async Task Clear_auth_cache_overloads() await session.ClearAuthCacheAsync(new RemovePassword("password") { Origin = "https://example.com", Username = "user", Password = "pw", Realm = "realm", Scheme = Scheme.basic }); } - [Fact] + [Fact(Timeout = 20000)] public async Task Clear_storage_with_options() { var session = this.fx.MainWindow.WebContents.Session; await session.ClearStorageDataAsync(new ClearStorageDataOptions { Storages = new[] { "cookies" }, Quotas = new[] { "temporary" } }); } - [Fact] - public void Enable_disable_network_emulation() + [Fact(Timeout = 20000)] + public async Task Enable_disable_network_emulation() { var session = this.fx.MainWindow.WebContents.Session; session.EnableNetworkEmulation(new EnableNetworkEmulationOptions { Offline = false, Latency = 10, DownloadThroughput = 50000, UploadThroughput = 20000 }); session.DisableNetworkEmulation(); } - [Fact] - public void Flush_storage_data_does_not_throw() + [Fact(Timeout = 20000)] + public async Task Flush_storage_data_does_not_throw() { var session = this.fx.MainWindow.WebContents.Session; session.FlushStorageData(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Set_user_agent_affects_new_navigation() { var session = this.fx.MainWindow.WebContents.Session; diff --git a/src/ElectronNET.IntegrationTests/Tests/ShellTests.cs b/src/ElectronNET.IntegrationTests/Tests/ShellTests.cs index 1ce3fb57..e81c762c 100644 --- a/src/ElectronNET.IntegrationTests/Tests/ShellTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/ShellTests.cs @@ -5,7 +5,7 @@ namespace ElectronNET.IntegrationTests.Tests [Collection("ElectronCollection")] public class ShellTests { - [Fact] + [Fact(Timeout = 20000)] public async Task OpenExternal_invalid_scheme_returns_error_or_empty() { var error = await Electron.Shell.OpenExternalAsync("mailto:test@example.com"); diff --git a/src/ElectronNET.IntegrationTests/Tests/ThumbarButtonTests.cs b/src/ElectronNET.IntegrationTests/Tests/ThumbarButtonTests.cs index 49613107..2ba58b14 100644 --- a/src/ElectronNET.IntegrationTests/Tests/ThumbarButtonTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/ThumbarButtonTests.cs @@ -13,7 +13,7 @@ public ThumbarButtonTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task SetThumbarButtons_returns_success() { var btn = new ThumbarButton("icon.png") { Tooltip = "Test" }; @@ -21,7 +21,7 @@ public async Task SetThumbarButtons_returns_success() success.Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Thumbar_button_click_invokes_callback() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) diff --git a/src/ElectronNET.IntegrationTests/Tests/TrayTests.cs b/src/ElectronNET.IntegrationTests/Tests/TrayTests.cs index fdbd9f44..c52a9137 100644 --- a/src/ElectronNET.IntegrationTests/Tests/TrayTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/TrayTests.cs @@ -12,7 +12,7 @@ public TrayTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_create_tray_and_destroy() { //await Electron.Tray.Show("assets/icon.png"); diff --git a/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs b/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs index b3593abb..c7bdde7a 100644 --- a/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs @@ -12,7 +12,7 @@ public WebContentsTests(ElectronFixture fx) this.fx = fx; } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_get_url_after_navigation() { var wc = this.fx.MainWindow.WebContents; @@ -21,7 +21,7 @@ public async Task Can_get_url_after_navigation() url.Should().Contain("example.com"); } - [Fact] + [Fact(Timeout = 20000)] public async Task ExecuteJavaScript_returns_title() { var wc = this.fx.MainWindow.WebContents; @@ -30,7 +30,7 @@ public async Task ExecuteJavaScript_returns_title() title.Should().NotBeNull(); } - [Fact] + [Fact(Timeout = 20000)] public async Task DomReady_event_fires() { var wc = this.fx.MainWindow.WebContents; @@ -41,7 +41,7 @@ public async Task DomReady_event_fires() fired.Should().BeTrue(); } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_print_to_pdf() { var html = "data:text/html,

PDF Test

Electron.NET

"; @@ -63,7 +63,7 @@ public async Task Can_print_to_pdf() } } - [Fact] + [Fact(Timeout = 20000)] public async Task Can_basic_print() { var html = "data:text/html,

Print Test

"; @@ -71,5 +71,13 @@ public async Task Can_basic_print() var ok = await this.fx.MainWindow.WebContents.PrintAsync(new PrintOptions { Silent = true, PrintBackground = true }); ok.Should().BeTrue(); } + + [SkippableFact(Timeout = 20000)] + public async Task GetPrintersAsync_check() + { + Skip.If(Environment.GetEnvironmentVariable("GITHUB_TOKEN") != null, "Skipping printer test in CI environment."); + var info = await fx.MainWindow.WebContents.GetPrintersAsync(); + info.Should().NotBeNull(); + } } } \ No newline at end of file