Skip to content

Javascript location customization #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions src/KristofferStrube.Blazor.FileAPI/BaseJSWrapper.cs
Original file line number Diff line number Diff line change
@@ -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<Task<IJSObjectReference>> helperTask;
protected readonly IJSRuntime jSRuntime;

/// <summary>
/// Constructs a wrapper instance for an equivalent JS instance.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="jSReference">A JS reference to an existing JS instance that should be wrapped.</param>
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<Task<IJSObjectReference>> helperTask;
protected readonly IJSRuntime jSRuntime;

public async ValueTask DisposeAsync()
{
if (helperTask.IsValueCreated)
/// <summary>
/// Constructs a wrapper instance for an equivalent JS instance.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="jSReference">A JS reference to an existing JS instance that should be wrapped.</param>
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);
}
}
161 changes: 81 additions & 80 deletions src/KristofferStrube.Blazor.FileAPI/Blob.InProcess.cs
Original file line number Diff line number Diff line change
@@ -1,95 +1,96 @@
using KristofferStrube.Blazor.Streams;
using Microsoft.JSInterop;

namespace KristofferStrube.Blazor.FileAPI;

/// <summary>
/// <see href="https://www.w3.org/TR/FileAPI/#blob-section">Blob browser specs</see>
/// </summary>
public class BlobInProcess : Blob
namespace KristofferStrube.Blazor.FileAPI
{
public new IJSInProcessObjectReference JSReference;
protected readonly IJSInProcessObjectReference inProcessHelper;

/// <summary>
/// Constructs a wrapper instance for a given JS Instance of a <see cref="Blob"/>.
/// <see href="https://www.w3.org/TR/FileAPI/#blob-section">Blob browser specs</see>
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="jSReference">A JS reference to an existing <see cref="Blob"/>.</param>
/// <returns>A wrapper instance for a <see cref="Blob"/>.</returns>
public static async Task<BlobInProcess> 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;

/// <summary>
/// Constructs a wrapper instance using the standard constructor.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="blobParts">The parts that will make the new <see cref="Blob"/>.</param>
/// <param name="options">Options for constructing the new Blob which includes MIME type and line endings settings.</param>
/// <returns></returns>
public static new async Task<BlobInProcess> CreateAsync(IJSRuntime jSRuntime, IList<BlobPart>? blobParts = null, BlobPropertyBag? options = null)
{
IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync();
object?[]? jsBlobParts = blobParts?.Select<BlobPart, object?>(blobPart => blobPart.Part switch
{
byte[] part => part,
Blob part => part.JSReference,
_ => blobPart.Part
})
.ToArray();
IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync<IJSInProcessObjectReference>("constructBlob", jsBlobParts, options);
return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance);
}
/// <summary>
/// Constructs a wrapper instance for a given JS Instance of a <see cref="Blob"/>.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="jSReference">A JS reference to an existing <see cref="Blob"/>.</param>
/// <returns>A wrapper instance for a <see cref="Blob"/>.</returns>
public static async Task<BlobInProcess> CreateAsync(IJSRuntime jSRuntime, IJSInProcessObjectReference jSReference)
{
IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync();
return new BlobInProcess(jSRuntime, inProcessHelper, jSReference);
}

/// <summary>
/// Constructs a wrapper instance for a given JS Instance of a <see cref="Blob"/>.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="inProcessHelper">An in process helper instance.</param>
/// <param name="jSReference">A JS reference to an existing <see cref="Blob"/>.</param>
internal BlobInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference)
{
this.inProcessHelper = inProcessHelper;
JSReference = jSReference;
}
/// <summary>
/// Constructs a wrapper instance using the standard constructor.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="blobParts">The parts that will make the new <see cref="Blob"/>.</param>
/// <param name="options">Options for constructing the new Blob which includes MIME type and line endings settings.</param>
/// <returns></returns>
public static new async Task<BlobInProcess> CreateAsync(IJSRuntime jSRuntime, IList<BlobPart>? blobParts = null, BlobPropertyBag? options = null)
{
IJSInProcessObjectReference inProcessHelper = await jSRuntime.GetInProcessHelperAsync();
object?[]? jsBlobParts = blobParts?.Select<BlobPart, object?>(blobPart => blobPart.Part switch
{
byte[] part => part,
Blob part => part.JSReference,
_ => blobPart.Part
})
.ToArray();
IJSInProcessObjectReference jSInstance = await inProcessHelper.InvokeAsync<IJSInProcessObjectReference>("constructBlob", jsBlobParts, options);
return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance);
}

/// <summary>
/// Creates a new <see cref="ReadableStreamInProcess"/> from the <see cref="Blob"/>.
/// </summary>
/// <returns>A new wrapper for a <see cref="ReadableStreamInProcess"/></returns>
public new async Task<ReadableStreamInProcess> StreamAsync()
{
IJSInProcessObjectReference jSInstance = JSReference.Invoke<IJSInProcessObjectReference>("stream");
return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance);
}
/// <summary>
/// Constructs a wrapper instance for a given JS Instance of a <see cref="Blob"/>.
/// </summary>
/// <param name="jSRuntime">An <see cref="IJSRuntime"/> instance.</param>
/// <param name="inProcessHelper">An in process helper instance.</param>
/// <param name="jSReference">A JS reference to an existing <see cref="Blob"/>.</param>
internal BlobInProcess(IJSRuntime jSRuntime, IJSInProcessObjectReference inProcessHelper, IJSInProcessObjectReference jSReference) : base(jSRuntime, jSReference)
{
this.inProcessHelper = inProcessHelper;
JSReference = jSReference;
}

/// <summary>
/// The size of this blob.
/// </summary>
/// <returns>A <see langword="ulong"/> representing the size of the blob in bytes.</returns>
public ulong Size => inProcessHelper.Invoke<ulong>("getAttribute", JSReference, "size");
/// <summary>
/// Creates a new <see cref="ReadableStreamInProcess"/> from the <see cref="Blob"/>.
/// </summary>
/// <returns>A new wrapper for a <see cref="ReadableStreamInProcess"/></returns>
public new async Task<ReadableStreamInProcess> StreamAsync()
{
IJSInProcessObjectReference jSInstance = JSReference.Invoke<IJSInProcessObjectReference>("stream");
return await ReadableStreamInProcess.CreateAsync(jSRuntime, jSInstance);
}

/// <summary>
/// The media type of this blob. This is either a parseable MIME type or an empty string.
/// </summary>
/// <returns>The MIME type of this blob.</returns>
public string Type => inProcessHelper.Invoke<string>("getAttribute", JSReference, "type");
/// <summary>
/// The size of this blob.
/// </summary>
/// <returns>A <see langword="ulong"/> representing the size of the blob in bytes.</returns>
public ulong Size => inProcessHelper.Invoke<ulong>("getAttribute", JSReference, "size");

/// <summary>
/// Gets some range of the content of a <see cref="Blob"/> as a new <see cref="Blob"/>.
/// </summary>
/// <param name="start">The start index of the range. If <see langword="null"/> or negative then <c>0</c> is assumed.</param>
/// <param name="end">The start index of the range. If <see langword="null"/> or larger than the size of the original <see cref="Blob"/> then the size of the original <see cref="Blob"/> is assumed.</param>
/// <param name="contentType">An optional MIME type of the new <see cref="Blob"/>. If <see langword="null"/> then the MIME type of the original <see cref="Blob"/> is used.</param>
/// <returns>A new <see cref="BlobInProcess"/>.</returns>
public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null)
{
start ??= 0;
end ??= (long)Size;
IJSInProcessObjectReference jSInstance = JSReference.Invoke<IJSInProcessObjectReference>("slice", start, end, contentType);
return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance);
/// <summary>
/// The media type of this blob. This is either a parseable MIME type or an empty string.
/// </summary>
/// <returns>The MIME type of this blob.</returns>
public string Type => inProcessHelper.Invoke<string>("getAttribute", JSReference, "type");

/// <summary>
/// Gets some range of the content of a <see cref="Blob"/> as a new <see cref="Blob"/>.
/// </summary>
/// <param name="start">The start index of the range. If <see langword="null"/> or negative then <c>0</c> is assumed.</param>
/// <param name="end">The start index of the range. If <see langword="null"/> or larger than the size of the original <see cref="Blob"/> then the size of the original <see cref="Blob"/> is assumed.</param>
/// <param name="contentType">An optional MIME type of the new <see cref="Blob"/>. If <see langword="null"/> then the MIME type of the original <see cref="Blob"/> is used.</param>
/// <returns>A new <see cref="BlobInProcess"/>.</returns>
public BlobInProcess Slice(long? start = null, long? end = null, string? contentType = null)
{
start ??= 0;
end ??= (long)Size;
IJSInProcessObjectReference jSInstance = JSReference.Invoke<IJSInProcessObjectReference>("slice", start, end, contentType);
return new BlobInProcess(jSRuntime, inProcessHelper, jSInstance);
}
}
}
Loading