From a03d7ca7870236142ddd4e8267ec8aa2fce9daa4 Mon Sep 17 00:00:00 2001 From: Jose Luis Chavez del Cid Date: Mon, 24 Jun 2024 02:07:23 -0600 Subject: [PATCH 1/2] Javascript location customization Following the pattern of other libraries from this author added support for settings the customization of the location of the javascript file. This will allow to configure it on the Program.cs file: services.AddURLService(c => { c.BasePath = "/_content/"; }); --- .../BaseJSWrapper.cs | 2 +- .../Extensions/IJSRuntimeExtensions.cs | 13 ++++++++----- .../IServiceCollectionExtensions.cs | 19 +++++++++++++++---- .../Options/FileApiOptions.cs | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs diff --git a/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs b/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs index 4ce4f42..9d9a97b 100644 --- a/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs +++ b/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs @@ -15,7 +15,7 @@ public abstract class BaseJSWrapper : IAsyncDisposable /// A JS reference to an existing JS instance that should be wrapped. internal BaseJSWrapper(IJSRuntime jSRuntime, IJSObjectReference jSReference) { - helperTask = new(jSRuntime.GetHelperAsync); + helperTask = new(() => jSRuntime.GetHelperAsync()); JSReference = jSReference; this.jSRuntime = jSRuntime; } diff --git a/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs b/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs index eee5969..08df30e 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs @@ -1,17 +1,20 @@ -using Microsoft.JSInterop; +using KristofferStrube.Blazor.FileAPI.Options; +using Microsoft.JSInterop; namespace KristofferStrube.Blazor.FileAPI; internal static class IJSRuntimeExtensions { - internal static async Task GetHelperAsync(this IJSRuntime jSRuntime) + internal static async Task GetHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) { + options ??= FileApiOptions.DefaultInstance; return await jSRuntime.InvokeAsync( - "import", "./_content/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.js"); + "import", options.FullScriptPath); } - internal static async Task GetInProcessHelperAsync(this IJSRuntime jSRuntime) + internal static async Task GetInProcessHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) { + options ??= FileApiOptions.DefaultInstance; return await jSRuntime.InvokeAsync( - "import", "./_content/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.js"); + "import", options.FullScriptPath); } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs b/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs index fda72a1..1a9edb0 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs @@ -1,17 +1,28 @@ -using Microsoft.Extensions.DependencyInjection; +using KristofferStrube.Blazor.FileAPI.Options; +using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; namespace KristofferStrube.Blazor.FileAPI; public static class IServiceCollectionExtensions { - public static IServiceCollection AddURLService(this IServiceCollection serviceCollection) + public static IServiceCollection AddURLService(this IServiceCollection serviceCollection, Action? configure) { + serviceCollection.ConfigureFaOptions(configure); return serviceCollection.AddScoped(); } - public static IServiceCollection AddURLServiceInProcess(this IServiceCollection serviceCollection) + public static IServiceCollection AddURLServiceInProcess(this IServiceCollection serviceCollection, Action? configure) { + serviceCollection.ConfigureFaOptions(configure); return serviceCollection.AddScoped(sp => new URLServiceInProcess((IJSInProcessRuntime)sp.GetRequiredService())); } -} + + private static void ConfigureFaOptions(this IServiceCollection services, Action? configure) + { + if (configure is null) return; + + services.Configure(configure); + configure(FileApiOptions.DefaultInstance); + } +} \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs b/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs new file mode 100644 index 0000000..e44196f --- /dev/null +++ b/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs @@ -0,0 +1,18 @@ +using System.Reflection; + +namespace KristofferStrube.Blazor.FileAPI.Options; + +public class FileApiOptions() +{ + public const string DefaultBasePath = "./_content/"; + public static readonly string DefaultNamespace = Assembly.GetExecutingAssembly().GetName().Name ?? "KristofferStrube.Blazor.FileAPI"; + public static readonly string DefaultScriptPath = $"{DefaultNamespace}/{DefaultNamespace}.js"; + + public string BasePath { get; set; } = DefaultBasePath; + public string ScriptPath { get; set; } = DefaultScriptPath; + + public string FullScriptPath => Path.Combine(this.BasePath, this.ScriptPath); + + internal static FileApiOptions DefaultInstance = new(); + +} \ No newline at end of file From c1225a5d5f10339a32a85b6dbc1badcb375c5f8b Mon Sep 17 00:00:00 2001 From: Jose Luis Chavez del Cid Date: Sat, 14 Jun 2025 22:58:27 -0600 Subject: [PATCH 2/2] Blazor Libraries to Work with WebPx Applications --- .../BaseJSWrapper.cs | 47 +- .../Blob.InProcess.cs | 161 +++---- src/KristofferStrube.Blazor.FileAPI/Blob.cs | 195 ++++---- .../Converters/DateTimeConverter.cs | 23 +- .../Converters/EnumDescriptionConverter.cs | 43 +- .../Enums/EndingType.cs | 23 +- .../Extensions/IJSRuntimeExtensions.cs | 27 +- .../IServiceCollectionExtensions.cs | 35 +- .../File.InProcess.cs | 185 ++++---- src/KristofferStrube.Blazor.FileAPI/File.cs | 115 ++--- .../FileReader.InProcess.cs | 397 ++++++++-------- .../FileReader.cs | 431 +++++++++--------- .../IURLService.InProcess.cs | 11 +- .../IURLService.cs | 11 +- .../KristofferStrube.Blazor.FileAPI.csproj | 7 +- .../Options/BlobPart.cs | 75 +-- .../Options/BlobPropertyBag.cs | 29 +- .../Options/FileApiOptions.cs | 21 +- .../Options/FilePropertyBag.cs | 21 +- .../ProgressEvent.InProcess.cs | 65 +-- .../ProgressEvent.cs | 73 +-- .../URLService.InProcess.cs | 59 +-- .../URLService.cs | 59 +-- 23 files changed, 1069 insertions(+), 1044 deletions(-) diff --git a/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs b/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs index 9d9a97b..660e7a7 100644 --- a/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs +++ b/src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs @@ -1,32 +1,33 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -public abstract class BaseJSWrapper : IAsyncDisposable +namespace KristofferStrube.Blazor.FileAPI { - public readonly IJSObjectReference JSReference; - protected readonly Lazy> helperTask; - protected readonly IJSRuntime jSRuntime; - - /// - /// Constructs a wrapper instance for an equivalent JS instance. - /// - /// An instance. - /// A JS reference to an existing JS instance that should be wrapped. - internal BaseJSWrapper(IJSRuntime jSRuntime, IJSObjectReference jSReference) + public abstract class BaseJSWrapper : IAsyncDisposable { - helperTask = new(() => jSRuntime.GetHelperAsync()); - JSReference = jSReference; - this.jSRuntime = jSRuntime; - } + public readonly IJSObjectReference JSReference; + protected readonly Lazy> helperTask; + protected readonly IJSRuntime jSRuntime; - public async ValueTask DisposeAsync() - { - if (helperTask.IsValueCreated) + /// + /// Constructs a wrapper instance for an equivalent JS instance. + /// + /// An instance. + /// A JS reference to an existing JS instance that should be wrapped. + internal BaseJSWrapper(IJSRuntime jSRuntime, IJSObjectReference jSReference) + { + helperTask = new(() => jSRuntime.GetHelperAsync()); + JSReference = jSReference; + this.jSRuntime = jSRuntime; + } + + public async ValueTask DisposeAsync() { - IJSObjectReference module = await helperTask.Value; - await module.DisposeAsync(); + if (helperTask.IsValueCreated) + { + IJSObjectReference module = await helperTask.Value; + await module.DisposeAsync(); + } + GC.SuppressFinalize(this); } - GC.SuppressFinalize(this); } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Blob.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/Blob.InProcess.cs index 986b558..e98659f 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Blob.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Blob.InProcess.cs @@ -1,95 +1,96 @@ using KristofferStrube.Blazor.Streams; using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// Blob browser specs -/// -public class BlobInProcess : Blob +namespace KristofferStrube.Blazor.FileAPI { - public new IJSInProcessObjectReference JSReference; - protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance for a given JS Instance of a . + /// Blob browser specs /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) + public class BlobInProcess : Blob { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - return new BlobInProcess(jSRuntime, inProcessHelper, jSReference); - } + public new IJSInProcessObjectReference JSReference; + protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// The parts that will make the new . - /// Options for constructing the new Blob which includes MIME type and line endings settings. - /// - public static new async Task CreateAsync(IJSRuntime jSRuntime, IList? blobParts = null, BlobPropertyBag? options = null) - { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - object?[]? jsBlobParts = blobParts?.Select(blobPart => blobPart.Part switch - { - byte[] part => part, - Blob part => part.JSReference, - _ => blobPart.Part - }) - .ToArray(); - IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructBlob", jsBlobParts, options); - return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + return new BlobInProcess(jSRuntime, inProcessHelper, jSReference); + } - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// An in process helper instance. - /// A JS reference to an existing . - internal BlobInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) - { - this.inProcessHelper = inProcessHelper; - JSReference = jSReference; - } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// The parts that will make the new . + /// Options for constructing the new Blob which includes MIME type and line endings settings. + /// + public static new async Task CreateAsync(IJSRuntime jSRuntime, IList? blobParts = null, BlobPropertyBag? options = null) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + object?[]? jsBlobParts = blobParts?.Select(blobPart => blobPart.Part switch + { + byte[] part => part, + Blob part => part.JSReference, + _ => blobPart.Part + }) + .ToArray(); + IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructBlob", jsBlobParts, options); + return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); + } - /// - /// Creates a new from the . - /// - /// A new wrapper for a - public new async Task StreamAsync() - { - IJSInProcessObjectReference jSInstance = JSReference.Invoke("stream"); - return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// An in process helper instance. + /// A JS reference to an existing . + internal BlobInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) + { + this.inProcessHelper = inProcessHelper; + JSReference = jSReference; + } - /// - /// The size of this blob. - /// - /// A representing the size of the blob in bytes. - public ulong Size => inProcessHelper.Invoke("getAttribute", JSReference, "size"); + /// + /// Creates a new from the . + /// + /// A new wrapper for a + public new async Task StreamAsync() + { + IJSInProcessObjectReference jSInstance = JSReference.Invoke("stream"); + return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance); + } - /// - /// The media type of this blob. This is either a parseable MIME type or an empty string. - /// - /// The MIME type of this blob. - public string Type => inProcessHelper.Invoke("getAttribute", JSReference, "type"); + /// + /// The size of this blob. + /// + /// A representing the size of the blob in bytes. + public ulong Size => inProcessHelper.Invoke("getAttribute", JSReference, "size"); - /// - /// Gets some range of the content of a as a new . - /// - /// The start index of the range. If or negative then 0 is assumed. - /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. - /// An optional MIME type of the new . If then the MIME type of the original is used. - /// A new . - public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null) - { - start ??= 0; - end ??= (long)Size; - IJSInProcessObjectReference jSInstance = JSReference.Invoke("slice", start, end, contentType); - return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); + /// + /// The media type of this blob. This is either a parseable MIME type or an empty string. + /// + /// The MIME type of this blob. + public string Type => inProcessHelper.Invoke("getAttribute", JSReference, "type"); + + /// + /// Gets some range of the content of a as a new . + /// + /// The start index of the range. If or negative then 0 is assumed. + /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. + /// An optional MIME type of the new . If then the MIME type of the original is used. + /// A new . + public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null) + { + start ??= 0; + end ??= (long)Size; + IJSInProcessObjectReference jSInstance = JSReference.Invoke("slice", start, end, contentType); + return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Blob.cs b/src/KristofferStrube.Blazor.FileAPI/Blob.cs index 78a3634..adc634e 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Blob.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Blob.cs @@ -1,114 +1,115 @@ using KristofferStrube.Blazor.Streams; using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// Blob browser specs -/// -public class Blob : BaseJSWrapper +namespace KristofferStrube.Blazor.FileAPI { /// - /// Constructs a wrapper instance for a given JS Instance of a . + /// Blob browser specs /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static Blob Create(IJSRuntime jSRuntime, IJSObjectReference jSReference) + public class Blob : BaseJSWrapper { - return new Blob(jSRuntime, jSReference); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static Blob Create(IJSRuntime jSRuntime, IJSObjectReference jSReference) + { + return new Blob(jSRuntime, jSReference); + } - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// The parts that will make the new . - /// Options for constructing the new Blob which includes MIME type and line endings settings. - /// - public static async Task CreateAsync(IJSRuntime jSRuntime, IList? blobParts = null, BlobPropertyBag? options = null) - { - IJSObjectReference helper = await jSRuntime.GetHelperAsync(); - object?[]? jsBlobParts = blobParts?.Select(blobPart => blobPart.Part switch - { - byte[] part => part, - Blob part => part.JSReference, - _ => blobPart.Part - }) - .ToArray(); - IJSObjectReference jSInstance = await helper.InvokeAsync("constructBlob", jsBlobParts, options); - return new Blob(jSRuntime, jSInstance); - } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// The parts that will make the new . + /// Options for constructing the new Blob which includes MIME type and line endings settings. + /// + public static async Task CreateAsync(IJSRuntime jSRuntime, IList? blobParts = null, BlobPropertyBag? options = null) + { + IJSObjectReference helper = await jSRuntime.GetHelperAsync(); + object?[]? jsBlobParts = blobParts?.Select(blobPart => blobPart.Part switch + { + byte[] part => part, + Blob part => part.JSReference, + _ => blobPart.Part + }) + .ToArray(); + IJSObjectReference jSInstance = await helper.InvokeAsync("constructBlob", jsBlobParts, options); + return new Blob(jSRuntime, jSInstance); + } - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - internal Blob(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + internal Blob(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } - /// - /// The size of this blob. - /// - /// A representing the size of the blob in bytes. - public async Task GetSizeAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "size"); - } + /// + /// The size of this blob. + /// + /// A representing the size of the blob in bytes. + public async Task GetSizeAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "size"); + } - /// - /// The media type of this blob. This is either a parseable MIME type or an empty string. - /// - /// The MIME type of this blob. - public async Task GetTypeAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "type"); - } + /// + /// The media type of this blob. This is either a parseable MIME type or an empty string. + /// + /// The MIME type of this blob. + public async Task GetTypeAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "type"); + } - /// - /// Gets some range of the content of a as a new . - /// - /// The start index of the range. If or negative then 0 is assumed. - /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. - /// An optional MIME type of the new . If then the MIME type of the original is used. - /// A new . - public async Task SliceAsync(long? start = null, long? end = null, string? contentType = null) - { - start ??= 0; - end ??= (long)await GetSizeAsync(); - IJSObjectReference jSInstance = await JSReference.InvokeAsync("slice", start, end, contentType); - return new Blob(jSRuntime, jSInstance); - } + /// + /// Gets some range of the content of a as a new . + /// + /// The start index of the range. If or negative then 0 is assumed. + /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. + /// An optional MIME type of the new . If then the MIME type of the original is used. + /// A new . + public async Task SliceAsync(long? start = null, long? end = null, string? contentType = null) + { + start ??= 0; + end ??= (long)await GetSizeAsync(); + IJSObjectReference jSInstance = await JSReference.InvokeAsync("slice", start, end, contentType); + return new Blob(jSRuntime, jSInstance); + } - /// - /// Creates a new from the . - /// - /// A new wrapper for a - public async Task StreamAsync() - { - IJSObjectReference jSInstance = await JSReference.InvokeAsync("stream"); - return await ReadableStream.CreateAsync(jSRuntime, jSInstance); - } + /// + /// Creates a new from the . + /// + /// A new wrapper for a + public async Task StreamAsync() + { + IJSObjectReference jSInstance = await JSReference.InvokeAsync("stream"); + return await ReadableStream.CreateAsync(jSRuntime, jSInstance); + } - /// - /// The content of the blob as a string. - /// - /// The content of the file in UTF-8 format. - public async Task TextAsync() - { - return await JSReference.InvokeAsync("text"); - } + /// + /// The content of the blob as a string. + /// + /// The content of the file in UTF-8 format. + public async Task TextAsync() + { + return await JSReference.InvokeAsync("text"); + } - /// - /// The content of the blob as a byte array. - /// - /// All bytes in the blob. - public async Task ArrayBufferAsync() - { - IJSObjectReference jSInstance = await JSReference.InvokeAsync("arrayBuffer"); - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("arrayBuffer", jSInstance); + /// + /// The content of the blob as a byte array. + /// + /// All bytes in the blob. + public async Task ArrayBufferAsync() + { + IJSObjectReference jSInstance = await JSReference.InvokeAsync("arrayBuffer"); + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("arrayBuffer", jSInstance); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Converters/DateTimeConverter.cs b/src/KristofferStrube.Blazor.FileAPI/Converters/DateTimeConverter.cs index c4dbe7f..20f6161 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Converters/DateTimeConverter.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Converters/DateTimeConverter.cs @@ -1,21 +1,22 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -internal class DateTimeConverter : JsonConverter +namespace KristofferStrube.Blazor.FileAPI { - public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal class DateTimeConverter : JsonConverter { - if (reader.TryGetUInt64(out ulong jsonValue)) + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - return DateTime.UnixEpoch.AddMilliseconds(jsonValue); + if (reader.TryGetUInt64(out ulong jsonValue)) + { + return DateTime.UnixEpoch.AddMilliseconds(jsonValue); + } + throw new JsonException($"string {reader.GetString()} could not be parsed as a long."); } - throw new JsonException($"string {reader.GetString()} could not be parsed as a long."); - } - public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) - { - writer.WriteNumberValue(value.Subtract(DateTime.UnixEpoch).TotalMilliseconds); + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteNumberValue(value.Subtract(DateTime.UnixEpoch).TotalMilliseconds); + } } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/Converters/EnumDescriptionConverter.cs b/src/KristofferStrube.Blazor.FileAPI/Converters/EnumDescriptionConverter.cs index d12dfb1..56ef799 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Converters/EnumDescriptionConverter.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Converters/EnumDescriptionConverter.cs @@ -3,43 +3,44 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - +namespace KristofferStrube.Blazor.FileAPI +{ #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. #pragma warning disable CS8603 // Possible null reference return. #pragma warning disable CS8604 // Possible null reference argument. #pragma warning disable CS8602 // Dereference of a possibly null reference. -internal class EnumDescriptionConverter : JsonConverter where T : IComparable, IFormattable, IConvertible -{ - public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal class EnumDescriptionConverter : JsonConverter where T : IComparable, IFormattable, IConvertible { - string jsonValue = reader.GetString(); - - foreach (FieldInfo? fi in typeToConvert.GetFields()) + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - DescriptionAttribute description = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute), false); + string jsonValue = reader.GetString(); - if (description != null) + foreach (FieldInfo? fi in typeToConvert.GetFields()) { - if (description.Description == jsonValue) + DescriptionAttribute description = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute), false); + + if (description != null) { - return (T)fi.GetValue(null); + if (description.Description == jsonValue) + { + return (T)fi.GetValue(null); + } } } + throw new JsonException($"string {jsonValue} was not found as a description in the enum {typeToConvert}"); } - throw new JsonException($"string {jsonValue} was not found as a description in the enum {typeToConvert}"); - } - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) - { - FieldInfo fi = value.GetType().GetField(value.ToString()); + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + FieldInfo fi = value.GetType().GetField(value.ToString()); - DescriptionAttribute description = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute), false); + DescriptionAttribute description = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute), false); - writer.WriteStringValue(description.Description); + writer.WriteStringValue(description.Description); + } } -} #pragma warning restore CS8602 // Dereference of a possibly null reference. #pragma warning restore CS8604 // Possible null reference argument. #pragma warning restore CS8603 // Possible null reference return. -#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. \ No newline at end of file +#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. +} \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/Enums/EndingType.cs b/src/KristofferStrube.Blazor.FileAPI/Enums/EndingType.cs index 52e821c..3cd3144 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Enums/EndingType.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Enums/EndingType.cs @@ -1,16 +1,17 @@ using System.ComponentModel; using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// EndingType browser specs -/// -[JsonConverter(typeof(EnumDescriptionConverter))] -public enum EndingType +namespace KristofferStrube.Blazor.FileAPI { - [Description("transparent")] - Transparent, - [Description("native")] - Native, + /// + /// EndingType browser specs + /// + [JsonConverter(typeof(EnumDescriptionConverter))] + public enum EndingType + { + [Description("transparent")] + Transparent, + [Description("native")] + Native, + } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs b/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs index 08df30e..988d098 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Extensions/IJSRuntimeExtensions.cs @@ -1,20 +1,21 @@ using KristofferStrube.Blazor.FileAPI.Options; using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -internal static class IJSRuntimeExtensions +namespace KristofferStrube.Blazor.FileAPI { - internal static async Task GetHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) - { - options ??= FileApiOptions.DefaultInstance; - return await jSRuntime.InvokeAsync( - "import", options.FullScriptPath); - } - internal static async Task GetInProcessHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) + internal static class IJSRuntimeExtensions { - options ??= FileApiOptions.DefaultInstance; - return await jSRuntime.InvokeAsync( - "import", options.FullScriptPath); + internal static async Task GetHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) + { + options ??= FileApiOptions.DefaultInstance; + return await jSRuntime.InvokeAsync( + "import", options.FullScriptPath); + } + internal static async Task GetInProcessHelperAsync(this IJSRuntime jSRuntime, FileApiOptions? options = null) + { + options ??= FileApiOptions.DefaultInstance; + return await jSRuntime.InvokeAsync( + "import", options.FullScriptPath); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs b/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs index 1a9edb0..bd142a4 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Extensions/IServiceCollectionExtensions.cs @@ -2,27 +2,28 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -public static class IServiceCollectionExtensions +namespace KristofferStrube.Blazor.FileAPI { - public static IServiceCollection AddURLService(this IServiceCollection serviceCollection, Action? configure) + public static class IServiceCollectionExtensions { - serviceCollection.ConfigureFaOptions(configure); - return serviceCollection.AddScoped(); - } + public static IServiceCollection AddURLService(this IServiceCollection serviceCollection, Action? configure) + { + serviceCollection.ConfigureFaOptions(configure); + return serviceCollection.AddScoped(); + } - public static IServiceCollection AddURLServiceInProcess(this IServiceCollection serviceCollection, Action? configure) - { - serviceCollection.ConfigureFaOptions(configure); - return serviceCollection.AddScoped(sp => new URLServiceInProcess((IJSInProcessRuntime)sp.GetRequiredService())); - } + public static IServiceCollection AddURLServiceInProcess(this IServiceCollection serviceCollection, Action? configure) + { + serviceCollection.ConfigureFaOptions(configure); + return serviceCollection.AddScoped(sp => new URLServiceInProcess((IJSInProcessRuntime)sp.GetRequiredService())); + } - private static void ConfigureFaOptions(this IServiceCollection services, Action? configure) - { - if (configure is null) return; + private static void ConfigureFaOptions(this IServiceCollection services, Action? configure) + { + if (configure is null) return; - services.Configure(configure); - configure(FileApiOptions.DefaultInstance); + services.Configure(configure); + configure(FileApiOptions.DefaultInstance); + } } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/File.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/File.InProcess.cs index 07fcef9..ae7a201 100644 --- a/src/KristofferStrube.Blazor.FileAPI/File.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/File.InProcess.cs @@ -1,108 +1,109 @@ using KristofferStrube.Blazor.Streams; using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// File browser specs -/// -public class FileInProcess : File +namespace KristofferStrube.Blazor.FileAPI { - public new IJSInProcessObjectReference JSReference; - protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance for a given JS Instance of a . + /// File browser specs /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) + public class FileInProcess : File { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - return new FileInProcess(jSRuntime, inProcessHelper, jSReference); - } + public new IJSInProcessObjectReference JSReference; + protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// The bits that will make the new . - /// The name of the new file. - /// Options for constructing the new Blob which includes MIME type, line endings, and last modified date. - /// - public static new async Task CreateAsync(IJSRuntime jSRuntime, IList fileBits, string fileName, FilePropertyBag? options = null) - { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - object?[]? jsFileBits = fileBits.Select(blobPart => blobPart.Part switch - { - byte[] part => part, - Blob part => part.JSReference, - _ => blobPart.Part - }) - .ToArray(); - IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructFile", jsFileBits, fileName, options); - return new FileInProcess(jSRuntime, inProcessHelper, jSInstance); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + return new FileInProcess(jSRuntime, inProcessHelper, jSReference); + } - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// An in process helper instance. - /// A JS reference to an existing . - internal FileInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) - { - this.inProcessHelper = inProcessHelper; - JSReference = jSReference; - } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// The bits that will make the new . + /// The name of the new file. + /// Options for constructing the new Blob which includes MIME type, line endings, and last modified date. + /// + public static new async Task CreateAsync(IJSRuntime jSRuntime, IList fileBits, string fileName, FilePropertyBag? options = null) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + object?[]? jsFileBits = fileBits.Select(blobPart => blobPart.Part switch + { + byte[] part => part, + Blob part => part.JSReference, + _ => blobPart.Part + }) + .ToArray(); + IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructFile", jsFileBits, fileName, options); + return new FileInProcess(jSRuntime, inProcessHelper, jSInstance); + } - /// - /// Creates a new from the . - /// - /// A new wrapper for a - public new async Task StreamAsync() - { - IJSInProcessObjectReference jSInstance = JSReference.Invoke("stream"); - return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// An in process helper instance. + /// A JS reference to an existing . + internal FileInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) + { + this.inProcessHelper = inProcessHelper; + JSReference = jSReference; + } - /// - /// The size of this blob. - /// - /// A representing the size of the blob in bytes. - public ulong Size => inProcessHelper.Invoke("getAttribute", JSReference, "size"); + /// + /// Creates a new from the . + /// + /// A new wrapper for a + public new async Task StreamAsync() + { + IJSInProcessObjectReference jSInstance = JSReference.Invoke("stream"); + return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance); + } - /// - /// The media type of this blob. This is either a parseable MIME type or an empty string. - /// - /// The MIME type of this blob. - public string Type => inProcessHelper.Invoke("getAttribute", JSReference, "type"); + /// + /// The size of this blob. + /// + /// A representing the size of the blob in bytes. + public ulong Size => inProcessHelper.Invoke("getAttribute", JSReference, "size"); - /// - /// Gets some range of the content of a as a new . - /// - /// The start index of the range. If or negative then 0 is assumed. - /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. - /// An optional MIME type of the new . If then the MIME type of the original is used. - /// A new . - public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null) - { - start ??= 0; - end ??= (long)Size; - IJSInProcessObjectReference jSInstance = JSReference.Invoke("slice", start, end, contentType); - return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); - } + /// + /// The media type of this blob. This is either a parseable MIME type or an empty string. + /// + /// The MIME type of this blob. + public string Type => inProcessHelper.Invoke("getAttribute", JSReference, "type"); - /// - /// The name of the file including file extension. - /// - /// The file name. - public string Name => inProcessHelper.Invoke("getAttribute", JSReference, "name"); + /// + /// Gets some range of the content of a as a new . + /// + /// The start index of the range. If or negative then 0 is assumed. + /// The start index of the range. If or larger than the size of the original then the size of the original is assumed. + /// An optional MIME type of the new . If then the MIME type of the original is used. + /// A new . + public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null) + { + start ??= 0; + end ??= (long)Size; + IJSInProcessObjectReference jSInstance = JSReference.Invoke("slice", start, end, contentType); + return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance); + } - /// - /// The time that the file was last modified. - /// - /// A new object representing when the file was last modified. - public DateTime LastModified => DateTime.UnixEpoch.AddMilliseconds(inProcessHelper.Invoke("getAttribute", JSReference, "lastModified")); + /// + /// The name of the file including file extension. + /// + /// The file name. + public string Name => inProcessHelper.Invoke("getAttribute", JSReference, "name"); + + /// + /// The time that the file was last modified. + /// + /// A new object representing when the file was last modified. + public DateTime LastModified => DateTime.UnixEpoch.AddMilliseconds(inProcessHelper.Invoke("getAttribute", JSReference, "lastModified")); + } } diff --git a/src/KristofferStrube.Blazor.FileAPI/File.cs b/src/KristofferStrube.Blazor.FileAPI/File.cs index 4b85da8..6016970 100644 --- a/src/KristofferStrube.Blazor.FileAPI/File.cs +++ b/src/KristofferStrube.Blazor.FileAPI/File.cs @@ -1,69 +1,70 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// File browser specs -/// -public class File : Blob +namespace KristofferStrube.Blazor.FileAPI { /// - /// Constructs a wrapper instance for a given JS Instance of a . + /// File browser specs /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static new File Create(IJSRuntime jSRuntime, IJSObjectReference jSReference) + public class File : Blob { - return new File(jSRuntime, jSReference); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static new File Create(IJSRuntime jSRuntime, IJSObjectReference jSReference) + { + return new File(jSRuntime, jSReference); + } - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// The bits that will make the new . - /// The name of the new file. - /// Options for constructing the new Blob which includes MIME type, line endings, and last modified date. - /// - public static async Task CreateAsync(IJSRuntime jSRuntime, IList fileBits, string fileName, FilePropertyBag? options = null) - { - IJSObjectReference helper = await jSRuntime.GetHelperAsync(); - object?[]? jsFileBits = fileBits.Select(blobPart => blobPart.Part switch - { - byte[] part => part, - Blob part => part.JSReference, - _ => blobPart.Part - }) - .ToArray(); - IJSObjectReference jSInstance = await helper.InvokeAsync("constructFile", jsFileBits, fileName, options); - return new File(jSRuntime, jSInstance); - } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// The bits that will make the new . + /// The name of the new file. + /// Options for constructing the new Blob which includes MIME type, line endings, and last modified date. + /// + public static async Task CreateAsync(IJSRuntime jSRuntime, IList fileBits, string fileName, FilePropertyBag? options = null) + { + IJSObjectReference helper = await jSRuntime.GetHelperAsync(); + object?[]? jsFileBits = fileBits.Select(blobPart => blobPart.Part switch + { + byte[] part => part, + Blob part => part.JSReference, + _ => blobPart.Part + }) + .ToArray(); + IJSObjectReference jSInstance = await helper.InvokeAsync("constructFile", jsFileBits, fileName, options); + return new File(jSRuntime, jSInstance); + } - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - internal File(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + internal File(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } - /// - /// The name of the file including file extension. - /// - /// The file name. - public async Task GetNameAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "name"); - } + /// + /// The name of the file including file extension. + /// + /// The file name. + public async Task GetNameAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "name"); + } - /// - /// The time that the file was last modified. - /// - /// A new object representing when the file was last modified. - public async Task GetLastModifiedAsync() - { - IJSObjectReference helper = await helperTask.Value; - return DateTime.UnixEpoch.AddMilliseconds(await helper.InvokeAsync("getAttribute", JSReference, "lastModified")); + /// + /// The time that the file was last modified. + /// + /// A new object representing when the file was last modified. + public async Task GetLastModifiedAsync() + { + IJSObjectReference helper = await helperTask.Value; + return DateTime.UnixEpoch.AddMilliseconds(await helper.InvokeAsync("getAttribute", JSReference, "lastModified")); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/FileReader.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/FileReader.InProcess.cs index 125c70f..b85b2d5 100644 --- a/src/KristofferStrube.Blazor.FileAPI/FileReader.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/FileReader.InProcess.cs @@ -1,232 +1,233 @@ using Microsoft.JSInterop; using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// FileReader browser specs -/// -public class FileReaderInProcess : FileReader +namespace KristofferStrube.Blazor.FileAPI { - public new IJSInProcessObjectReference JSReference; - protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) - { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - return new FileReaderInProcess(jSRuntime, inProcessHelper, jSReference); - } - - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// A wrapper instance for a . - public static new async Task CreateAsync(IJSRuntime jSRuntime) - { - IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); - IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructFileReader"); - FileReaderInProcess fileReaderInProcess = new FileReaderInProcess(jSRuntime, inProcessHelper, jSInstance); - await inProcessHelper.InvokeVoidAsync("registerEventHandlers", DotNetObjectReference.Create(fileReaderInProcess), jSInstance); - return fileReaderInProcess; - } - - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// An in process helper instance. - /// A JS reference to an existing . - internal FileReaderInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) - { - this.inProcessHelper = inProcessHelper; - JSReference = jSReference; - } - - /// - /// Starts a new read for some as an [] which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// - public void ReadAsArrayBuffer(Blob blob) - { - JSReference.InvokeVoid("readAsArrayBuffer", blob.JSReference); - } - - /// - /// Starts a new read for some as a binarily encoded which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// - public void ReadAsBinaryString(Blob blob) - { - JSReference.InvokeVoid("readAsBinaryString", blob.JSReference); - } - /// - /// Starts a new read for some as a which can be read from once the load has ended which can be checked by setting the action . + /// FileReader browser specs /// - /// The that should be read asynchronously. - /// An optional encoding for the text. The default is UTF-8. - /// - public void ReadAsText(Blob blob, string? encoding = null) + public class FileReaderInProcess : FileReader { - JSReference.InvokeVoid("readAsText", blob.JSReference, encoding); - } - - /// - /// Starts a new read for some as a base64 encoded Data URL which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// - public void ReadAsDataURL(Blob blob) - { - JSReference.InvokeVoid("readAsDataURL", blob.JSReference); - } - - /// - /// Terminates the load if the is else it sets the result to . - /// - /// The read that should be terminated. - /// - public void Abort(Blob blob) - { - JSReference.InvokeVoid("abort", blob.JSReference); - } - - /// - /// Gets the state of the . - /// - /// As a standard either , or - public ushort ReadyState => inProcessHelper.Invoke("getAttribute", JSReference, "readyState"); - - /// - /// Checks whether the result is a either a or a byte array. - /// - /// Either the type of or type of []. - public Type? ResultType => inProcessHelper.Invoke("isArrayBuffer", JSReference) ? typeof(byte[]) : typeof(string); - - /// - /// Gets the result of the read a . - /// - /// A representing the read. If there was no result from the read or if the read has not ended yet then it will be . - public string? ResultAsString => inProcessHelper.Invoke("getAttribute", JSReference, "result"); - - /// - /// Gets the result of the read a []. - /// - /// A [] representing the read. If there was no result from the read or if the read has not ended yet then it will be . - public byte[]? ResultAsByteArray => inProcessHelper.Invoke("arrayBuffer", inProcessHelper.Invoke("getAttribute", JSReference, "result")); - - /// - /// Gets the error object reference which will be if no error occured. - /// - /// A nullable IJSObjectReference because it was out of scope to wrap the Exception API. - public IJSObjectReference? Error => inProcessHelper.Invoke("getAttribute", JSReference, "error"); - - /// - /// Invoked when a load starts. - /// - public new Action? OnLoadStart { get; set; } - - /// - /// Invoked when the progress of a load changes which includes when it ends. - /// - [JsonIgnore] - public new Action? OnProgress { get; set; } - - /// - /// Invoked when a load ends successfully. - /// - [JsonIgnore] - public new Action? OnLoad { get; set; } - - /// - /// Invoked when a load is aborted. - /// - [JsonIgnore] - public new Action? OnAbort { get; set; } - - /// - /// Invoked when a load fails due to an error. - /// - [JsonIgnore] - public new Action? OnError { get; set; } + public new IJSInProcessObjectReference JSReference; + protected readonly IJSInProcessObjectReference inProcessHelper; + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static async Task CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + return new FileReaderInProcess(jSRuntime, inProcessHelper, jSReference); + } - /// - /// Invoked when a load finishes successfully or not. - /// - [JsonIgnore] - public new Action? OnLoadEnd { get; set; } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// A wrapper instance for a . + public static new async Task CreateAsync(IJSRuntime jSRuntime) + { + IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync(); + IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync("constructFileReader"); + FileReaderInProcess fileReaderInProcess = new FileReaderInProcess(jSRuntime, inProcessHelper, jSInstance); + await inProcessHelper.InvokeVoidAsync("registerEventHandlers", DotNetObjectReference.Create(fileReaderInProcess), jSInstance); + return fileReaderInProcess; + } - [JSInvokable] - public void InvokeOnLoadStart(IJSInProcessObjectReference jsProgressEvent) - { - if (OnLoadStart is null) + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// An in process helper instance. + /// A JS reference to an existing . + internal FileReaderInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) { - return; + this.inProcessHelper = inProcessHelper; + JSReference = jSReference; } - OnLoadStart.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); - } + /// + /// Starts a new read for some as an [] which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public void ReadAsArrayBuffer(Blob blob) + { + JSReference.InvokeVoid("readAsArrayBuffer", blob.JSReference); + } - [JSInvokable] - public void InvokeOnProgress(IJSInProcessObjectReference jsProgressEvent) - { - if (OnProgress is null) + /// + /// Starts a new read for some as a binarily encoded which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public void ReadAsBinaryString(Blob blob) { - return; + JSReference.InvokeVoid("readAsBinaryString", blob.JSReference); } - OnProgress.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); - } + /// + /// Starts a new read for some as a which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// An optional encoding for the text. The default is UTF-8. + /// + public void ReadAsText(Blob blob, string? encoding = null) + { + JSReference.InvokeVoid("readAsText", blob.JSReference, encoding); + } - [JSInvokable] - public void InvokeOnLoad(IJSInProcessObjectReference jsProgressEvent) - { - if (OnLoad is null) + /// + /// Starts a new read for some as a base64 encoded Data URL which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public void ReadAsDataURL(Blob blob) { - return; + JSReference.InvokeVoid("readAsDataURL", blob.JSReference); } - OnLoad.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); - } + /// + /// Terminates the load if the is else it sets the result to . + /// + /// The read that should be terminated. + /// + public void Abort(Blob blob) + { + JSReference.InvokeVoid("abort", blob.JSReference); + } - [JSInvokable] - public void InvokeOnAbort(IJSInProcessObjectReference jsProgressEvent) - { - if (OnAbort is null) + /// + /// Gets the state of the . + /// + /// As a standard either , or + public ushort ReadyState => inProcessHelper.Invoke("getAttribute", JSReference, "readyState"); + + /// + /// Checks whether the result is a either a or a byte array. + /// + /// Either the type of or type of []. + public Type? ResultType => inProcessHelper.Invoke("isArrayBuffer", JSReference) ? typeof(byte[]) : typeof(string); + + /// + /// Gets the result of the read a . + /// + /// A representing the read. If there was no result from the read or if the read has not ended yet then it will be . + public string? ResultAsString => inProcessHelper.Invoke("getAttribute", JSReference, "result"); + + /// + /// Gets the result of the read a []. + /// + /// A [] representing the read. If there was no result from the read or if the read has not ended yet then it will be . + public byte[]? ResultAsByteArray => inProcessHelper.Invoke("arrayBuffer", inProcessHelper.Invoke("getAttribute", JSReference, "result")); + + /// + /// Gets the error object reference which will be if no error occured. + /// + /// A nullable IJSObjectReference because it was out of scope to wrap the Exception API. + public IJSObjectReference? Error => inProcessHelper.Invoke("getAttribute", JSReference, "error"); + + /// + /// Invoked when a load starts. + /// + public new Action? OnLoadStart { get; set; } + + /// + /// Invoked when the progress of a load changes which includes when it ends. + /// + [JsonIgnore] + public new Action? OnProgress { get; set; } + + /// + /// Invoked when a load ends successfully. + /// + [JsonIgnore] + public new Action? OnLoad { get; set; } + + /// + /// Invoked when a load is aborted. + /// + [JsonIgnore] + public new Action? OnAbort { get; set; } + + /// + /// Invoked when a load fails due to an error. + /// + [JsonIgnore] + public new Action? OnError { get; set; } + + /// + /// Invoked when a load finishes successfully or not. + /// + [JsonIgnore] + public new Action? OnLoadEnd { get; set; } + + [JSInvokable] + public void InvokeOnLoadStart(IJSInProcessObjectReference jsProgressEvent) { - return; + if (OnLoadStart is null) + { + return; + } + + OnLoadStart.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); } - OnAbort.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); - } + [JSInvokable] + public void InvokeOnProgress(IJSInProcessObjectReference jsProgressEvent) + { + if (OnProgress is null) + { + return; + } - [JSInvokable] - public void InvokeOnError(IJSInProcessObjectReference jsProgressEvent) - { - if (OnError is null) + OnProgress.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); + } + + [JSInvokable] + public void InvokeOnLoad(IJSInProcessObjectReference jsProgressEvent) { - return; + if (OnLoad is null) + { + return; + } + + OnLoad.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); } - OnError.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); - } + [JSInvokable] + public void InvokeOnAbort(IJSInProcessObjectReference jsProgressEvent) + { + if (OnAbort is null) + { + return; + } - [JSInvokable] - public void InvokeOnLoadEnd(IJSInProcessObjectReference jsProgressEvent) - { - if (OnLoadEnd is null) + OnAbort.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); + } + + [JSInvokable] + public void InvokeOnError(IJSInProcessObjectReference jsProgressEvent) { - return; + if (OnError is null) + { + return; + } + + OnError.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); } - OnLoadEnd.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); + [JSInvokable] + public void InvokeOnLoadEnd(IJSInProcessObjectReference jsProgressEvent) + { + if (OnLoadEnd is null) + { + return; + } + + OnLoadEnd.Invoke(new ProgressEventInProcess(jSRuntime, inProcessHelper, jsProgressEvent)); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/FileReader.cs b/src/KristofferStrube.Blazor.FileAPI/FileReader.cs index c638e5f..c06c507 100644 --- a/src/KristofferStrube.Blazor.FileAPI/FileReader.cs +++ b/src/KristofferStrube.Blazor.FileAPI/FileReader.cs @@ -1,254 +1,255 @@ using Microsoft.JSInterop; using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// FileReader browser specs -/// -public class FileReader : BaseJSWrapper +namespace KristofferStrube.Blazor.FileAPI { /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - /// A wrapper instance for a . - public static async Task CreateAsync(IJSRuntime jSRuntime, IJSObjectReference jSReference) - { - IJSObjectReference helper = await jSRuntime.GetHelperAsync(); - FileReader fileReader = new(jSRuntime, jSReference); - await helper.InvokeVoidAsync("registerEventHandlersAsync", DotNetObjectReference.Create(fileReader), jSReference); - return fileReader; - } - - /// - /// Constructs a wrapper instance using the standard constructor. - /// - /// An instance. - /// A wrapper instance for a . - public static async Task CreateAsync(IJSRuntime jSRuntime) - { - IJSObjectReference helper = await jSRuntime.GetHelperAsync(); - IJSObjectReference jSInstance = await helper.InvokeAsync("constructFileReader"); - FileReader fileReader = new(jSRuntime, jSInstance); - await helper.InvokeVoidAsync("registerEventHandlersAsync", DotNetObjectReference.Create(fileReader), jSInstance); - return fileReader; - } - - /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - internal FileReader(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } - - /// - /// Starts a new read for some as an [] which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// - public async Task ReadAsArrayBufferAsync(Blob blob) - { - await JSReference.InvokeVoidAsync("readAsArrayBuffer", blob.JSReference); - } - - /// - /// Starts a new read for some as a binarily encoded which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// - public async Task ReadAsBinaryStringAsync(Blob blob) - { - await JSReference.InvokeVoidAsync("readAsBinaryString", blob.JSReference); - } - - /// - /// Starts a new read for some as a which can be read from once the load has ended which can be checked by setting the action . - /// - /// The that should be read asynchronously. - /// An optional encoding for the text. The default is UTF-8. - /// - public async Task ReadAsTextAsync(Blob blob, string? encoding = null) - { - await JSReference.InvokeVoidAsync("readAsText", blob.JSReference, encoding); - } - - /// - /// Starts a new read for some as a base64 encoded Data URL which can be read from once the load has ended which can be checked by setting the action . + /// FileReader browser specs /// - /// The that should be read asynchronously. - /// - public async Task ReadAsDataURLAsync(Blob blob) + public class FileReader : BaseJSWrapper { - await JSReference.InvokeVoidAsync("readAsDataURL", blob.JSReference); - } - - /// - /// Terminates the load if the is else it sets the result to . - /// - /// The read that should be terminated. - /// - public async Task AbortAsync(Blob blob) - { - await JSReference.InvokeVoidAsync("abort", blob.JSReference); - } - - public const ushort EMPTY = 0; - public const ushort LOADING = 1; - public const ushort DONE = 2; - - /// - /// Gets the state of the . - /// - /// As a standard either , or - public async Task GetReadyStateAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "readyState"); - } - - /// - /// Checks whether the result is a either a or a byte array. - /// - /// Either the type of or type of []. - public async Task GetResultTypeAsync() - { - IJSObjectReference helper = await helperTask.Value; - bool isArrayBuffer = await helper.InvokeAsync("isArrayBuffer", JSReference); - return isArrayBuffer ? typeof(byte[]) : typeof(string); - } - - /// - /// Gets the result of the read a . - /// - /// A representing the read. If there was no result from the read or if the read has not ended yet then it will be . - public async Task GetResultAsStringAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "result"); - } - - /// - /// Gets the result of the read a []. - /// - /// A [] representing the read. If there was no result from the read or if the read has not ended yet then it will be . - public async Task GetResultAsByteArrayAsync() - { - IJSObjectReference helper = await helperTask.Value; - IJSObjectReference jSResult = await helper.InvokeAsync("getAttribute", JSReference, "result"); - return await helper.InvokeAsync("arrayBuffer", jSResult); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + /// A wrapper instance for a . + public static async Task CreateAsync(IJSRuntime jSRuntime, IJSObjectReference jSReference) + { + IJSObjectReference helper = await jSRuntime.GetHelperAsync(); + FileReader fileReader = new(jSRuntime, jSReference); + await helper.InvokeVoidAsync("registerEventHandlersAsync", DotNetObjectReference.Create(fileReader), jSReference); + return fileReader; + } - /// - /// Gets the error object reference which will be if no error occured. - /// - /// A nullable IJSObjectReference because it was out of scope to wrap the Exception API. - public async Task GetErrorAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "error"); - } + /// + /// Constructs a wrapper instance using the standard constructor. + /// + /// An instance. + /// A wrapper instance for a . + public static async Task CreateAsync(IJSRuntime jSRuntime) + { + IJSObjectReference helper = await jSRuntime.GetHelperAsync(); + IJSObjectReference jSInstance = await helper.InvokeAsync("constructFileReader"); + FileReader fileReader = new(jSRuntime, jSInstance); + await helper.InvokeVoidAsync("registerEventHandlersAsync", DotNetObjectReference.Create(fileReader), jSInstance); + return fileReader; + } - /// - /// Invoked when a load starts. - /// - [JsonIgnore] - public Func? OnLoadStart { get; set; } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + internal FileReader(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } + + /// + /// Starts a new read for some as an [] which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public async Task ReadAsArrayBufferAsync(Blob blob) + { + await JSReference.InvokeVoidAsync("readAsArrayBuffer", blob.JSReference); + } - /// - /// Invoked when the progress of a load changes which includes when it ends. - /// - [JsonIgnore] - public Func? OnProgress { get; set; } + /// + /// Starts a new read for some as a binarily encoded which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public async Task ReadAsBinaryStringAsync(Blob blob) + { + await JSReference.InvokeVoidAsync("readAsBinaryString", blob.JSReference); + } - /// - /// Invoked when a load ends successfully. - /// - [JsonIgnore] - public Func? OnLoad { get; set; } + /// + /// Starts a new read for some as a which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// An optional encoding for the text. The default is UTF-8. + /// + public async Task ReadAsTextAsync(Blob blob, string? encoding = null) + { + await JSReference.InvokeVoidAsync("readAsText", blob.JSReference, encoding); + } - /// - /// Invoked when a load is aborted. - /// - [JsonIgnore] - public Func? OnAbort { get; set; } + /// + /// Starts a new read for some as a base64 encoded Data URL which can be read from once the load has ended which can be checked by setting the action . + /// + /// The that should be read asynchronously. + /// + public async Task ReadAsDataURLAsync(Blob blob) + { + await JSReference.InvokeVoidAsync("readAsDataURL", blob.JSReference); + } - /// - /// Invoked when a load fails due to an error. - /// - [JsonIgnore] - public Func? OnError { get; set; } + /// + /// Terminates the load if the is else it sets the result to . + /// + /// The read that should be terminated. + /// + public async Task AbortAsync(Blob blob) + { + await JSReference.InvokeVoidAsync("abort", blob.JSReference); + } - /// - /// Invoked when a load finishes successfully or not. - /// - [JsonIgnore] - public Func? OnLoadEnd { get; set; } + public const ushort EMPTY = 0; + public const ushort LOADING = 1; + public const ushort DONE = 2; - [JSInvokable] - public async Task InvokeOnLoadStartAsync(IJSObjectReference jsProgressEvent) - { - if (OnLoadStart is null) + /// + /// Gets the state of the . + /// + /// As a standard either , or + public async Task GetReadyStateAsync() { - return; + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "readyState"); } - await OnLoadStart.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); - } - - [JSInvokable] - public async Task InvokeOnProgressAsync(IJSObjectReference jsProgressEvent) - { - if (OnProgress is null) + /// + /// Checks whether the result is a either a or a byte array. + /// + /// Either the type of or type of []. + public async Task GetResultTypeAsync() { - return; + IJSObjectReference helper = await helperTask.Value; + bool isArrayBuffer = await helper.InvokeAsync("isArrayBuffer", JSReference); + return isArrayBuffer ? typeof(byte[]) : typeof(string); } - await OnProgress.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); - } + /// + /// Gets the result of the read a . + /// + /// A representing the read. If there was no result from the read or if the read has not ended yet then it will be . + public async Task GetResultAsStringAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "result"); + } - [JSInvokable] - public async Task InvokeOnLoadAsync(IJSObjectReference jsProgressEvent) - { - if (OnLoad is null) + /// + /// Gets the result of the read a []. + /// + /// A [] representing the read. If there was no result from the read or if the read has not ended yet then it will be . + public async Task GetResultAsByteArrayAsync() { - return; + IJSObjectReference helper = await helperTask.Value; + IJSObjectReference jSResult = await helper.InvokeAsync("getAttribute", JSReference, "result"); + return await helper.InvokeAsync("arrayBuffer", jSResult); } - await OnLoad.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); - } + /// + /// Gets the error object reference which will be if no error occured. + /// + /// A nullable IJSObjectReference because it was out of scope to wrap the Exception API. + public async Task GetErrorAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "error"); + } - [JSInvokable] - public async Task InvokeOnAbortAsync(IJSObjectReference jsProgressEvent) - { - if (OnAbort is null) + /// + /// Invoked when a load starts. + /// + [JsonIgnore] + public Func? OnLoadStart { get; set; } + + /// + /// Invoked when the progress of a load changes which includes when it ends. + /// + [JsonIgnore] + public Func? OnProgress { get; set; } + + /// + /// Invoked when a load ends successfully. + /// + [JsonIgnore] + public Func? OnLoad { get; set; } + + /// + /// Invoked when a load is aborted. + /// + [JsonIgnore] + public Func? OnAbort { get; set; } + + /// + /// Invoked when a load fails due to an error. + /// + [JsonIgnore] + public Func? OnError { get; set; } + + /// + /// Invoked when a load finishes successfully or not. + /// + [JsonIgnore] + public Func? OnLoadEnd { get; set; } + + [JSInvokable] + public async Task InvokeOnLoadStartAsync(IJSObjectReference jsProgressEvent) { - return; + if (OnLoadStart is null) + { + return; + } + + await OnLoadStart.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); } - await OnAbort.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); - } + [JSInvokable] + public async Task InvokeOnProgressAsync(IJSObjectReference jsProgressEvent) + { + if (OnProgress is null) + { + return; + } - [JSInvokable] - public async Task InvokeOnErrorAsync(IJSObjectReference jsProgressEvent) - { - if (OnError is null) + await OnProgress.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); + } + + [JSInvokable] + public async Task InvokeOnLoadAsync(IJSObjectReference jsProgressEvent) { - return; + if (OnLoad is null) + { + return; + } + + await OnLoad.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); } - await OnError.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); - } + [JSInvokable] + public async Task InvokeOnAbortAsync(IJSObjectReference jsProgressEvent) + { + if (OnAbort is null) + { + return; + } - [JSInvokable] - public async Task InvokeOnLoadEndAsync(IJSObjectReference jsProgressEvent) - { - if (OnLoadEnd is null) + await OnAbort.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); + } + + [JSInvokable] + public async Task InvokeOnErrorAsync(IJSObjectReference jsProgressEvent) { - return; + if (OnError is null) + { + return; + } + + await OnError.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); } - await OnLoadEnd.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); + [JSInvokable] + public async Task InvokeOnLoadEndAsync(IJSObjectReference jsProgressEvent) + { + if (OnLoadEnd is null) + { + return; + } + + await OnLoadEnd.Invoke(new ProgressEvent(jSRuntime, jsProgressEvent)); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/IURLService.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/IURLService.InProcess.cs index e0b82bf..7eadb38 100644 --- a/src/KristofferStrube.Blazor.FileAPI/IURLService.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/IURLService.InProcess.cs @@ -1,7 +1,8 @@ -namespace KristofferStrube.Blazor.FileAPI; - -public interface IURLServiceInProcess : IURLService +namespace KristofferStrube.Blazor.FileAPI { - string CreateObjectURL(Blob obj); - void RevokeObjectURL(string url); + public interface IURLServiceInProcess : IURLService + { + string CreateObjectURL(Blob obj); + void RevokeObjectURL(string url); + } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/IURLService.cs b/src/KristofferStrube.Blazor.FileAPI/IURLService.cs index 8a9da3d..d63a62f 100644 --- a/src/KristofferStrube.Blazor.FileAPI/IURLService.cs +++ b/src/KristofferStrube.Blazor.FileAPI/IURLService.cs @@ -1,7 +1,8 @@ -namespace KristofferStrube.Blazor.FileAPI; - -public interface IURLService +namespace KristofferStrube.Blazor.FileAPI { - Task CreateObjectURLAsync(Blob obj); - Task RevokeObjectURLAsync(string url); + public interface IURLService + { + Task CreateObjectURLAsync(Blob obj); + Task RevokeObjectURLAsync(string url); + } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.csproj b/src/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.csproj index 498ceec..e783cef 100644 --- a/src/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.csproj +++ b/src/KristofferStrube.Blazor.FileAPI/KristofferStrube.Blazor.FileAPI.csproj @@ -35,8 +35,11 @@ - - + + + + + diff --git a/src/KristofferStrube.Blazor.FileAPI/Options/BlobPart.cs b/src/KristofferStrube.Blazor.FileAPI/Options/BlobPart.cs index f223bc8..fc883d8 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Options/BlobPart.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Options/BlobPart.cs @@ -1,43 +1,44 @@ -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// BlobPart browser specs -/// -public class BlobPart +namespace KristofferStrube.Blazor.FileAPI { - internal readonly object Part; - - internal BlobPart(object part) - { - Part = part; - } - [Obsolete("We added implicit converters from byte[] to BlobPart so you can parse it directly without using this constructor first.")] - public BlobPart(byte[] part) - { - Part = part; - } - [Obsolete("We added implicit converters from Blob to BlobPart so you can parse it directly without using this constructor first.")] - public BlobPart(Blob part) - { - Part = part; - } - [Obsolete("We added implicit converters from string to BlobPart so you can parse it directly without using this constructor first.")] - public BlobPart(string part) + /// + /// BlobPart browser specs + /// + public class BlobPart { - Part = part; - } + internal readonly object Part; + internal BlobPart(object part) + { + Part = part; + } + [Obsolete("We added implicit converters from byte[] to BlobPart so you can parse it directly without using this constructor first.")] + public BlobPart(byte[] part) + { + Part = part; + } + [Obsolete("We added implicit converters from Blob to BlobPart so you can parse it directly without using this constructor first.")] + public BlobPart(Blob part) + { + Part = part; + } + [Obsolete("We added implicit converters from string to BlobPart so you can parse it directly without using this constructor first.")] + public BlobPart(string part) + { + Part = part; + } - public static implicit operator BlobPart(byte[] part) - { - return new((object)part); - } - public static implicit operator BlobPart(Blob part) - { - return new((object)part); - } - public static implicit operator BlobPart(string part) - { - return new((object)part); + + public static implicit operator BlobPart(byte[] part) + { + return new((object)part); + } + public static implicit operator BlobPart(Blob part) + { + return new((object)part); + } + public static implicit operator BlobPart(string part) + { + return new((object)part); + } } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/Options/BlobPropertyBag.cs b/src/KristofferStrube.Blazor.FileAPI/Options/BlobPropertyBag.cs index af285ec..e8dc81d 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Options/BlobPropertyBag.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Options/BlobPropertyBag.cs @@ -1,21 +1,22 @@ using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// BlobPropertyBag browser specs -/// -public class BlobPropertyBag +namespace KristofferStrube.Blazor.FileAPI { /// - /// The MIME type of the new in lowercase. + /// BlobPropertyBag browser specs /// - [JsonPropertyName("type")] - public string Type { get; set; } = ""; + public class BlobPropertyBag + { + /// + /// The MIME type of the new in lowercase. + /// + [JsonPropertyName("type")] + public string Type { get; set; } = ""; - /// - /// The line endings for the new . - /// - [JsonPropertyName("endings")] - public EndingType Endings { get; set; } = EndingType.Transparent; + /// + /// The line endings for the new . + /// + [JsonPropertyName("endings")] + public EndingType Endings { get; set; } = EndingType.Transparent; + } } diff --git a/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs b/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs index e44196f..2ec1c40 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Options/FileApiOptions.cs @@ -1,18 +1,19 @@ using System.Reflection; -namespace KristofferStrube.Blazor.FileAPI.Options; - -public class FileApiOptions() +namespace KristofferStrube.Blazor.FileAPI.Options { - public const string DefaultBasePath = "./_content/"; - public static readonly string DefaultNamespace = Assembly.GetExecutingAssembly().GetName().Name ?? "KristofferStrube.Blazor.FileAPI"; - public static readonly string DefaultScriptPath = $"{DefaultNamespace}/{DefaultNamespace}.js"; + public class FileApiOptions() + { + public const string DefaultBasePath = "./_content/"; + public static readonly string DefaultNamespace = Assembly.GetExecutingAssembly().GetName().Name ?? "KristofferStrube.Blazor.FileAPI"; + public static readonly string DefaultScriptPath = $"{DefaultNamespace}/{DefaultNamespace}.js"; - public string BasePath { get; set; } = DefaultBasePath; - public string ScriptPath { get; set; } = DefaultScriptPath; + public string BasePath { get; set; } = DefaultBasePath; + public string ScriptPath { get; set; } = DefaultScriptPath; - public string FullScriptPath => Path.Combine(this.BasePath, this.ScriptPath); + public string FullScriptPath => Path.Combine(this.BasePath, this.ScriptPath); - internal static FileApiOptions DefaultInstance = new(); + internal static FileApiOptions DefaultInstance = new(); + } } \ No newline at end of file diff --git a/src/KristofferStrube.Blazor.FileAPI/Options/FilePropertyBag.cs b/src/KristofferStrube.Blazor.FileAPI/Options/FilePropertyBag.cs index 4b2ef4f..f9d98bb 100644 --- a/src/KristofferStrube.Blazor.FileAPI/Options/FilePropertyBag.cs +++ b/src/KristofferStrube.Blazor.FileAPI/Options/FilePropertyBag.cs @@ -1,16 +1,17 @@ using System.Text.Json.Serialization; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// FilePropertyBag browser specs -/// -public class FilePropertyBag : BlobPropertyBag +namespace KristofferStrube.Blazor.FileAPI { /// - /// When the new was last modified. + /// FilePropertyBag browser specs /// - [JsonPropertyName("lastModified")] - [JsonConverter(typeof(DateTimeConverter))] - public DateTime LastModified { get; set; } = DateTime.UtcNow; + public class FilePropertyBag : BlobPropertyBag + { + /// + /// When the new was last modified. + /// + [JsonPropertyName("lastModified")] + [JsonConverter(typeof(DateTimeConverter))] + public DateTime LastModified { get; set; } = DateTime.UtcNow; + } } diff --git a/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.InProcess.cs index 49c1eff..69a8571 100644 --- a/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.InProcess.cs @@ -1,42 +1,43 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// ProgressEvent browser specs -/// -public class ProgressEventInProcess : ProgressEvent +namespace KristofferStrube.Blazor.FileAPI { - public new IJSInProcessObjectReference JSReference; - protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Constructs a wrapper instance for a given JS Instance of a . + /// ProgressEvent browser specs /// - /// An instance. - /// An in process helper instance. - /// A JS reference to an existing . - internal ProgressEventInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) + public class ProgressEventInProcess : ProgressEvent { - this.inProcessHelper = inProcessHelper; - JSReference = jSReference; - } + public new IJSInProcessObjectReference JSReference; + protected readonly IJSInProcessObjectReference inProcessHelper; - /// - /// Indicates whether the total can be calculated. - /// - /// A indicating if the total length was computable. - public bool LengthComputable => inProcessHelper.Invoke("getAttribute", JSReference, "lengthComputable"); + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// An in process helper instance. + /// A JS reference to an existing . + internal ProgressEventInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference) + { + this.inProcessHelper = inProcessHelper; + JSReference = jSReference; + } - /// - /// The loaded number of bytes of the total. - /// - /// The length of the currently loaded part. - public ulong Loaded => inProcessHelper.Invoke("getAttribute", JSReference, "loaded"); + /// + /// Indicates whether the total can be calculated. + /// + /// A indicating if the total length was computable. + public bool LengthComputable => inProcessHelper.Invoke("getAttribute", JSReference, "lengthComputable"); - /// - /// The total number of bytes if it was computable else this is 0. - /// - /// The total length of the read. - public ulong Total => inProcessHelper.Invoke("getAttribute", JSReference, "total"); + /// + /// The loaded number of bytes of the total. + /// + /// The length of the currently loaded part. + public ulong Loaded => inProcessHelper.Invoke("getAttribute", JSReference, "loaded"); + + /// + /// The total number of bytes if it was computable else this is 0. + /// + /// The total length of the read. + public ulong Total => inProcessHelper.Invoke("getAttribute", JSReference, "total"); + } } diff --git a/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.cs b/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.cs index bb229dc..ff7b71a 100644 --- a/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.cs +++ b/src/KristofferStrube.Blazor.FileAPI/ProgressEvent.cs @@ -1,46 +1,47 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// ProgressEvent browser specs -/// -public class ProgressEvent : BaseJSWrapper +namespace KristofferStrube.Blazor.FileAPI { /// - /// Constructs a wrapper instance for a given JS Instance of a . - /// - /// An instance. - /// A JS reference to an existing . - internal ProgressEvent(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } - - /// - /// Indicates whether the total can be calculated. + /// ProgressEvent browser specs /// - /// A indicating if the total length was computable. - public async Task GetLengthComputableAsync() + public class ProgressEvent : BaseJSWrapper { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "lengthComputable"); - } + /// + /// Constructs a wrapper instance for a given JS Instance of a . + /// + /// An instance. + /// A JS reference to an existing . + internal ProgressEvent(IJSRuntime jSRuntime, IJSObjectReference jSReference) : base(jSRuntime, jSReference) { } - /// - /// The loaded number of bytes of the total. - /// - /// The length of the currently loaded part. - public async Task GetLoadedAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "loaded"); - } + /// + /// Indicates whether the total can be calculated. + /// + /// A indicating if the total length was computable. + public async Task GetLengthComputableAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "lengthComputable"); + } - /// - /// The total number of bytes if it was computable else this is 0. - /// - /// The total length of the read. - public async Task GetTotalAsync() - { - IJSObjectReference helper = await helperTask.Value; - return await helper.InvokeAsync("getAttribute", JSReference, "total"); + /// + /// The loaded number of bytes of the total. + /// + /// The length of the currently loaded part. + public async Task GetLoadedAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "loaded"); + } + + /// + /// The total number of bytes if it was computable else this is 0. + /// + /// The total length of the read. + public async Task GetTotalAsync() + { + IJSObjectReference helper = await helperTask.Value; + return await helper.InvokeAsync("getAttribute", JSReference, "total"); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/URLService.InProcess.cs b/src/KristofferStrube.Blazor.FileAPI/URLService.InProcess.cs index 718afcf..52eb2b9 100644 --- a/src/KristofferStrube.Blazor.FileAPI/URLService.InProcess.cs +++ b/src/KristofferStrube.Blazor.FileAPI/URLService.InProcess.cs @@ -1,39 +1,40 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// URL browser specs -/// -public class URLServiceInProcess : URLService, IURLServiceInProcess +namespace KristofferStrube.Blazor.FileAPI { - protected new readonly IJSInProcessRuntime jSRuntime; - /// - /// Constructs a that can be used to access the partial part of the URL interface defined in the FileAPI definition. + /// URL browser specs /// - /// - public URLServiceInProcess(IJSInProcessRuntime jSRuntime) : base(jSRuntime) + public class URLServiceInProcess : URLService, IURLServiceInProcess { - this.jSRuntime = jSRuntime; - } + protected new readonly IJSInProcessRuntime jSRuntime; - /// - /// Creates a new Blob URL and adds that to the current contexts Blob URL store. - /// - /// The that you wish to create a URL for. - /// a Blob Url which can be used as a source in different media like image, sound, iframe sources. - public string CreateObjectURL(Blob obj) - { - return jSRuntime.Invoke("URL.createObjectURL", obj.JSReference); - } + /// + /// Constructs a that can be used to access the partial part of the URL interface defined in the FileAPI definition. + /// + /// + public URLServiceInProcess(IJSInProcessRuntime jSRuntime) : base(jSRuntime) + { + this.jSRuntime = jSRuntime; + } - /// - /// Removes a specific URL from the current contexts Blob URL store. - /// - /// The URL that is to be removed. - public void RevokeObjectURL(string url) - { - jSRuntime.InvokeVoid("URL.revokeObjectURL", url); + /// + /// Creates a new Blob URL and adds that to the current contexts Blob URL store. + /// + /// The that you wish to create a URL for. + /// a Blob Url which can be used as a source in different media like image, sound, iframe sources. + public string CreateObjectURL(Blob obj) + { + return jSRuntime.Invoke("URL.createObjectURL", obj.JSReference); + } + + /// + /// Removes a specific URL from the current contexts Blob URL store. + /// + /// The URL that is to be removed. + public void RevokeObjectURL(string url) + { + jSRuntime.InvokeVoid("URL.revokeObjectURL", url); + } } } diff --git a/src/KristofferStrube.Blazor.FileAPI/URLService.cs b/src/KristofferStrube.Blazor.FileAPI/URLService.cs index bbf4a38..c885a03 100644 --- a/src/KristofferStrube.Blazor.FileAPI/URLService.cs +++ b/src/KristofferStrube.Blazor.FileAPI/URLService.cs @@ -1,39 +1,40 @@ using Microsoft.JSInterop; -namespace KristofferStrube.Blazor.FileAPI; - -/// -/// URL browser specs -/// -public class URLService : IURLService +namespace KristofferStrube.Blazor.FileAPI { - protected readonly IJSRuntime jSRuntime; - /// - /// Constructs a that can be used to access the partial part of the URL interface defined in the FileAPI definition. + /// URL browser specs /// - /// - public URLService(IJSRuntime jSRuntime) + public class URLService : IURLService { - this.jSRuntime = jSRuntime; - } + protected readonly IJSRuntime jSRuntime; - /// - /// Creates a new Blob URL and adds that to the current contexts Blob URL store. - /// - /// The that you wish to create a URL for. - /// a Blob Url which can be used as a source in different media like image, sound, iframe sources. - public async Task CreateObjectURLAsync(Blob obj) - { - return await jSRuntime.InvokeAsync("URL.createObjectURL", obj.JSReference); - } + /// + /// Constructs a that can be used to access the partial part of the URL interface defined in the FileAPI definition. + /// + /// + public URLService(IJSRuntime jSRuntime) + { + this.jSRuntime = jSRuntime; + } - /// - /// Removes a specific URL from the current contexts Blob URL store. - /// - /// The URL that is to be removed. - public async Task RevokeObjectURLAsync(string url) - { - await jSRuntime.InvokeVoidAsync("URL.revokeObjectURL", url); + /// + /// Creates a new Blob URL and adds that to the current contexts Blob URL store. + /// + /// The that you wish to create a URL for. + /// a Blob Url which can be used as a source in different media like image, sound, iframe sources. + public async Task CreateObjectURLAsync(Blob obj) + { + return await jSRuntime.InvokeAsync("URL.createObjectURL", obj.JSReference); + } + + /// + /// Removes a specific URL from the current contexts Blob URL store. + /// + /// The URL that is to be removed. + public async Task RevokeObjectURLAsync(string url) + { + await jSRuntime.InvokeVoidAsync("URL.revokeObjectURL", url); + } } }