diff --git a/.gitignore b/.gitignore
index 45bfc87..74f3f03 100644
--- a/.gitignore
+++ b/.gitignore
@@ -331,3 +331,5 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+/src/Blazor.FileReader/script/package-lock.json
+/src/Blazor.FileReader/package-lock.json
diff --git a/src/Blazor.FileReader/Blazor.FileReader.csproj b/src/Blazor.FileReader/Blazor.FileReader.csproj
index 8c431a0..422d7df 100644
--- a/src/Blazor.FileReader/Blazor.FileReader.csproj
+++ b/src/Blazor.FileReader/Blazor.FileReader.csproj
@@ -1,89 +1,85 @@
-
-
-
-
- netstandard2.0;net5.0;net6.0
- true
- true
- latest
- false
- Tor Knutsson (Tewr)
- https://github.com/Tewr/BlazorFileReader
- https://github.com/Tewr/BlazorFileReader
- Create Read-Only file streams from file input elements or drop targets in Blazor.
- blazor blazor-component stream filestream file-stream read-file filereader
- Debug;Release;Ghpages
- Tewr.Blazor.FileReader
- fixes a bug under net6 that would throw PlatformNotSupportedException
- MIT
- icon.png
- 3.0
- Tewr.Blazor.FileReader
- Tewr.Blazor.FileReader
- 3.3.1.21360
- 3.3.1.21360
- 3.3.1.21360
-
-
-
-
-
-
- 1701;1702;NU5104
- Tewr.Blazor.FileReader.xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- Never
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
- $(DefineConstants);NETSTANDARD20
-
-
-
- $(DefineConstants);NET5
-
-
-
+
+
+
+
+ netstandard2.0;net5.0;net6.0
+ true
+ true
+ latest
+ false
+ Tor Knutsson (Tewr)
+ https://github.com/Tewr/BlazorFileReader
+ https://github.com/Tewr/BlazorFileReader
+ Create Read-Only file streams from file input elements or drop targets in Blazor.
+ blazor blazor-component stream filestream file-stream read-file filereader
+ Debug;Release;Ghpages
+ Tewr.Blazor.FileReader
+ fixes a bug under net6 that would throw PlatformNotSupportedException
+ MIT
+ icon.png
+ 3.0
+ Tewr.Blazor.FileReader
+ Tewr.Blazor.FileReader
+ 3.3.1.21360
+ 3.3.1.21360
+ 3.3.1.21360
+
+
+
+
+
+
+ 1701;1702;NU5104
+ Tewr.Blazor.FileReader.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ Never
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ $(DefineConstants);NETSTANDARD20
+
+
+
+ $(DefineConstants);NET5
+
+
+
diff --git a/src/Blazor.FileReader/FileReaderRef.cs b/src/Blazor.FileReader/FileReaderRef.cs
index 47afe47..be65b15 100644
--- a/src/Blazor.FileReader/FileReaderRef.cs
+++ b/src/Blazor.FileReader/FileReaderRef.cs
@@ -1,398 +1,407 @@
-using Microsoft.AspNetCore.Components;
-using Microsoft.JSInterop;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Tewr.Blazor.FileReader.DropEvents;
-
-namespace Tewr.Blazor.FileReader
-{
- ///
- /// Provides methods for interacting with an element that provides file streams.
- ///
- public interface IFileReaderRef
- {
- ///
- /// Register for drop events on the source element
- ///
- /// If set to true, drop target file list becomes additive. Defaults to false.
- /// An awaitable task representing the operation
- Task RegisterDropEventsAsync(bool additive = false);
-
- ///
- /// Register for drop events on the source element
- ///
- /// Provides expert options for manipulating the default javascript behaviour of the drag and drop events.
- /// An awaitable task representing the operation
- Task RegisterDropEventsAsync(DropEventsOptions dropEventsOptions);
-
- ///
- /// Unregister drop events on the source element
- ///
- /// An awaitable Task representing the operation
- Task UnregisterDropEventsAsync();
-
- ///
- /// Register for paste events on the source element
- ///
- /// If set to true, target file list becomes additive. Defaults to false.
- /// An awaitable task representing the operation
- Task RegisterPasteEventAsync(bool additive = false);
-
- ///
- /// Register for paste events on the source element
- ///
- /// Provides expert options for manipulating the default javascript behaviour of the paste events.
- /// An awaitable task representing the operation
- Task RegisterPasteEventAsync(PasteEventOptions pasteEventOptions);
-
- ///
- /// Unregister paste events on the source element
- ///
- /// An awaitable Task representing the operation
- Task UnregisterPasteEventAsync();
-
- ///
- /// Clears any value set on the source element
- ///
- /// An awaitable Task representing the operation
- Task ClearValue();
-
- ///
- /// Enumerates the currently selected file references
- ///
- /// An awaitable Task that provides an enumeration of the currently selected file references
- Task> EnumerateFilesAsync();
- }
-
- ///
- /// Provides properties and instance methods for the reading file metadata and aids in the creation of Readonly Stream objects.
- ///
- public interface IFileReference
- {
-
-#if NET5_0_OR_GREATER
- ///
- /// Returns the underlying file object as an
- ///
- ///
- Task GetJSObjectReferenceAsync();
-
- ///
- /// Returns an object url for a file.
- ///
- ///
- Task GetObjectUrlAsync();
-#endif
-
- ///
- /// Opens a read-only to read the file.
- ///
- /// A read-only to read the file.
- Task OpenReadAsync();
-
- ///
- /// Opens a read-only base64-encoded string stream to read the file
- ///
- /// A read-only to read the file.
- Task OpenReadBase64Async();
-
- ///
- /// Convenience method to read the file fully into memory using a single interop call
- /// and returns it as a . Buffer size will be equal to the file size.
- /// The length of the resulting will be the same as the file size.
- ///
- /// In most cases the fastest way to read a file into ram, but also the method that uses the most memory.
- /// Will use at least twice the file size of memory at the end of the read operation.
- /// A representing the full file, with set to 0.
- Task CreateMemoryStreamAsync();
-
- ///
- /// Convenience method to read the file fully into memory using a single interop call
- /// and returns it as a . Buffer size will be equal to the file size.
- /// The length of the resulting will be the same as the file size.
- ///
- /// In most cases the fastest way to read a file into ram, but the most expensive in memory usage.
- /// Will use at least twice the file size of memory at the end of the read operation.
- /// A representing the full file, with set to 0.
- Task CreateMemoryStreamAsync(CancellationToken cancellationToken);
-
- ///
- /// Convenience method to read the file fully into memory represented as a , using the specified .
- /// The length of the resulting will be the same as the file size.
- ///
- /// A representing the full file, with set to 0.
- Task CreateMemoryStreamAsync(int bufferSize);
-
- ///
- /// Convenience method to read the file fully into memory represented as a , using the specified .
- /// The length of the resulting will be the same as the file size.
- ///
- /// A representing the full file, with set to 0.
- Task CreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken);
-
- ///
- /// Reads the file metadata.
- ///
- /// An object containing the file metadata
- Task ReadFileInfoAsync();
- }
-
- ///
- /// Provides a base64-encoded string view of a sequence of bytes from a file.
- ///
- public interface IBase64Stream : IDisposable, IAsyncDisposable
- {
- ///
- /// Gets or sets the current byte position in the Stream.
- ///
- long Position { get; set; }
-
- ///
- /// Gets the length of the stream in bytes.
- ///
- long Length { get; }
-
- ///
- /// Asynchronously reads a sequence of bytes as a base64 encoded string from the current stream
- /// and advances the position within the stream by the number of bytes read.
- ///
- /// The byte offset in the source at which to begin reading data from the stream.
- /// The maximum number of bytes to read.
- ///
- /// The requested sequence of bytes as a base64 encoded string.
- /// The resulting string can be shorter than the number of bytes requested if
- /// the number of bytes currently available is less than the requested
- /// number, or it can be string.empty if the end of the stream has been reached.
- Task ReadAsync(int offset, int count, CancellationToken cancellationToken);
- }
-
- ///
- /// Provides properties for file metadata.
- ///
- public interface IFileInfo
- {
- ///
- /// Returns the name of the file referenced by the File object.
- ///
- string Name { get; }
-
- ///
- /// Returns a list of non-standard DOM properties attached to the object, like the webkitRelativePath property.
- ///
- Dictionary NonStandardProperties { get; }
-
- ///
- /// Returns the size of the file in bytes.
- ///
- long Size { get; }
-
- ///
- /// Returns the MIME type of the file.
- ///
- string Type { get; }
-
- ///
- /// Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at Midnight).
- ///
- long? LastModified { get; }
-
- ///
- /// Returns the last modified time of the file.
- ///
- DateTime? LastModifiedDate { get; }
-
- ///
- /// Returns information of the position of any stream related to this file.
- ///
- IFilePositionInfo PositionInfo { get; }
- }
-
- internal class FileReaderRef : IFileReaderRef
- {
- public async Task> EnumerateFilesAsync() =>
- Enumerable.Range(0, Math.Max(0, await this.FileReaderJsInterop.GetFileCount(this.ElementRef)))
- .Select(index => (IFileReference)new FileReference(this, index));
-
- public async Task RegisterDropEventsAsync(bool additive) =>
- await RegisterDropEventsAsync(new DropEventsOptions { Additive = additive });
-
- public async Task RegisterDropEventsAsync(DropEventsOptions dropEventsOptions)
- {
- if (dropEventsOptions is null)
- {
- throw new ArgumentNullException(nameof(dropEventsOptions));
- }
-
- await this.FileReaderJsInterop.RegisterDropEvents(this.ElementRef, dropEventsOptions);
- }
-
- public async Task UnregisterDropEventsAsync() => await this.FileReaderJsInterop.UnregisterDropEvents(this.ElementRef);
-
- public async Task RegisterPasteEventAsync(bool additive) =>
- await RegisterPasteEventAsync(new PasteEventOptions { Additive = additive });
-
- public async Task RegisterPasteEventAsync(PasteEventOptions pasteEventOptions)
- {
- if (pasteEventOptions is null)
- {
- throw new ArgumentNullException(nameof(pasteEventOptions));
- }
-
- await this.FileReaderJsInterop.RegisterPasteEvent(this.ElementRef, pasteEventOptions);
- }
-
- public async Task UnregisterPasteEventAsync() => await this.FileReaderJsInterop.UnregisterPasteEvent(this.ElementRef);
-
- public async Task ClearValue()
- => await this.FileReaderJsInterop.ClearValue(this.ElementRef);
-
- public ElementReference ElementRef { get; private set; }
- public FileReaderJsInterop FileReaderJsInterop { get; }
-
- internal FileReaderRef(ElementReference elementRef, FileReaderJsInterop fileReaderJsInterop)
- {
- this.ElementRef = elementRef;
- this.FileReaderJsInterop = fileReaderJsInterop;
- }
-
- }
-
- internal class FileReference : IFileReference
- {
- private readonly FileReaderRef fileLoaderRef;
- private readonly int index;
- private IFileInfo fileInfo;
-
- public FileReference(FileReaderRef fileLoaderRef, int index)
- {
- this.fileLoaderRef = fileLoaderRef;
- this.index = index;
- }
-
- public async Task CreateMemoryStreamAsync()
- {
- return await CreateMemoryStreamAsync(CancellationToken.None);
- }
-
- public async Task CreateMemoryStreamAsync(CancellationToken cancellationToken) {
- return await CreateMemoryStreamAsync((int)(await ReadFileInfoAsync()).Size, cancellationToken);
- }
-
- public Task CreateMemoryStreamAsync(int bufferSize)
- {
- return CreateMemoryStreamAsync(bufferSize, CancellationToken.None);
- }
-
- public Task CreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken)
- {
- return InnerCreateMemoryStreamAsync(bufferSize, cancellationToken);
- }
-
- public async Task OpenReadAsync()
- {
- return await this.fileLoaderRef.FileReaderJsInterop.OpenFileStream(this.fileLoaderRef.ElementRef, index, await ReadFileInfoAsync());
- }
-
- public async Task ReadFileInfoAsync()
- {
- if (fileInfo == null)
- {
- fileInfo = await this.fileLoaderRef.FileReaderJsInterop.GetFileInfoFromElement(fileLoaderRef.ElementRef, index);
- }
-
- return fileInfo;
- }
-
- public async Task OpenReadBase64Async()
- {
- return await this.fileLoaderRef.FileReaderJsInterop.OpenBase64Stream(fileLoaderRef.ElementRef, index, await ReadFileInfoAsync());
- }
-
- private async Task InnerCreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken)
- {
- MemoryStream memoryStream;
- if (bufferSize < 1)
- {
- throw new InvalidOperationException("Unable to determine buffersize or provided buffersize was 0 or less");
- }
- else
- {
- memoryStream = new MemoryStream(bufferSize);
- }
-
- await using (var fs = await OpenReadAsync())
- {
- await fs.CopyToAsync(memoryStream, bufferSize, cancellationToken);
- }
- memoryStream.Position = 0;
- return memoryStream;
- }
-
-#if NET5_0_OR_GREATER
- public Task GetJSObjectReferenceAsync()
- {
- return this.fileLoaderRef.FileReaderJsInterop.GetJSObjectReferenceAsync(fileLoaderRef.ElementRef, this.index);
- }
-
- public async Task GetObjectUrlAsync()
- {
- var file = await GetJSObjectReferenceAsync();
-
- var objectUrl = new ObjectUrl(this.fileLoaderRef.FileReaderJsInterop.CurrentJSRuntime, file);
- await objectUrl.InitAsync();
- return objectUrl;
- }
-
-#endif
-
- }
-
- internal class FileInfo : IFileInfo
- {
- private static readonly DateTime Epoch = new DateTime(1970, 01, 01);
- private readonly Lazy lastModifiedDate;
- private readonly FilePositionInfo filePositionInfo;
- private long size;
-
- public FileInfo()
- {
- this.lastModifiedDate = new Lazy(() =>
- LastModified == null ? null : (DateTime?)Epoch.AddMilliseconds(this.LastModified.Value));
- this.filePositionInfo = new FilePositionInfo();
- }
-
- public string Name { get; set; }
-
- public Dictionary NonStandardProperties { get; set; }
-
- public long Size {
- get => size;
- set {
- size = value;
- this.filePositionInfo.FileSize = size;
- }
- }
-
- public string Type { get; set; }
-
- public long? LastModified { get; set; }
-
- public DateTime? LastModifiedDate => this.lastModifiedDate.Value;
-
- public IFilePositionInfo PositionInfo => filePositionInfo;
- }
-
- ///
- /// Stream that implements
- ///
- public abstract class AsyncDisposableStream : Stream, IAsyncDisposable
- {
- ///
- public abstract ValueTask DisposeAsync();
- }
-
-}
+using Microsoft.AspNetCore.Components;
+using Microsoft.JSInterop;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Tewr.Blazor.FileReader.DropEvents;
+
+namespace Tewr.Blazor.FileReader
+{
+ ///
+ /// Provides methods for interacting with an element that provides file streams.
+ ///
+ public interface IFileReaderRef
+ {
+ ///
+ /// Register for drop events on the source element
+ ///
+ /// If set to true, drop target file list becomes additive. Defaults to false.
+ /// An awaitable task representing the operation
+ Task RegisterDropEventsAsync(bool additive = false);
+
+ ///
+ /// Register for drop events on the source element
+ ///
+ /// Provides expert options for manipulating the default javascript behaviour of the drag and drop events.
+ /// An awaitable task representing the operation
+ Task RegisterDropEventsAsync(DropEventsOptions dropEventsOptions);
+
+ ///
+ /// Unregister drop events on the source element
+ ///
+ /// An awaitable Task representing the operation
+ Task UnregisterDropEventsAsync();
+
+ ///
+ /// Register for paste events on the source element
+ ///
+ /// If set to true, target file list becomes additive. Defaults to false.
+ /// An awaitable task representing the operation
+ Task RegisterPasteEventAsync(bool additive = false);
+
+ ///
+ /// Register for paste events on the source element
+ ///
+ /// Provides expert options for manipulating the default javascript behaviour of the paste events.
+ /// An awaitable task representing the operation
+ Task RegisterPasteEventAsync(PasteEventOptions pasteEventOptions);
+
+ ///
+ /// Unregister paste events on the source element
+ ///
+ /// An awaitable Task representing the operation
+ Task UnregisterPasteEventAsync();
+
+ ///
+ /// Clears any value set on the source element
+ ///
+ /// An awaitable Task representing the operation
+ Task ClearValue();
+
+ ///
+ /// Enumerates the currently selected file references
+ ///
+ /// An awaitable Task that provides an enumeration of the currently selected file references
+ Task> EnumerateFilesAsync();
+ }
+
+ ///
+ /// Provides properties and instance methods for the reading file metadata and aids in the creation of Readonly Stream objects.
+ ///
+ public interface IFileReference
+ {
+
+#if NET5_0_OR_GREATER
+ ///
+ /// Returns the underlying file object as an
+ ///
+ ///
+ Task GetJSObjectReferenceAsync();
+
+ ///
+ /// Returns an object url for a file.
+ ///
+ ///
+ Task GetObjectUrlAsync();
+#endif
+
+ ///
+ /// Opens a read-only to read the file.
+ ///
+ /// A read-only to read the file.
+ Task OpenReadAsync();
+
+ ///
+ /// Opens a read-only base64-encoded string stream to read the file
+ ///
+ /// A read-only to read the file.
+ Task OpenReadBase64Async();
+
+ ///
+ /// Convenience method to read the file fully into memory using a single interop call
+ /// and returns it as a . Buffer size will be equal to the file size.
+ /// The length of the resulting will be the same as the file size.
+ ///
+ /// In most cases the fastest way to read a file into ram, but also the method that uses the most memory.
+ /// Will use at least twice the file size of memory at the end of the read operation.
+ /// A representing the full file, with set to 0.
+ Task CreateMemoryStreamAsync();
+
+ ///
+ /// Convenience method to read the file fully into memory using a single interop call
+ /// and returns it as a . Buffer size will be equal to the file size.
+ /// The length of the resulting will be the same as the file size.
+ ///
+ /// In most cases the fastest way to read a file into ram, but the most expensive in memory usage.
+ /// Will use at least twice the file size of memory at the end of the read operation.
+ /// A representing the full file, with set to 0.
+ Task CreateMemoryStreamAsync(CancellationToken cancellationToken);
+
+ ///
+ /// Convenience method to read the file fully into memory represented as a , using the specified .
+ /// The length of the resulting will be the same as the file size.
+ ///
+ /// A representing the full file, with set to 0.
+ Task CreateMemoryStreamAsync(int bufferSize);
+
+ ///
+ /// Convenience method to read the file fully into memory represented as a , using the specified .
+ /// The length of the resulting will be the same as the file size.
+ ///
+ /// A representing the full file, with set to 0.
+ Task CreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken);
+
+ ///
+ /// Reads the file metadata.
+ ///
+ /// An object containing the file metadata
+ Task ReadFileInfoAsync();
+ }
+
+ ///
+ /// Provides a base64-encoded string view of a sequence of bytes from a file.
+ ///
+ public interface IBase64Stream : IDisposable, IAsyncDisposable
+ {
+ ///
+ /// Gets or sets the current byte position in the Stream.
+ ///
+ long Position { get; set; }
+
+ ///
+ /// Gets the length of the stream in bytes.
+ ///
+ long Length { get; }
+
+ ///
+ /// Asynchronously reads a sequence of bytes as a base64 encoded string from the current stream
+ /// and advances the position within the stream by the number of bytes read.
+ ///
+ /// The byte offset in the source at which to begin reading data from the stream.
+ /// The maximum number of bytes to read.
+ ///
+ /// The requested sequence of bytes as a base64 encoded string.
+ /// The resulting string can be shorter than the number of bytes requested if
+ /// the number of bytes currently available is less than the requested
+ /// number, or it can be string.empty if the end of the stream has been reached.
+ Task ReadAsync(int offset, int count, CancellationToken cancellationToken);
+ }
+
+ ///
+ /// Provides properties for file metadata.
+ ///
+ public interface IFileInfo
+ {
+ ///
+ /// Returns the name of the file referenced by the File object.
+ ///
+ string Name { get; }
+
+ ///
+ /// Returns a list of non-standard DOM properties attached to the object, like the webkitRelativePath property.
+ ///
+ Dictionary NonStandardProperties { get; }
+
+ ///
+ /// Returns the size of the file in bytes.
+ ///
+ long Size { get; }
+
+ ///
+ /// Returns the MIME type of the file.
+ ///
+ string Type { get; }
+
+ ///
+ /// Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at Midnight).
+ ///
+ long? LastModified { get; }
+
+ ///
+ /// Returns the last modified time of the file.
+ ///
+ DateTime? LastModifiedDate { get; }
+
+ ///
+ /// Gets the relative path including the filename.
+ ///
+ /// The webkit relative path.
+ string WebkitRelativePath { get; }
+
+ ///
+ /// Returns information of the position of any stream related to this file.
+ ///
+ IFilePositionInfo PositionInfo { get; }
+ }
+
+ internal class FileReaderRef : IFileReaderRef
+ {
+ public async Task> EnumerateFilesAsync() =>
+ Enumerable.Range(0, Math.Max(0, await this.FileReaderJsInterop.GetFileCount(this.ElementRef)))
+ .Select(index => (IFileReference)new FileReference(this, index));
+
+ public async Task RegisterDropEventsAsync(bool additive) =>
+ await RegisterDropEventsAsync(new DropEventsOptions { Additive = additive });
+
+ public async Task RegisterDropEventsAsync(DropEventsOptions dropEventsOptions)
+ {
+ if (dropEventsOptions is null)
+ {
+ throw new ArgumentNullException(nameof(dropEventsOptions));
+ }
+
+ await this.FileReaderJsInterop.RegisterDropEvents(this.ElementRef, dropEventsOptions);
+ }
+
+ public async Task UnregisterDropEventsAsync() => await this.FileReaderJsInterop.UnregisterDropEvents(this.ElementRef);
+
+ public async Task RegisterPasteEventAsync(bool additive) =>
+ await RegisterPasteEventAsync(new PasteEventOptions { Additive = additive });
+
+ public async Task RegisterPasteEventAsync(PasteEventOptions pasteEventOptions)
+ {
+ if (pasteEventOptions is null)
+ {
+ throw new ArgumentNullException(nameof(pasteEventOptions));
+ }
+
+ await this.FileReaderJsInterop.RegisterPasteEvent(this.ElementRef, pasteEventOptions);
+ }
+
+ public async Task UnregisterPasteEventAsync() => await this.FileReaderJsInterop.UnregisterPasteEvent(this.ElementRef);
+
+ public async Task ClearValue()
+ => await this.FileReaderJsInterop.ClearValue(this.ElementRef);
+
+ public ElementReference ElementRef { get; private set; }
+ public FileReaderJsInterop FileReaderJsInterop { get; }
+
+ internal FileReaderRef(ElementReference elementRef, FileReaderJsInterop fileReaderJsInterop)
+ {
+ this.ElementRef = elementRef;
+ this.FileReaderJsInterop = fileReaderJsInterop;
+ }
+
+ }
+
+ internal class FileReference : IFileReference
+ {
+ private readonly FileReaderRef fileLoaderRef;
+ private readonly int index;
+ private IFileInfo fileInfo;
+
+ public FileReference(FileReaderRef fileLoaderRef, int index)
+ {
+ this.fileLoaderRef = fileLoaderRef;
+ this.index = index;
+ }
+
+ public async Task CreateMemoryStreamAsync()
+ {
+ return await CreateMemoryStreamAsync(CancellationToken.None);
+ }
+
+ public async Task CreateMemoryStreamAsync(CancellationToken cancellationToken) {
+ return await CreateMemoryStreamAsync((int)(await ReadFileInfoAsync()).Size, cancellationToken);
+ }
+
+ public Task CreateMemoryStreamAsync(int bufferSize)
+ {
+ return CreateMemoryStreamAsync(bufferSize, CancellationToken.None);
+ }
+
+ public Task CreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken)
+ {
+ return InnerCreateMemoryStreamAsync(bufferSize, cancellationToken);
+ }
+
+ public async Task OpenReadAsync()
+ {
+ return await this.fileLoaderRef.FileReaderJsInterop.OpenFileStream(this.fileLoaderRef.ElementRef, index, await ReadFileInfoAsync());
+ }
+
+ public async Task ReadFileInfoAsync()
+ {
+ if (fileInfo == null)
+ {
+ fileInfo = await this.fileLoaderRef.FileReaderJsInterop.GetFileInfoFromElement(fileLoaderRef.ElementRef, index);
+ }
+
+ return fileInfo;
+ }
+
+ public async Task OpenReadBase64Async()
+ {
+ return await this.fileLoaderRef.FileReaderJsInterop.OpenBase64Stream(fileLoaderRef.ElementRef, index, await ReadFileInfoAsync());
+ }
+
+ private async Task InnerCreateMemoryStreamAsync(int bufferSize, CancellationToken cancellationToken)
+ {
+ MemoryStream memoryStream;
+ if (bufferSize < 1)
+ {
+ throw new InvalidOperationException("Unable to determine buffersize or provided buffersize was 0 or less");
+ }
+ else
+ {
+ memoryStream = new MemoryStream(bufferSize);
+ }
+
+ await using (var fs = await OpenReadAsync())
+ {
+ await fs.CopyToAsync(memoryStream, bufferSize, cancellationToken);
+ }
+ memoryStream.Position = 0;
+ return memoryStream;
+ }
+
+#if NET5_0_OR_GREATER
+ public Task GetJSObjectReferenceAsync()
+ {
+ return this.fileLoaderRef.FileReaderJsInterop.GetJSObjectReferenceAsync(fileLoaderRef.ElementRef, this.index);
+ }
+
+ public async Task GetObjectUrlAsync()
+ {
+ var file = await GetJSObjectReferenceAsync();
+
+ var objectUrl = new ObjectUrl(this.fileLoaderRef.FileReaderJsInterop.CurrentJSRuntime, file);
+ await objectUrl.InitAsync();
+ return objectUrl;
+ }
+
+#endif
+
+ }
+
+ internal class FileInfo : IFileInfo
+ {
+ private static readonly DateTime Epoch = new DateTime(1970, 01, 01);
+ private readonly Lazy lastModifiedDate;
+ private readonly FilePositionInfo filePositionInfo;
+ private long size;
+
+ public FileInfo()
+ {
+ this.lastModifiedDate = new Lazy(() =>
+ LastModified == null ? null : (DateTime?)Epoch.AddMilliseconds(this.LastModified.Value));
+ this.filePositionInfo = new FilePositionInfo();
+ }
+
+ public string Name { get; set; }
+
+ public Dictionary NonStandardProperties { get; set; }
+
+ public long Size {
+ get => size;
+ set {
+ size = value;
+ this.filePositionInfo.FileSize = size;
+ }
+ }
+
+ public string Type { get; set; }
+
+ public long? LastModified { get; set; }
+
+ public DateTime? LastModifiedDate => this.lastModifiedDate.Value;
+
+ ///
+ public string WebkitRelativePath { get; set; }
+
+ public IFilePositionInfo PositionInfo => filePositionInfo;
+ }
+
+ ///
+ /// Stream that implements
+ ///
+ public abstract class AsyncDisposableStream : Stream, IAsyncDisposable
+ {
+ ///
+ public abstract ValueTask DisposeAsync();
+ }
+
+}
diff --git a/src/Blazor.FileReader/Tewr.Blazor.FileReader.md b/src/Blazor.FileReader/Tewr.Blazor.FileReader.md
index df868f6..a821d8d 100644
--- a/src/Blazor.FileReader/Tewr.Blazor.FileReader.md
+++ b/src/Blazor.FileReader/Tewr.Blazor.FileReader.md
@@ -21,6 +21,8 @@
- [OnRegisterDropEventsScript](#P-Tewr-Blazor-FileReader-DropEvents-DropEventsOptions-OnRegisterDropEventsScript 'Tewr.Blazor.FileReader.DropEvents.DropEventsOptions.OnRegisterDropEventsScript')
- [DropEventsOptionsExtensions](#T-Tewr-Blazor-FileReader-DropEvents-DropEventsOptionsExtensions 'Tewr.Blazor.FileReader.DropEvents.DropEventsOptionsExtensions')
- [SetDragOverDataTransferDropEffect(source,dropEffect)](#M-Tewr-Blazor-FileReader-DropEvents-DropEventsOptionsExtensions-SetDragOverDataTransferDropEffect-Tewr-Blazor-FileReader-DropEvents-DropEventsOptions,Tewr-Blazor-FileReader-DropEvents-DropEffect- 'Tewr.Blazor.FileReader.DropEvents.DropEventsOptionsExtensions.SetDragOverDataTransferDropEffect(Tewr.Blazor.FileReader.DropEvents.DropEventsOptions,Tewr.Blazor.FileReader.DropEvents.DropEffect)')
+- [FileInfo](#T-Tewr-Blazor-FileReader-FileInfo 'Tewr.Blazor.FileReader.FileInfo')
+ - [WebkitRelativePath](#P-Tewr-Blazor-FileReader-FileInfo-WebkitRelativePath 'Tewr.Blazor.FileReader.FileInfo.WebkitRelativePath')
- [FileReaderJsInterop](#T-Tewr-Blazor-FileReader-FileReaderJsInterop 'Tewr.Blazor.FileReader.FileReaderJsInterop')
- [EndTask(taskId)](#M-Tewr-Blazor-FileReader-FileReaderJsInterop-EndTask-System-Int64- 'Tewr.Blazor.FileReader.FileReaderJsInterop.EndTask(System.Int64)')
- [FileReaderServiceOptions](#T-Tewr-Blazor-FileReader-FileReaderServiceOptions 'Tewr.Blazor.FileReader.FileReaderServiceOptions')
@@ -38,6 +40,7 @@
- [PositionInfo](#P-Tewr-Blazor-FileReader-IFileInfo-PositionInfo 'Tewr.Blazor.FileReader.IFileInfo.PositionInfo')
- [Size](#P-Tewr-Blazor-FileReader-IFileInfo-Size 'Tewr.Blazor.FileReader.IFileInfo.Size')
- [Type](#P-Tewr-Blazor-FileReader-IFileInfo-Type 'Tewr.Blazor.FileReader.IFileInfo.Type')
+ - [WebkitRelativePath](#P-Tewr-Blazor-FileReader-IFileInfo-WebkitRelativePath 'Tewr.Blazor.FileReader.IFileInfo.WebkitRelativePath')
- [IFilePositionInfo](#T-Tewr-Blazor-FileReader-IFilePositionInfo 'Tewr.Blazor.FileReader.IFilePositionInfo')
- [DataStream](#P-Tewr-Blazor-FileReader-IFilePositionInfo-DataStream 'Tewr.Blazor.FileReader.IFilePositionInfo.DataStream')
- [Percentage](#P-Tewr-Blazor-FileReader-IFilePositionInfo-Percentage 'Tewr.Blazor.FileReader.IFilePositionInfo.Percentage')
@@ -253,6 +256,20 @@ Sets the specified [](#!-dropEffect 'dropEffect') value on the dataTransfer prop
https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
+
+## FileInfo `type`
+
+##### Namespace
+
+Tewr.Blazor.FileReader
+
+
+### WebkitRelativePath `property`
+
+##### Summary
+
+*Inherit from parent.*
+
## FileReaderJsInterop `type`
@@ -402,6 +419,13 @@ Returns the size of the file in bytes.
Returns the MIME type of the file.
+
+### WebkitRelativePath `property`
+
+##### Summary
+
+Gets the relative path including the filename.
+
## IFilePositionInfo `type`
diff --git a/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml b/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml
index e86d784..a2d3b5d 100644
--- a/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml
+++ b/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml
@@ -1,464 +1,473 @@
-
-
-
- Tewr.Blazor.FileReader
-
-
-
-
- Exception that is thrown if an exception occurs in the browser during file reader operations
-
-
-
-
-
- If set to true, drop target file list becomes additive. Defaults to false.
-
-
-
-
- Predefined global javascript function that will be executed on the drop event.
- The method will be passed the following arguments: The Event, the target element, and the FileReaderComponent instance.
-
-
-
-
- Javascript function snippet that will be executed on the drop event.
- The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
- Do not set this property using user-provided data, as it would be a security risk.
-
-
-
-
- Predefined global javascript function that will be executed on the dragover event.
- The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
-
-
-
-
- Javascript function snippet that will be executed on the dragover event.
- The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
- Do not set this property using user-provided data, as it would be a security risk.
-
-
-
-
- Predefined global javascript function that will be executed immediately after the drag and drop events have been registered.
- The method will be passed the following arguments: null, the target element, and the FileReaderComponent instance.
-
-
-
-
- Javascript function snippet that will be executed immediately after the drag and drop events have been registered.
- The method will be passed the following arguments: null, the target element, and the FileReaderComponent instance.
- Do not set this property using user-provided data, as it would be a security risk.
-
-
-
-
- Possible values of the DataTransfer.dropEffect property
-
-
- https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
-
-
-
-
- A copy of the source item is made at the new location.
-
-
-
-
- An item is moved to a new location.
-
-
-
-
- A link is established to the source at the new location.
-
-
-
-
- The item may not be dropped.
-
-
-
-
- Sets the specified value on the dataTransfer property in the dragover event to the specified value.
-
-
-
- https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
-
-
-
-
- Provides expert options for manipulating the default behaviour of the paste event.
-
-
-
-
- If set to true, paste target file list becomes additive. Defaults to false.
-
-
-
-
- Provides information on the position of a Stream currently reading this file.
-
-
-
-
- The current position of a Stream currently reading this file.
-
-
-
-
- The value of when was last called
-
-
-
-
- The delta between current and what the value was at the last call to
-
-
-
-
- The current position of a Stream currently reading this file, relative to the file size.
-
-
-
-
- The value of when was last called
-
-
-
-
- The delta between current and
-
-
-
-
- The underlying stream that was the source of the change.
-
-
-
-
- Saves value of to
- and to
-
-
- The saved values may also be comsumed as deltas from convenience
- properties and
-
-
-
-
- Called after has changed.
-
-
-
-
- Called from Js
-
-
-
-
-
- Provides methods for interacting with an element that provides file streams.
-
-
-
-
- Register for drop events on the source element
-
- If set to true, drop target file list becomes additive. Defaults to false.
- An awaitable task representing the operation
-
-
-
- Register for drop events on the source element
-
- Provides expert options for manipulating the default javascript behaviour of the drag and drop events.
- An awaitable task representing the operation
-
-
-
- Unregister drop events on the source element
-
- An awaitable Task representing the operation
-
-
-
- Register for paste events on the source element
-
- If set to true, target file list becomes additive. Defaults to false.
- An awaitable task representing the operation
-
-
-
- Register for paste events on the source element
-
- Provides expert options for manipulating the default javascript behaviour of the paste events.
- An awaitable task representing the operation
-
-
-
- Unregister paste events on the source element
-
- An awaitable Task representing the operation
-
-
-
- Clears any value set on the source element
-
- An awaitable Task representing the operation
-
-
-
- Enumerates the currently selected file references
-
- An awaitable Task that provides an enumeration of the currently selected file references
-
-
-
- Provides properties and instance methods for the reading file metadata and aids in the creation of Readonly Stream objects.
-
-
-
-
- Returns the underlying file object as an
-
-
-
-
-
- Returns an object url for a file.
-
-
-
-
-
- Opens a read-only to read the file.
-
- A read-only to read the file.
-
-
-
- Opens a read-only base64-encoded string stream to read the file
-
- A read-only to read the file.
-
-
-
- Convenience method to read the file fully into memory using a single interop call
- and returns it as a . Buffer size will be equal to the file size.
- The length of the resulting will be the same as the file size.
-
- In most cases the fastest way to read a file into ram, but also the method that uses the most memory.
- Will use at least twice the file size of memory at the end of the read operation.
- A representing the full file, with set to 0.
-
-
-
- Convenience method to read the file fully into memory using a single interop call
- and returns it as a . Buffer size will be equal to the file size.
- The length of the resulting will be the same as the file size.
-
- In most cases the fastest way to read a file into ram, but the most expensive in memory usage.
- Will use at least twice the file size of memory at the end of the read operation.
- A representing the full file, with set to 0.
-
-
-
- Convenience method to read the file fully into memory represented as a , using the specified .
- The length of the resulting will be the same as the file size.
-
- A representing the full file, with set to 0.
-
-
-
- Convenience method to read the file fully into memory represented as a , using the specified .
- The length of the resulting will be the same as the file size.
-
- A representing the full file, with set to 0.
-
-
-
- Reads the file metadata.
-
- An object containing the file metadata
-
-
-
- Provides a base64-encoded string view of a sequence of bytes from a file.
-
-
-
-
- Gets or sets the current byte position in the Stream.
-
-
-
-
- Gets the length of the stream in bytes.
-
-
-
-
- Asynchronously reads a sequence of bytes as a base64 encoded string from the current stream
- and advances the position within the stream by the number of bytes read.
-
- The byte offset in the source at which to begin reading data from the stream.
- The maximum number of bytes to read.
-
- The requested sequence of bytes as a base64 encoded string.
- The resulting string can be shorter than the number of bytes requested if
- the number of bytes currently available is less than the requested
- number, or it can be string.empty if the end of the stream has been reached.
-
-
-
- Provides properties for file metadata.
-
-
-
-
- Returns the name of the file referenced by the File object.
-
-
-
-
- Returns a list of non-standard DOM properties attached to the object, like the webkitRelativePath property.
-
-
-
-
- Returns the size of the file in bytes.
-
-
-
-
- Returns the MIME type of the file.
-
-
-
-
- Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at Midnight).
-
-
-
-
- Returns the last modified time of the file.
-
-
-
-
- Returns information of the position of any stream related to this file.
-
-
-
-
- Stream that implements
-
-
-
-
-
-
-
- Provides configuration options for
-
-
-
-
- Initializes the file service on the first interop call.
- Redundant for client-side blazor.
-
-
- Initializing on the first call is neccessary only if the javascript
- interop file (FileReaderComponent.js)
- has not been loaded manually using a script tag.
-
-
-
-
- For client-side blazor, uses shared memory buffer to transfer data quickly.
- Not available for server-side blazor.
-
-
-
-
- Activates server-side buffer chunking. Activated if not running on WASM.
-
-
-
-
- SignalR setting
-
-
-
-
- Servive for creating a instance from an element.
-
-
-
-
- Explicitly initializes this instance by loading the neccessary interop code to the browser.
-
-
-
-
-
- Creates a new instance of for the specified element.
-
- A reference to an element that can provide file streams.
- Should be obtained using the @ref attribute.
- Should reference either an input element of type file or a drop target.
- a new instance of
-
-
-
- Represents an object url for a file.
-
- https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
-
-
-
- Returns the Object Url.
-
-
-
-
- Returns true if the application is running on WASM.
-
-
-
-
- Tries reading HubOptions<ComponentHub>.MaximumReceiveMessageSize using reflection.
-
-
-
- true if the value could be sucessfully read.
-
-
-
- Provides extension methods for setting up
-
-
-
-
- Adds as a scoped service
- to the specified .
-
-
-
-
-
- Adds as a scoped service
- to the specified with the specifed
-
-
- Delegate that modifies the options for
-
-
-
+
+
+
+ Tewr.Blazor.FileReader
+
+
+
+
+ Exception that is thrown if an exception occurs in the browser during file reader operations
+
+
+
+
+
+ If set to true, drop target file list becomes additive. Defaults to false.
+
+
+
+
+ Predefined global javascript function that will be executed on the drop event.
+ The method will be passed the following arguments: The Event, the target element, and the FileReaderComponent instance.
+
+
+
+
+ Javascript function snippet that will be executed on the drop event.
+ The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
+ Do not set this property using user-provided data, as it would be a security risk.
+
+
+
+
+ Predefined global javascript function that will be executed on the dragover event.
+ The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
+
+
+
+
+ Javascript function snippet that will be executed on the dragover event.
+ The method will be passed the following arguments: The DragEvent, the target element, and the FileReaderComponent instance.
+ Do not set this property using user-provided data, as it would be a security risk.
+
+
+
+
+ Predefined global javascript function that will be executed immediately after the drag and drop events have been registered.
+ The method will be passed the following arguments: null, the target element, and the FileReaderComponent instance.
+
+
+
+
+ Javascript function snippet that will be executed immediately after the drag and drop events have been registered.
+ The method will be passed the following arguments: null, the target element, and the FileReaderComponent instance.
+ Do not set this property using user-provided data, as it would be a security risk.
+
+
+
+
+ Possible values of the DataTransfer.dropEffect property
+
+
+ https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
+
+
+
+
+ A copy of the source item is made at the new location.
+
+
+
+
+ An item is moved to a new location.
+
+
+
+
+ A link is established to the source at the new location.
+
+
+
+
+ The item may not be dropped.
+
+
+
+
+ Sets the specified value on the dataTransfer property in the dragover event to the specified value.
+
+
+
+ https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
+
+
+
+
+ Provides expert options for manipulating the default behaviour of the paste event.
+
+
+
+
+ If set to true, paste target file list becomes additive. Defaults to false.
+
+
+
+
+ Provides information on the position of a Stream currently reading this file.
+
+
+
+
+ The current position of a Stream currently reading this file.
+
+
+
+
+ The value of when was last called
+
+
+
+
+ The delta between current and what the value was at the last call to
+
+
+
+
+ The current position of a Stream currently reading this file, relative to the file size.
+
+
+
+
+ The value of when was last called
+
+
+
+
+ The delta between current and
+
+
+
+
+ The underlying stream that was the source of the change.
+
+
+
+
+ Saves value of to
+ and to
+
+
+ The saved values may also be comsumed as deltas from convenience
+ properties and
+
+
+
+
+ Called after has changed.
+
+
+
+
+ Called from Js
+
+
+
+
+
+ Provides methods for interacting with an element that provides file streams.
+
+
+
+
+ Register for drop events on the source element
+
+ If set to true, drop target file list becomes additive. Defaults to false.
+ An awaitable task representing the operation
+
+
+
+ Register for drop events on the source element
+
+ Provides expert options for manipulating the default javascript behaviour of the drag and drop events.
+ An awaitable task representing the operation
+
+
+
+ Unregister drop events on the source element
+
+ An awaitable Task representing the operation
+
+
+
+ Register for paste events on the source element
+
+ If set to true, target file list becomes additive. Defaults to false.
+ An awaitable task representing the operation
+
+
+
+ Register for paste events on the source element
+
+ Provides expert options for manipulating the default javascript behaviour of the paste events.
+ An awaitable task representing the operation
+
+
+
+ Unregister paste events on the source element
+
+ An awaitable Task representing the operation
+
+
+
+ Clears any value set on the source element
+
+ An awaitable Task representing the operation
+
+
+
+ Enumerates the currently selected file references
+
+ An awaitable Task that provides an enumeration of the currently selected file references
+
+
+
+ Provides properties and instance methods for the reading file metadata and aids in the creation of Readonly Stream objects.
+
+
+
+
+ Returns the underlying file object as an
+
+
+
+
+
+ Returns an object url for a file.
+
+
+
+
+
+ Opens a read-only to read the file.
+
+ A read-only to read the file.
+
+
+
+ Opens a read-only base64-encoded string stream to read the file
+
+ A read-only to read the file.
+
+
+
+ Convenience method to read the file fully into memory using a single interop call
+ and returns it as a . Buffer size will be equal to the file size.
+ The length of the resulting will be the same as the file size.
+
+ In most cases the fastest way to read a file into ram, but also the method that uses the most memory.
+ Will use at least twice the file size of memory at the end of the read operation.
+ A representing the full file, with set to 0.
+
+
+
+ Convenience method to read the file fully into memory using a single interop call
+ and returns it as a . Buffer size will be equal to the file size.
+ The length of the resulting will be the same as the file size.
+
+ In most cases the fastest way to read a file into ram, but the most expensive in memory usage.
+ Will use at least twice the file size of memory at the end of the read operation.
+ A representing the full file, with set to 0.
+
+
+
+ Convenience method to read the file fully into memory represented as a , using the specified .
+ The length of the resulting will be the same as the file size.
+
+ A representing the full file, with set to 0.
+
+
+
+ Convenience method to read the file fully into memory represented as a , using the specified .
+ The length of the resulting will be the same as the file size.
+
+ A representing the full file, with set to 0.
+
+
+
+ Reads the file metadata.
+
+ An object containing the file metadata
+
+
+
+ Provides a base64-encoded string view of a sequence of bytes from a file.
+
+
+
+
+ Gets or sets the current byte position in the Stream.
+
+
+
+
+ Gets the length of the stream in bytes.
+
+
+
+
+ Asynchronously reads a sequence of bytes as a base64 encoded string from the current stream
+ and advances the position within the stream by the number of bytes read.
+
+ The byte offset in the source at which to begin reading data from the stream.
+ The maximum number of bytes to read.
+
+ The requested sequence of bytes as a base64 encoded string.
+ The resulting string can be shorter than the number of bytes requested if
+ the number of bytes currently available is less than the requested
+ number, or it can be string.empty if the end of the stream has been reached.
+
+
+
+ Provides properties for file metadata.
+
+
+
+
+ Returns the name of the file referenced by the File object.
+
+
+
+
+ Returns a list of non-standard DOM properties attached to the object, like the webkitRelativePath property.
+
+
+
+
+ Returns the size of the file in bytes.
+
+
+
+
+ Returns the MIME type of the file.
+
+
+
+
+ Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at Midnight).
+
+
+
+
+ Returns the last modified time of the file.
+
+
+
+
+ Gets the relative path including the filename.
+
+ The webkit relative path.
+
+
+
+ Returns information of the position of any stream related to this file.
+
+
+
+
+
+
+
+ Stream that implements
+
+
+
+
+
+
+
+ Provides configuration options for
+
+
+
+
+ Initializes the file service on the first interop call.
+ Redundant for client-side blazor.
+
+
+ Initializing on the first call is neccessary only if the javascript
+ interop file (FileReaderComponent.js)
+ has not been loaded manually using a script tag.
+
+
+
+
+ For client-side blazor, uses shared memory buffer to transfer data quickly.
+ Not available for server-side blazor.
+
+
+
+
+ Activates server-side buffer chunking. Activated if not running on WASM.
+
+
+
+
+ SignalR setting
+
+
+
+
+ Servive for creating a instance from an element.
+
+
+
+
+ Explicitly initializes this instance by loading the neccessary interop code to the browser.
+
+
+
+
+
+ Creates a new instance of for the specified element.
+
+ A reference to an element that can provide file streams.
+ Should be obtained using the @ref attribute.
+ Should reference either an input element of type file or a drop target.
+ a new instance of
+
+
+
+ Represents an object url for a file.
+
+ https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
+
+
+
+ Returns the Object Url.
+
+
+
+
+ Returns true if the application is running on WASM.
+
+
+
+
+ Tries reading HubOptions<ComponentHub>.MaximumReceiveMessageSize using reflection.
+
+
+
+ true if the value could be sucessfully read.
+
+
+
+ Provides extension methods for setting up
+
+
+
+
+ Adds as a scoped service
+ to the specified .
+
+
+
+
+
+ Adds as a scoped service
+ to the specified with the specifed
+
+
+ Delegate that modifies the options for
+
+
+
diff --git a/src/Blazor.FileReader/package.json b/src/Blazor.FileReader/package.json
new file mode 100644
index 0000000..d33970e
--- /dev/null
+++ b/src/Blazor.FileReader/package.json
@@ -0,0 +1,9 @@
+{
+ "version": "1.0.18",
+ "name": "typescript-bundle",
+ "private": false,
+ "dependencies": {
+ "typescript-bundle": "^1.0.18",
+ "typescript": "^4.9.5"
+ }
+}
diff --git a/src/Blazor.FileReader/script/ConcatFileList.ts b/src/Blazor.FileReader/script/ConcatFileList.ts
index db6523a..48df338 100644
--- a/src/Blazor.FileReader/script/ConcatFileList.ts
+++ b/src/Blazor.FileReader/script/ConcatFileList.ts
@@ -12,7 +12,7 @@
this[i] = existing[i];
}
- const eligebleAdditions = [];
+ const eligibleAdditions = [];
// Check for doubles
for (let i = 0; i < additions.length; i++) {
@@ -26,15 +26,15 @@
}
if (!exists) {
- eligebleAdditions[eligebleAdditions.length] = addition;
+ eligibleAdditions[eligibleAdditions.length] = addition;
}
}
- for (let i = 0; i < eligebleAdditions.length; i++) {
- this[i + existing.length] = eligebleAdditions[i];
+ for (let i = 0; i < eligibleAdditions.length; i++) {
+ this[i + existing.length] = eligibleAdditions[i];
}
- this.length = existing.length + eligebleAdditions.length;
+ this.length = existing.length + eligibleAdditions.length;
}
}
diff --git a/src/Blazor.FileReader/script/DragnDrop.ts b/src/Blazor.FileReader/script/DragnDrop.ts
index d2df8a1..ce4deb7 100644
--- a/src/Blazor.FileReader/script/DragnDrop.ts
+++ b/src/Blazor.FileReader/script/DragnDrop.ts
@@ -1,6 +1,7 @@
import { FileReaderComponent } from "./FileReaderComponent"
import { FileReaderJsInterop } from "./FileReaderJsInterop"
import { ConcatFileList } from "./ConcatFileList"
+import { FileEntryList } from "./FileEntryList"
const nameof = (name: keyof T) => name;
const dropEvent = nameof("drop");
@@ -44,15 +45,117 @@ function BuildDragEventHandler(declaredMethod: string, script: string, eventDesc
return (() => { }) as DragEventHandler;
}
+// Go through the data transfer object to pull out the files and folders
+async function getFilesAsync(dataTransfer: DataTransfer): Promise {
+ const files: File[] = [];
+ const len = dataTransfer.items.length;
+ const webkitQueue: FileSystemEntry[] = [];
+ const fileQueue: File[] = [];
+
+ // First must save off all the files
+ for (let i = 0; i < len; i++) {
+ const item = dataTransfer.items[i];
+ if (item.kind === "file") {
+ if (typeof item.webkitGetAsEntry === "function") {
+ const entry = item.webkitGetAsEntry();
+ webkitQueue.push(entry);
+ } else {
+ const file = item.getAsFile();
+ if (file) {
+ fileQueue.push(file);
+ }
+ }
+ }
+ }
+
+ // Get the content for the web kit files
+ for (let i = 0; i < webkitQueue.length; i++) {
+ const entry = webkitQueue[i];
+
+ const entryContent = await readEntryContentAsync(entry);
+ files.push(...entryContent);
+ }
+
+ // Get the content for any other files
+ for (let i = 0; i < fileQueue.length; i++) {
+ const entry = fileQueue[i];
+ files.push(entry);
+ }
+
+ return new FileEntryList(files);;
+}
+
+// Returns a promise with all the files in the directory hierarchy
+async function readEntryContentAsync(entry: FileSystemEntry): Promise {
+ return await new Promise((resolve, reject) => {
+ let reading = 0;
+ const contents: File[] = [];
+
+ return readEntry(entry);
+
+ function readEntry(innerEntry: FileSystemEntry) {
+ if (isFile(innerEntry)) {
+ reading++;
+ let fullPath = innerEntry.fullPath;
+ if (fullPath.charAt(0) === "/" || fullPath.charAt(0) === "\\")
+ fullPath = fullPath.substring(1);
+
+ innerEntry.file(file => {
+ reading--;
+ // overwrite the webkitRelativePath to ensure the correct path is added from the entry.
+ Object.defineProperty(file, "webkitRelativePath",
+ {
+ get() {
+ return fullPath;
+ }
+ });
+ contents.push(file);
+
+ if (reading === 0) {
+ resolve(contents);
+ }
+ });
+ } else if (isDirectory(innerEntry)) {
+ readReaderContent(innerEntry.createReader());
+ }
+ }
+
+ function readReaderContent(reader: FileSystemDirectoryReader) {
+ reading++;
+
+ reader.readEntries(function (entries) {
+ reading--;
+ for (const entry of entries) {
+ readEntry(entry);
+ }
+
+ if (reading === 0) {
+ resolve(contents);
+ }
+ });
+ }
+ });
+}
+
+// for TypeScript typing (type guard function)
+// https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
+function isDirectory(entry: FileSystemEntry): entry is FileSystemDirectoryEntry {
+ return entry.isDirectory;
+}
+
+function isFile(entry: FileSystemEntry): entry is FileSystemFileEntry {
+ return entry.isFile;
+}
+
function RegisterDropEvents(this: FileReaderComponent, element: HTMLElement, registerOptions: DropEventsOptions): boolean {
this.LogIfNull(element);
const onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent);
- const dropHandler = (ev: DragEvent) => {
+ const dropHandler = async (ev: DragEvent) => {
ev.preventDefault();
+
if (ev.target instanceof HTMLElement) {
- let list = ev.dataTransfer.files;
-
+ let list = await getFilesAsync((ev.dataTransfer));
if (registerOptions.additive) {
const existing = this.elementDataTransfers.get(element);
if (existing !== undefined && existing.length > 0) {
diff --git a/src/Blazor.FileReader/script/FileEntryList.ts b/src/Blazor.FileReader/script/FileEntryList.ts
new file mode 100644
index 0000000..2927693
--- /dev/null
+++ b/src/Blazor.FileReader/script/FileEntryList.ts
@@ -0,0 +1,20 @@
+// FileList from File[]
+class FileEntryList implements FileList {
+ [index: number]: File;
+
+ length: number;
+
+ item(index: number): File {
+ return this[index];
+ }
+
+ constructor(additions: File[]) {
+ for (let i = 0; i < additions.length; i++) {
+ this[i] = additions[i];
+ }
+
+ this.length = additions.length;
+ }
+}
+
+export { FileEntryList }
\ No newline at end of file
diff --git a/src/Blazor.FileReader/script/FileReaderComponent.ts b/src/Blazor.FileReader/script/FileReaderComponent.ts
index 5c767f5..365dd89 100644
--- a/src/Blazor.FileReader/script/FileReaderComponent.ts
+++ b/src/Blazor.FileReader/script/FileReaderComponent.ts
@@ -10,10 +10,10 @@ class FileReaderComponent {
private newFileStreamReference = 0;
private readonly fileStreams: { [reference: number]: File } = {};
- protected readonly dragElements: Map = new Map();
- protected readonly pasteElements: Map = new Map();
- protected readonly elementDataTransfers: Map = new Map();
- private readonly readResultByTaskId: Map = new Map();
+ protected readonly dragElements = new Map();
+ protected readonly pasteElements = new Map();
+ protected readonly elementDataTransfers = new Map();
+ private readonly readResultByTaskId = new Map();
protected LogIfNull(element: HTMLElement) {
if (element == null) {
@@ -39,6 +39,7 @@ class FileReaderComponent {
files = dataTransfer;
}
}
+
return files;
}
@@ -69,6 +70,7 @@ class FileReaderComponent {
return 0;
};
+ // Called from cs.
public GetFileInfoFromElement = (element: HTMLElement, index: number): IFileInfo => {
this.LogIfNull(element);
const files = this.GetFiles(element);
@@ -94,8 +96,10 @@ class FileReaderComponent {
name: file.name,
nonStandardProperties: null,
size: file.size,
- type: file.type
+ type: file.type,
+ webkitRelativePath: file.webkitRelativePath,
};
+
const properties: { [propertyName: string]: object } = {};
for (const property in file) {
if (Object.prototype.hasOwnProperty.call(file, property) && !(property in result)) {
@@ -126,7 +130,7 @@ class FileReaderComponent {
FileReaderJsInterop.initialize();
}
- const fileRef: number = this.newFileStreamReference++;
+ const fileRef = this.newFileStreamReference++;
this.fileStreams[fileRef] = file;
return fileRef;
}
@@ -213,8 +217,8 @@ class FileReaderComponent {
return () => {
try {
resolve({result: r.result, file: file });
- } catch (e) {
- reject(e);
+ } catch (ex) {
+ reject(ex);
}
}
})(reader);
diff --git a/src/Blazor.FileReader/script/Interfaces.ts b/src/Blazor.FileReader/script/Interfaces.ts
index 2ab6f2b..17e6519 100644
--- a/src/Blazor.FileReader/script/Interfaces.ts
+++ b/src/Blazor.FileReader/script/Interfaces.ts
@@ -55,6 +55,7 @@ interface IFileInfo {
size: number;
type: string;
lastModified: number;
+ webkitRelativePath: string;
};
interface IDotNetBuffer {
diff --git a/src/Blazor.FileReader/tsconfig.json b/src/Blazor.FileReader/tsconfig.json
index 1e7411e..0d8bb3f 100644
--- a/src/Blazor.FileReader/tsconfig.json
+++ b/src/Blazor.FileReader/tsconfig.json
@@ -5,14 +5,19 @@
"outDir": "wwwroot",
"removeComments": true,
"sourceMap": true,
- "target": "es5",
+ "target": "es6",
"lib": [
"dom",
"es5",
"es6",
+ "es7",
"es2015",
"es2016",
- "es2017"
+ "es2017",
+ "es2018",
+ "es2019",
+ "es2020",
+ "es2021"
]
},
"include": ["**/*.ts"],
diff --git a/src/Blazor.FileReader/wwwroot/FileReaderComponent.js b/src/Blazor.FileReader/wwwroot/FileReaderComponent.js
index 29c39d8..6b01694 100644
--- a/src/Blazor.FileReader/wwwroot/FileReaderComponent.js
+++ b/src/Blazor.FileReader/wwwroot/FileReaderComponent.js
@@ -1,424 +1,494 @@
-(function() { var module = (function () {
- var defines = {};
- var entry = [null];
+(function() { var module = (() => {
+ const defines = {};
+ const entry = [null];
function define(name, dependencies, factory) {
- defines[name] = { dependencies: dependencies, factory: factory };
+ defines[name] = { dependencies, factory };
entry[0] = name;
}
- define("require", ["exports"], function (exports) {
+ define("require", ["exports"], (exports) => {
Object.defineProperty(exports, "__cjsModule", { value: true });
- Object.defineProperty(exports, "default", { value: function (name) { return resolve(name); } });
+ Object.defineProperty(exports, "default", { value: (name) => resolve(name) });
});
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- var __generator = (this && this.__generator) || function (thisArg, body) {
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
- function verb(n) { return function (v) { return step([n, v]); }; }
- function step(op) {
- if (f) throw new TypeError("Generator is already executing.");
- while (_) try {
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
- if (y = 0, t) op = [op[0] & 2, t.value];
- switch (op[0]) {
- case 0: case 1: t = op; break;
- case 4: _.label++; return { value: op[1], done: false };
- case 5: _.label++; y = op[1]; op = [0]; continue;
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
- default:
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
- if (t[2]) _.ops.pop();
- _.trys.pop(); continue;
- }
- op = body.call(thisArg, _);
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
- }
- };
- define("FileReaderJsInterop", ["require", "exports"], function (require, exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var FileReaderJsInterop = (function () {
- function FileReaderJsInterop() {
- }
- FileReaderJsInterop.initialize = function () {
- FileReaderJsInterop.endTask =
- Module.mono_bind_static_method("[" + this.assembly + "] Tewr.Blazor.FileReader.FileReaderJsInterop:EndTask");
- FileReaderJsInterop.initialized = true;
- };
- FileReaderJsInterop.assembly = 'Tewr.Blazor.FileReader';
- FileReaderJsInterop.initialized = false;
- return FileReaderJsInterop;
- }());
- exports.FileReaderJsInterop = FileReaderJsInterop;
- });
- define("ConcatFileList", ["require", "exports"], function (require, exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var ConcatFileList = (function () {
- function ConcatFileList(existing, additions) {
- for (var i = 0; i < existing.length; i++) {
- this[i] = existing[i];
- }
- var eligebleAdditions = [];
- for (var i = 0; i < additions.length; i++) {
- var exists = false;
- var addition = additions[i];
- for (var j = 0; j < existing.length; j++) {
- if (existing[j] === addition) {
- exists = true;
- break;
- }
- }
- if (!exists) {
- eligebleAdditions[eligebleAdditions.length] = addition;
- }
- }
- for (var i = 0; i < eligebleAdditions.length; i++) {
- this[i + existing.length] = eligebleAdditions[i];
- }
- this.length = existing.length + eligebleAdditions.length;
- }
- ConcatFileList.prototype.item = function (index) {
- return this[index];
- };
- return ConcatFileList;
- }());
- exports.ConcatFileList = ConcatFileList;
- });
- define("DragnDrop", ["require", "exports", "FileReaderJsInterop", "ConcatFileList"], function (require, exports, FileReaderJsInterop_1, ConcatFileList_1) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var nameof = function (name) { return name; };
- var dropEvent = nameof("drop");
- var dragOverEvent = nameof("dragover");
- function BuildDragEventHandler(declaredMethod, script, eventDescription) {
- var declaredHandler;
- if (declaredMethod) {
- if (!window.hasOwnProperty(declaredMethod) || typeof window[declaredMethod] !== 'function') {
- throw (FileReaderJsInterop_1.FileReaderJsInterop.assembly + ": BuildDragEventHandler: window." + declaredMethod + " was provided as an option for event '" + eventDescription + "', but was not declared or was not a function. Make sure your script that defines this method is loaded before calling RegisterDropEvents.");
- }
- else {
- declaredHandler = window[declaredMethod];
- }
- }
- if (script) {
- var scriptHandler_1 = Function("return " + script)();
- if (!scriptHandler_1 || typeof scriptHandler_1 !== 'function') {
- throw (FileReaderJsInterop_1.FileReaderJsInterop.assembly + ": BuildDragEventHandler: script was provided as an option for event '" + eventDescription + "', but was not properly declared or was not a function.");
- }
- else {
- if (!declaredHandler) {
- return scriptHandler_1;
- }
- return function (dragEvent, element, fileReaderComponent) {
- declaredHandler(dragEvent, element, fileReaderComponent);
- scriptHandler_1(dragEvent, element, fileReaderComponent);
- };
- }
- }
- if (declaredHandler) {
- return declaredHandler;
- }
- return (function () { });
- }
- exports.BuildDragEventHandler = BuildDragEventHandler;
- function RegisterDropEvents(element, registerOptions) {
- var _this = this;
- this.LogIfNull(element);
- var onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent);
- var dropHandler = function (ev) {
- ev.preventDefault();
- if (ev.target instanceof HTMLElement) {
- var list = ev.dataTransfer.files;
- if (registerOptions.additive) {
- var existing = _this.elementDataTransfers.get(element);
- if (existing !== undefined && existing.length > 0) {
- list = new ConcatFileList_1.ConcatFileList(existing, list);
- }
- }
- _this.elementDataTransfers.set(element, list);
- }
- onAfterDropHandler(ev, element, _this);
- };
- var onAfterDragOverHandler = BuildDragEventHandler(registerOptions.onDragOverMethod, registerOptions.onDragOverScript, dragOverEvent);
- var dragOverHandler = function (ev) {
- ev.preventDefault();
- onAfterDragOverHandler(ev, element, _this);
- };
- var onAfterRegisterHandler = BuildDragEventHandler(registerOptions.onRegisterDropEventsMethod, registerOptions.onRegisterDropEventsScript, 'RegisterDropEvents');
- var eventHandlers = { drop: dropHandler, dragover: dragOverHandler };
- this.dragElements.set(element, eventHandlers);
- element.addEventListener(dropEvent, eventHandlers.drop);
- element.addEventListener(dragOverEvent, eventHandlers.dragover);
- onAfterRegisterHandler(null, element, this);
- return true;
- }
- exports.RegisterDropEvents = RegisterDropEvents;
- function UnregisterDropEvents(element) {
- this.LogIfNull(element);
- var eventHandlers = this.dragElements.get(element);
- if (eventHandlers) {
- element.removeEventListener(dropEvent, eventHandlers.drop);
- element.removeEventListener(dragOverEvent, eventHandlers.dragover);
- }
- this.elementDataTransfers.delete(element);
- this.dragElements.delete(element);
- return true;
- }
- exports.UnregisterDropEvents = UnregisterDropEvents;
- });
- define("FileReaderComponent", ["require", "exports", "DragnDrop", "Clipboard", "FileReaderJsInterop"], function (require, exports, DragnDrop_1, Clipboard_1, FileReaderJsInterop_2) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var FileReaderComponent = (function () {
- function FileReaderComponent() {
- var _this = this;
- this.newFileStreamReference = 0;
- this.fileStreams = {};
- this.dragElements = new Map();
- this.pasteElements = new Map();
- this.elementDataTransfers = new Map();
- this.readResultByTaskId = new Map();
- this.RegisterDropEvents = DragnDrop_1.RegisterDropEvents;
- this.UnregisterDropEvents = DragnDrop_1.UnregisterDropEvents;
- this.RegisterPasteEvent = Clipboard_1.RegisterPasteEvent;
- this.UnregisterPasteEvent = Clipboard_1.UnregisterPasteEvent;
- this.GetFileCount = function (element) {
- _this.LogIfNull(element);
- var files = _this.GetFiles(element);
- if (!files) {
- return -1;
- }
- var result = files.length;
- return result;
- };
- this.ClearValue = function (element) {
- _this.LogIfNull(element);
- if (element instanceof HTMLInputElement) {
- element.value = null;
- }
- else {
- _this.elementDataTransfers.delete(element);
- }
- return 0;
- };
- this.GetFileInfoFromElement = function (element, index) {
- _this.LogIfNull(element);
- var files = _this.GetFiles(element);
- if (!files) {
- return null;
- }
- var file = files.item(index);
- if (!file) {
- return null;
- }
- return _this.GetFileInfoFromFile(file);
- };
- this.Dispose = function (fileRef) {
- return delete (_this.fileStreams[fileRef]);
- };
- this.OpenRead = function (element, fileIndex, useWasmSharedBuffer) {
- _this.LogIfNull(element);
- var files = _this.GetFiles(element);
- if (!files) {
- throw 'No FileList available.';
- }
- var file = files.item(fileIndex);
- if (!file) {
- throw "No file with index " + fileIndex + " available.";
- }
- return _this.OpenReadFile(file, useWasmSharedBuffer);
- };
- this.OpenReadFile = function (file, useWasmSharedBuffer) {
- if (useWasmSharedBuffer && !FileReaderJsInterop_2.FileReaderJsInterop.initialized) {
- FileReaderJsInterop_2.FileReaderJsInterop.initialize();
- }
- var fileRef = _this.newFileStreamReference++;
- _this.fileStreams[fileRef] = file;
- return fileRef;
- };
- this.ReadFileParamsPointer = function (readFileParamsPointer) {
- return {
- taskId: Blazor.platform.readUint64Field(readFileParamsPointer, 0),
- bufferOffset: Blazor.platform.readUint64Field(readFileParamsPointer, 8),
- count: Blazor.platform.readInt32Field(readFileParamsPointer, 16),
- fileRef: Blazor.platform.readInt32Field(readFileParamsPointer, 20),
- position: Blazor.platform.readUint64Field(readFileParamsPointer, 24)
- };
- };
- this.ReadBufferPointer = function (readBufferPointer) {
- return {
- taskId: Blazor.platform.readUint64Field(readBufferPointer, 0),
- buffer: Blazor.platform.readInt32Field(readBufferPointer, 8)
- };
- };
- this.ReadFileUnmarshalledAsync = function (readFileParamsPointer) {
- var readFileParams = _this.ReadFileParamsPointer(readFileParamsPointer);
- var asyncCall = new Promise(function (resolve, reject) {
- return _this.ReadFileSlice(readFileParams, function (r, b) { return r.readAsArrayBuffer(b); })
- .then(function (r) {
- _this.readResultByTaskId.set(readFileParams.taskId, {
- arrayBuffer: r.result,
- params: readFileParams
- });
- resolve();
- }, function (e) { return reject(e); });
- });
- asyncCall.then(function () { return FileReaderJsInterop_2.FileReaderJsInterop.endTask(readFileParams.taskId); }, function (error) {
- console.error("ReadFileUnmarshalledAsync error", error);
- DotNet.invokeMethodAsync(FileReaderJsInterop_2.FileReaderJsInterop.assembly, "EndReadFileUnmarshalledAsyncError", readFileParams.taskId, error.toString());
- });
- return 0;
- };
- this.FillBufferUnmarshalled = function (bufferPointer) {
- var readBufferParams = _this.ReadBufferPointer(bufferPointer);
- var dotNetBufferView = Blazor.platform.toUint8Array(readBufferParams.buffer);
- var data = _this.readResultByTaskId.get(readBufferParams.taskId);
- _this.readResultByTaskId.delete(readBufferParams.taskId);
- dotNetBufferView.set(new Uint8Array(data.arrayBuffer), data.params.bufferOffset);
- var byteCount = Math.min(data.arrayBuffer.byteLength, data.params.count);
- return byteCount;
- };
- this.ReadFileMarshalledAsync = function (readFileParams) {
- return new Promise(function (resolve, reject) {
- return _this.ReadFileSlice(readFileParams, function (r, b) { return r.readAsDataURL(b); })
- .then(function (r) {
- var contents = r.result;
- var data = contents ? contents.split(";base64,")[1] : null;
- resolve(data);
- }, function (e) { return reject(e); });
- });
- };
- this.ReadFileSlice = function (readFileParams, method) {
- return new Promise(function (resolve, reject) {
- var file = _this.fileStreams[readFileParams.fileRef];
- try {
- var reader = new FileReader();
- reader.onload = (function (r) {
- return function () {
- try {
- resolve({ result: r.result, file: file });
- }
- catch (e) {
- reject(e);
- }
- };
- })(reader);
- method(reader, file.slice(readFileParams.position, readFileParams.position + readFileParams.count));
- }
- catch (e) {
- reject(e);
- }
- });
- };
- }
- FileReaderComponent.prototype.LogIfNull = function (element) {
- if (element == null) {
- console.log(FileReaderJsInterop_2.FileReaderJsInterop.assembly + ": HTMLElement is null. Can't access IFileReaderRef after HTMLElement was removed from DOM.");
- }
- };
- FileReaderComponent.prototype.GetFiles = function (element) {
- var files = null;
- if (element instanceof HTMLInputElement) {
- files = element.files;
- }
- else {
- var dataTransfer = this.elementDataTransfers.get(element);
- if (dataTransfer) {
- files = dataTransfer;
- }
- }
- return files;
- };
- FileReaderComponent.prototype.GetJSObjectReference = function (element, fileIndex) {
- this.LogIfNull(element);
- var files = this.GetFiles(element);
- return files.item(fileIndex);
- };
- FileReaderComponent.prototype.GetFileInfoFromFile = function (file) {
- var result = {
- lastModified: file.lastModified,
- name: file.name,
- nonStandardProperties: null,
- size: file.size,
- type: file.type
- };
- var properties = {};
- for (var property in file) {
- if (Object.prototype.hasOwnProperty.call(file, property) && !(property in result)) {
- properties[property] = file[property];
- }
- }
- result.nonStandardProperties = properties;
- return result;
- };
- FileReaderComponent.prototype.ReadFileSliceAsync = function (fileRef, position, count) {
- return __awaiter(this, void 0, void 0, function () {
- var file, slice;
- return __generator(this, function (_a) {
- file = this.fileStreams[fileRef];
- slice = file.slice(position, position + count);
- return [2, slice];
- });
- });
- };
- return FileReaderComponent;
- }());
- exports.FileReaderComponent = FileReaderComponent;
- var FileReaderComponentInstance = new FileReaderComponent();
- exports.FileReaderComponentInstance = FileReaderComponentInstance;
- });
- define("Clipboard", ["require", "exports", "ConcatFileList"], function (require, exports, ConcatFileList_2) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- function RegisterPasteEvent(element, registerOptions) {
- var _this = this;
- this.LogIfNull(element);
- var pasteHandler = function (ev) {
- if (ev.target instanceof HTMLElement) {
- var list = ev.clipboardData.files;
- if (list.length > 0) {
- ev.preventDefault();
- if (registerOptions.additive) {
- var existing = _this.elementDataTransfers.get(element);
- if (existing !== undefined && existing.length > 0) {
- list = new ConcatFileList_2.ConcatFileList(existing, list);
- }
- }
- }
- _this.elementDataTransfers.set(element, list);
- }
- };
- this.pasteElements.set(element, pasteHandler);
- element.addEventListener("paste", pasteHandler);
- return true;
- }
- exports.RegisterPasteEvent = RegisterPasteEvent;
- function UnregisterPasteEvent(element) {
- this.LogIfNull(element);
- var eventHandler = this.pasteElements.get(element);
- if (eventHandler) {
- element.removeEventListener("paste", eventHandler);
- }
- this.elementDataTransfers.delete(element);
- this.pasteElements.delete(element);
- return true;
- }
- exports.UnregisterPasteEvent = UnregisterPasteEvent;
- });
- ;
- ;
- ;
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ };
+ define("FileReaderJsInterop", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.FileReaderJsInterop = void 0;
+ class FileReaderJsInterop {
+ static initialize() {
+ FileReaderJsInterop.endTask =
+ Module.mono_bind_static_method(`[${this.assembly}] Tewr.Blazor.FileReader.FileReaderJsInterop:EndTask`);
+ FileReaderJsInterop.initialized = true;
+ }
+ }
+ exports.FileReaderJsInterop = FileReaderJsInterop;
+ FileReaderJsInterop.assembly = 'Tewr.Blazor.FileReader';
+ FileReaderJsInterop.initialized = false;
+ });
+ define("ConcatFileList", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.ConcatFileList = void 0;
+ class ConcatFileList {
+ item(index) {
+ return this[index];
+ }
+ constructor(existing, additions) {
+ for (let i = 0; i < existing.length; i++) {
+ this[i] = existing[i];
+ }
+ const eligibleAdditions = [];
+ for (let i = 0; i < additions.length; i++) {
+ let exists = false;
+ const addition = additions[i];
+ for (let j = 0; j < existing.length; j++) {
+ if (existing[j] === addition) {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists) {
+ eligibleAdditions[eligibleAdditions.length] = addition;
+ }
+ }
+ for (let i = 0; i < eligibleAdditions.length; i++) {
+ this[i + existing.length] = eligibleAdditions[i];
+ }
+ this.length = existing.length + eligibleAdditions.length;
+ }
+ }
+ exports.ConcatFileList = ConcatFileList;
+ });
+ define("FileEntryList", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.FileEntryList = void 0;
+ class FileEntryList {
+ item(index) {
+ return this[index];
+ }
+ constructor(additions) {
+ for (let i = 0; i < additions.length; i++) {
+ this[i] = additions[i];
+ }
+ this.length = additions.length;
+ }
+ }
+ exports.FileEntryList = FileEntryList;
+ });
+ define("DragnDrop", ["require", "exports", "FileReaderJsInterop", "ConcatFileList", "FileEntryList"], function (require, exports, FileReaderJsInterop_1, ConcatFileList_1, FileEntryList_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.UnregisterDropEvents = exports.RegisterDropEvents = exports.BuildDragEventHandler = void 0;
+ const nameof = (name) => name;
+ const dropEvent = nameof("drop");
+ const dragOverEvent = nameof("dragover");
+ function BuildDragEventHandler(declaredMethod, script, eventDescription) {
+ let declaredHandler;
+ if (declaredMethod) {
+ if (!window.hasOwnProperty(declaredMethod) || typeof window[declaredMethod] !== 'function') {
+ throw (`${FileReaderJsInterop_1.FileReaderJsInterop.assembly}: BuildDragEventHandler: window.${declaredMethod} was provided as an option for event '${eventDescription}', but was not declared or was not a function. Make sure your script that defines this method is loaded before calling RegisterDropEvents.`);
+ }
+ else {
+ declaredHandler = window[declaredMethod];
+ }
+ }
+ if (script) {
+ const scriptHandler = Function(`return ${script}`)();
+ if (!scriptHandler || typeof scriptHandler !== 'function') {
+ throw (`${FileReaderJsInterop_1.FileReaderJsInterop.assembly}: BuildDragEventHandler: script was provided as an option for event '${eventDescription}', but was not properly declared or was not a function.`);
+ }
+ else {
+ if (!declaredHandler) {
+ return scriptHandler;
+ }
+ return (dragEvent, element, fileReaderComponent) => {
+ declaredHandler(dragEvent, element, fileReaderComponent);
+ scriptHandler(dragEvent, element, fileReaderComponent);
+ };
+ }
+ }
+ if (declaredHandler) {
+ return declaredHandler;
+ }
+ return (() => { });
+ }
+ exports.BuildDragEventHandler = BuildDragEventHandler;
+ function getFilesAsync(dataTransfer) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const files = [];
+ const len = dataTransfer.items.length;
+ const webkitQueue = [];
+ const fileQueue = [];
+ for (let i = 0; i < len; i++) {
+ const item = dataTransfer.items[i];
+ if (item.kind === "file") {
+ if (typeof item.webkitGetAsEntry === "function") {
+ const entry = item.webkitGetAsEntry();
+ webkitQueue.push(entry);
+ }
+ else {
+ const file = item.getAsFile();
+ if (file) {
+ fileQueue.push(file);
+ }
+ }
+ }
+ }
+ for (let i = 0; i < webkitQueue.length; i++) {
+ const entry = webkitQueue[i];
+ const entryContent = yield readEntryContentAsync(entry);
+ files.push(...entryContent);
+ }
+ for (let i = 0; i < fileQueue.length; i++) {
+ const entry = fileQueue[i];
+ files.push(entry);
+ }
+ return new FileEntryList_1.FileEntryList(files);
+ ;
+ });
+ }
+ function readEntryContentAsync(entry) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return yield new Promise((resolve, reject) => {
+ let reading = 0;
+ const contents = [];
+ return readEntry(entry);
+ function readEntry(innerEntry) {
+ if (isFile(innerEntry)) {
+ reading++;
+ let fullPath = innerEntry.fullPath;
+ if (fullPath.charAt(0) === "/" || fullPath.charAt(0) === "\\")
+ fullPath = fullPath.substring(1);
+ innerEntry.file(file => {
+ reading--;
+ Object.defineProperty(file, "webkitRelativePath", {
+ get() {
+ return fullPath;
+ }
+ });
+ contents.push(file);
+ if (reading === 0) {
+ resolve(contents);
+ }
+ });
+ }
+ else if (isDirectory(innerEntry)) {
+ readReaderContent(innerEntry.createReader());
+ }
+ }
+ function readReaderContent(reader) {
+ reading++;
+ reader.readEntries(function (entries) {
+ reading--;
+ for (const entry of entries) {
+ readEntry(entry);
+ }
+ if (reading === 0) {
+ resolve(contents);
+ }
+ });
+ }
+ });
+ });
+ }
+ function isDirectory(entry) {
+ return entry.isDirectory;
+ }
+ function isFile(entry) {
+ return entry.isFile;
+ }
+ function RegisterDropEvents(element, registerOptions) {
+ this.LogIfNull(element);
+ const onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent);
+ const dropHandler = (ev) => __awaiter(this, void 0, void 0, function* () {
+ ev.preventDefault();
+ if (ev.target instanceof HTMLElement) {
+ let list = yield getFilesAsync((ev.dataTransfer));
+ if (registerOptions.additive) {
+ const existing = this.elementDataTransfers.get(element);
+ if (existing !== undefined && existing.length > 0) {
+ list = new ConcatFileList_1.ConcatFileList(existing, list);
+ }
+ }
+ this.elementDataTransfers.set(element, list);
+ }
+ onAfterDropHandler(ev, element, this);
+ });
+ const onAfterDragOverHandler = BuildDragEventHandler(registerOptions.onDragOverMethod, registerOptions.onDragOverScript, dragOverEvent);
+ const dragOverHandler = (ev) => {
+ ev.preventDefault();
+ onAfterDragOverHandler(ev, element, this);
+ };
+ const onAfterRegisterHandler = BuildDragEventHandler(registerOptions.onRegisterDropEventsMethod, registerOptions.onRegisterDropEventsScript, 'RegisterDropEvents');
+ const eventHandlers = { drop: dropHandler, dragover: dragOverHandler };
+ this.dragElements.set(element, eventHandlers);
+ element.addEventListener(dropEvent, eventHandlers.drop);
+ element.addEventListener(dragOverEvent, eventHandlers.dragover);
+ onAfterRegisterHandler(null, element, this);
+ return true;
+ }
+ exports.RegisterDropEvents = RegisterDropEvents;
+ function UnregisterDropEvents(element) {
+ this.LogIfNull(element);
+ const eventHandlers = this.dragElements.get(element);
+ if (eventHandlers) {
+ element.removeEventListener(dropEvent, eventHandlers.drop);
+ element.removeEventListener(dragOverEvent, eventHandlers.dragover);
+ }
+ this.elementDataTransfers.delete(element);
+ this.dragElements.delete(element);
+ return true;
+ }
+ exports.UnregisterDropEvents = UnregisterDropEvents;
+ });
+ define("FileReaderComponent", ["require", "exports", "DragnDrop", "Clipboard", "FileReaderJsInterop"], function (require, exports, DragnDrop_1, Clipboard_1, FileReaderJsInterop_2) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.FileReaderComponentInstance = exports.FileReaderComponent = void 0;
+ class FileReaderComponent {
+ constructor() {
+ this.newFileStreamReference = 0;
+ this.fileStreams = {};
+ this.dragElements = new Map();
+ this.pasteElements = new Map();
+ this.elementDataTransfers = new Map();
+ this.readResultByTaskId = new Map();
+ this.RegisterDropEvents = DragnDrop_1.RegisterDropEvents;
+ this.UnregisterDropEvents = DragnDrop_1.UnregisterDropEvents;
+ this.RegisterPasteEvent = Clipboard_1.RegisterPasteEvent;
+ this.UnregisterPasteEvent = Clipboard_1.UnregisterPasteEvent;
+ this.GetFileCount = (element) => {
+ this.LogIfNull(element);
+ const files = this.GetFiles(element);
+ if (!files) {
+ return -1;
+ }
+ const result = files.length;
+ return result;
+ };
+ this.ClearValue = (element) => {
+ this.LogIfNull(element);
+ if (element instanceof HTMLInputElement) {
+ element.value = null;
+ }
+ else {
+ this.elementDataTransfers.delete(element);
+ }
+ return 0;
+ };
+ this.GetFileInfoFromElement = (element, index) => {
+ this.LogIfNull(element);
+ const files = this.GetFiles(element);
+ if (!files) {
+ return null;
+ }
+ const file = files.item(index);
+ if (!file) {
+ return null;
+ }
+ return this.GetFileInfoFromFile(file);
+ };
+ this.Dispose = (fileRef) => {
+ return delete (this.fileStreams[fileRef]);
+ };
+ this.OpenRead = (element, fileIndex, useWasmSharedBuffer) => {
+ this.LogIfNull(element);
+ const files = this.GetFiles(element);
+ if (!files) {
+ throw 'No FileList available.';
+ }
+ const file = files.item(fileIndex);
+ if (!file) {
+ throw `No file with index ${fileIndex} available.`;
+ }
+ return this.OpenReadFile(file, useWasmSharedBuffer);
+ };
+ this.OpenReadFile = (file, useWasmSharedBuffer) => {
+ if (useWasmSharedBuffer && !FileReaderJsInterop_2.FileReaderJsInterop.initialized) {
+ FileReaderJsInterop_2.FileReaderJsInterop.initialize();
+ }
+ const fileRef = this.newFileStreamReference++;
+ this.fileStreams[fileRef] = file;
+ return fileRef;
+ };
+ this.ReadFileParamsPointer = (readFileParamsPointer) => {
+ return {
+ taskId: Blazor.platform.readUint64Field(readFileParamsPointer, 0),
+ bufferOffset: Blazor.platform.readUint64Field(readFileParamsPointer, 8),
+ count: Blazor.platform.readInt32Field(readFileParamsPointer, 16),
+ fileRef: Blazor.platform.readInt32Field(readFileParamsPointer, 20),
+ position: Blazor.platform.readUint64Field(readFileParamsPointer, 24)
+ };
+ };
+ this.ReadBufferPointer = (readBufferPointer) => {
+ return {
+ taskId: Blazor.platform.readUint64Field(readBufferPointer, 0),
+ buffer: Blazor.platform.readInt32Field(readBufferPointer, 8)
+ };
+ };
+ this.ReadFileUnmarshalledAsync = (readFileParamsPointer) => {
+ const readFileParams = this.ReadFileParamsPointer(readFileParamsPointer);
+ const asyncCall = new Promise((resolve, reject) => {
+ return this.ReadFileSlice(readFileParams, (r, b) => r.readAsArrayBuffer(b))
+ .then(r => {
+ this.readResultByTaskId.set(readFileParams.taskId, {
+ arrayBuffer: r.result,
+ params: readFileParams
+ });
+ resolve();
+ }, e => reject(e));
+ });
+ asyncCall.then(() => FileReaderJsInterop_2.FileReaderJsInterop.endTask(readFileParams.taskId), error => {
+ console.error("ReadFileUnmarshalledAsync error", error);
+ DotNet.invokeMethodAsync(FileReaderJsInterop_2.FileReaderJsInterop.assembly, "EndReadFileUnmarshalledAsyncError", readFileParams.taskId, error.toString());
+ });
+ return 0;
+ };
+ this.FillBufferUnmarshalled = (bufferPointer) => {
+ const readBufferParams = this.ReadBufferPointer(bufferPointer);
+ const dotNetBufferView = Blazor.platform.toUint8Array(readBufferParams.buffer);
+ const data = this.readResultByTaskId.get(readBufferParams.taskId);
+ this.readResultByTaskId.delete(readBufferParams.taskId);
+ dotNetBufferView.set(new Uint8Array(data.arrayBuffer), data.params.bufferOffset);
+ const byteCount = Math.min(data.arrayBuffer.byteLength, data.params.count);
+ return byteCount;
+ };
+ this.ReadFileMarshalledAsync = (readFileParams) => {
+ return new Promise((resolve, reject) => {
+ return this.ReadFileSlice(readFileParams, (r, b) => r.readAsDataURL(b))
+ .then(r => {
+ const contents = r.result;
+ const data = contents ? contents.split(";base64,")[1] : null;
+ resolve(data);
+ }, e => reject(e));
+ });
+ };
+ this.ReadFileSlice = (readFileParams, method) => {
+ return new Promise((resolve, reject) => {
+ const file = this.fileStreams[readFileParams.fileRef];
+ try {
+ const reader = new FileReader();
+ reader.onload = ((r) => {
+ return () => {
+ try {
+ resolve({ result: r.result, file: file });
+ }
+ catch (ex) {
+ reject(ex);
+ }
+ };
+ })(reader);
+ method(reader, file.slice(readFileParams.position, readFileParams.position + readFileParams.count));
+ }
+ catch (e) {
+ reject(e);
+ }
+ });
+ };
+ }
+ LogIfNull(element) {
+ if (element == null) {
+ console.log(`${FileReaderJsInterop_2.FileReaderJsInterop.assembly}: HTMLElement is null. Can't access IFileReaderRef after HTMLElement was removed from DOM.`);
+ }
+ }
+ GetFiles(element) {
+ let files = null;
+ if (element instanceof HTMLInputElement) {
+ files = element.files;
+ }
+ else {
+ const dataTransfer = this.elementDataTransfers.get(element);
+ if (dataTransfer) {
+ files = dataTransfer;
+ }
+ }
+ return files;
+ }
+ GetJSObjectReference(element, fileIndex) {
+ this.LogIfNull(element);
+ const files = this.GetFiles(element);
+ return files.item(fileIndex);
+ }
+ GetFileInfoFromFile(file) {
+ const result = {
+ lastModified: file.lastModified,
+ name: file.name,
+ nonStandardProperties: null,
+ size: file.size,
+ type: file.type,
+ webkitRelativePath: file.webkitRelativePath,
+ };
+ const properties = {};
+ for (const property in file) {
+ if (Object.prototype.hasOwnProperty.call(file, property) && !(property in result)) {
+ properties[property] = file[property];
+ }
+ }
+ result.nonStandardProperties = properties;
+ return result;
+ }
+ ReadFileSliceAsync(fileRef, position, count) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const file = this.fileStreams[fileRef];
+ const slice = file.slice(position, position + count);
+ return slice;
+ });
+ }
+ }
+ exports.FileReaderComponent = FileReaderComponent;
+ const FileReaderComponentInstance = new FileReaderComponent();
+ exports.FileReaderComponentInstance = FileReaderComponentInstance;
+ });
+ define("Clipboard", ["require", "exports", "ConcatFileList"], function (require, exports, ConcatFileList_2) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.UnregisterPasteEvent = exports.RegisterPasteEvent = void 0;
+ function RegisterPasteEvent(element, registerOptions) {
+ this.LogIfNull(element);
+ const pasteHandler = (ev) => {
+ if (ev.target instanceof HTMLElement) {
+ let list = ev.clipboardData.files;
+ if (list.length > 0) {
+ ev.preventDefault();
+ if (registerOptions.additive) {
+ const existing = this.elementDataTransfers.get(element);
+ if (existing !== undefined && existing.length > 0) {
+ list = new ConcatFileList_2.ConcatFileList(existing, list);
+ }
+ }
+ }
+ this.elementDataTransfers.set(element, list);
+ }
+ };
+ this.pasteElements.set(element, pasteHandler);
+ element.addEventListener("paste", pasteHandler);
+ return true;
+ }
+ exports.RegisterPasteEvent = RegisterPasteEvent;
+ function UnregisterPasteEvent(element) {
+ this.LogIfNull(element);
+ const eventHandler = this.pasteElements.get(element);
+ if (eventHandler) {
+ element.removeEventListener("paste", eventHandler);
+ }
+ this.elementDataTransfers.delete(element);
+ this.pasteElements.delete(element);
+ return true;
+ }
+ exports.UnregisterPasteEvent = UnregisterPasteEvent;
+ });
+ ;
+ ;
+ ;
'marker:resolver';
@@ -430,8 +500,8 @@
return defines[name + '/index'];
}
else {
- var dependencies = ['exports'];
- var factory = function (exports) {
+ const dependencies = ['exports'];
+ const factory = (exports) => {
try {
Object.defineProperty(exports, "__cjsModule", { value: true });
Object.defineProperty(exports, "default", { value: require(name) });
@@ -440,10 +510,10 @@
throw Error(['module "', name, '" not found.'].join(''));
}
};
- return { dependencies: dependencies, factory: factory };
+ return { dependencies, factory };
}
}
- var instances = {};
+ const instances = {};
function resolve(name) {
if (instances[name]) {
return instances[name];
@@ -451,11 +521,14 @@
if (name === 'exports') {
return {};
}
- var define = get_define(name);
+ const define = get_define(name);
+ if (typeof define.factory !== 'function') {
+ return define.factory;
+ }
instances[name] = {};
- var dependencies = define.dependencies.map(function (name) { return resolve(name); });
- define.factory.apply(define, dependencies);
- var exports = dependencies[define.dependencies.indexOf('exports')];
+ const dependencies = define.dependencies.map(name => resolve(name));
+ define.factory(...dependencies);
+ const exports = dependencies[define.dependencies.indexOf('exports')];
instances[name] = (exports['__cjsModule']) ? exports.default : exports;
return instances[name];
}
diff --git a/src/Blazor.FileReader/wwwroot/FileReaderComponent.js.map b/src/Blazor.FileReader/wwwroot/FileReaderComponent.js.map
index 6d10683..4b03747 100644
--- a/src/Blazor.FileReader/wwwroot/FileReaderComponent.js.map
+++ b/src/Blazor.FileReader/wwwroot/FileReaderComponent.js.map
@@ -1 +1 @@
-{"version":3,"file":"FileReaderComponent.js","sourceRoot":"","sources":["../script/FileReaderJsInterop.ts","../script/ConcatFileList.ts","../script/DragnDrop.ts","../script/FileReaderComponent.ts","../script/Clipboard.ts","../script/Interfaces.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"FileReaderComponent.js","sourceRoot":"","sources":["../script/FileReaderJsInterop.ts","../script/ConcatFileList.ts","../script/FileEntryList.ts","../script/DragnDrop.ts","../script/FileReaderComponent.ts","../script/Clipboard.ts","../script/Interfaces.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor
index 7b02307..c9adaeb 100644
--- a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor
+++ b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor
@@ -1,4 +1,5 @@
@using System.IO;
+@using System.Threading
@inject IFileReaderService fileReaderService;