From 0374882e666de7fc2b537aeea3c6cba1678ffab6 Mon Sep 17 00:00:00 2001 From: Christopher Winland Date: Mon, 5 Jun 2023 09:46:04 -0400 Subject: [PATCH] Add webkitRelativePath to dragdrop with multiple folders (#190) * File folder path drag drop (#1) * . * Add TypeScript MSBuild * Add Check in GetFiles for missing files. Get from dragdrop instead. * Update Demos * Use native input functionality for drag / drop. Add option to switch between using webkitdirectory. Use div / ondrop to drop multiple folders and files. * Move property to non standard properties * Update Demo * Fix/Cleanup * Fix async issue * remove try catches not needed and rethrow others --- .gitignore | 2 + .../Blazor.FileReader.csproj | 182 ++-- src/Blazor.FileReader/FileReaderRef.cs | 823 ++++++++-------- .../Tewr.Blazor.FileReader.xml | 928 +++++++++--------- src/Blazor.FileReader/package.json | 9 + .../script/ConcatFileList.ts | 10 +- src/Blazor.FileReader/script/DragnDrop.ts | 112 ++- src/Blazor.FileReader/script/FileEntryList.ts | 20 + .../script/FileReaderComponent.ts | 24 +- src/Blazor.FileReader/script/Interfaces.ts | 3 +- src/Blazor.FileReader/tsconfig.json | 9 +- .../wwwroot/FileReaderComponent.js | 462 +++++---- .../wwwroot/FileReaderComponent.js.map | 2 +- .../DragnDropCommon.razor | 129 +-- .../DragnDropDivCommon.razor | 40 +- .../DragnDropInputCommon.razor | 47 +- .../Pages/_Host.cshtml | 5 +- .../appsettings.Development.json | 5 +- .../wwwroot/animated-icon.svg | 24 + .../wwwroot/index.html | 2 +- .../Pages/_Host.cshtml | 2 +- .../appsettings.Development.json | 5 +- .../wwwroot/animated-icon.svg | 24 + .../wwwroot/index.html | 2 +- .../Pages/_Layout.cshtml | 2 +- .../appsettings.Development.json | 9 +- .../wwwroot/animated-icon.svg | 24 + .../wwwroot/index.html | 2 +- 28 files changed, 1635 insertions(+), 1273 deletions(-) create mode 100644 src/Blazor.FileReader/package.json create mode 100644 src/Blazor.FileReader/script/FileEntryList.ts create mode 100644 src/Demo/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg create mode 100644 src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg create mode 100644 src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg diff --git a/.gitignore b/.gitignore index 45bfc87b..74f3f034 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 8c431a08..12b3afdc 100644 --- a/src/Blazor.FileReader/Blazor.FileReader.csproj +++ b/src/Blazor.FileReader/Blazor.FileReader.csproj @@ -1,89 +1,93 @@ - - - - - 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 + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + $(DefineConstants);NETSTANDARD20 + + + + $(DefineConstants);NET5 + + + \ No newline at end of file diff --git a/src/Blazor.FileReader/FileReaderRef.cs b/src/Blazor.FileReader/FileReaderRef.cs index 47afe475..a1ffef84 100644 --- a/src/Blazor.FileReader/FileReaderRef.cs +++ b/src/Blazor.FileReader/FileReaderRef.cs @@ -1,398 +1,425 @@ -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; } + + /// + /// Returns information of the position of any stream related to this file. + /// + IFilePositionInfo PositionInfo { get; } + } + + internal class FileReaderRef : IFileReaderRef + { + public async Task> EnumerateFilesAsync() + { + var count = await GetFileCount(); + var result = Enumerable.Range(0, Math.Max(0, count)) + .Select(index => (IFileReference)new FileReference(this, index)); + return result; + } + + // Get the count twice. Ensure that both numbers are the same. if not, keep getting until the number is stable. + // This is a workaround for the event handler firing off before the AfterDrop event. + public async Task GetFileCount() + { + var lastCount = -10; + while (true) + { + var currentCount = await FileReaderJsInterop.GetFileCount(ElementRef); + + if (lastCount == currentCount) + { + break; + } + + lastCount = currentCount; + await Task.Delay(500); + } + + return lastCount; + } + 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(); + } + +} diff --git a/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml b/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml index e86d784f..9c787d30 100644 --- a/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml +++ b/src/Blazor.FileReader/Tewr.Blazor.FileReader.xml @@ -1,464 +1,464 @@ - - - - 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. + + + + + 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 00000000..d33970ee --- /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 db6523a1..48df338e 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 d2df8a16..9dc00e89 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,23 +45,120 @@ 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 { + //return await new Promise((resolve, reject) => { + 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 file = await readEntryAsync(webkitQueue[i]); + files.push(...file); + } + + // Get the content for any other files + files.push(...fileQueue); + + return new FileEntryList(files); +} + +async function readEntryAsync(innerEntry: FileSystemEntry): Promise { + const files: File[] = []; + + if (isFile(innerEntry)) { + let fullPath = innerEntry.fullPath; + if (fullPath.charAt(0) === "/" || fullPath.charAt(0) === "\\") + fullPath = fullPath.substring(1); + try { + const file = await getFile(innerEntry); + files.push(redefineWebkitRelativePath(file, fullPath)); + } catch (err) { + console.error(`error on ${fullPath}`); + console.error(err); + throw err; + } + } else if (isDirectory(innerEntry)) { + try { + const entries = await getEntries(innerEntry.createReader()); + for (const entry of entries) { + const innerFiles = await readEntryAsync(entry); + files.push(...innerFiles); + } + } catch (err2) { + console.error(err2); + throw err2; + } + } + + return files; +} + +async function getEntries(reader): Promise { + return await new Promise((resolve, reject) => reader.readEntries(resolve, reject)); +} + +async function getFile(fileEntry: FileSystemFileEntry): Promise { + return new Promise((resolve, reject) => fileEntry.file(resolve, reject)); +} + +function redefineWebkitRelativePath(file: File, fullPath: string): File { + // overwrite the webkitRelativePath to ensure the correct path is added from the entry. + Object.defineProperty(file, "webkitRelativePath", + { + get() { + return fullPath; + } + }); + + return file; +} + +// 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(); + this.elementDataTransfers.clear(); if (ev.target instanceof HTMLElement) { - let list = ev.dataTransfer.files; - + let files = await getFilesAsync((ev.dataTransfer)); if (registerOptions.additive) { - const existing = this.elementDataTransfers.get(element); - if (existing !== undefined && existing.length > 0) { - list = new ConcatFileList(existing, list); + const existing = this.elementDataTransfers.get(element) ?? new FileList(); + if (existing.length > 0) { + files = new ConcatFileList(existing, files); } } - this.elementDataTransfers.set(element, list); + this.elementDataTransfers.set(element, files); } onAfterDropHandler(ev, element, this); diff --git a/src/Blazor.FileReader/script/FileEntryList.ts b/src/Blazor.FileReader/script/FileEntryList.ts new file mode 100644 index 00000000..2927693d --- /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 5c767f56..5726ca5f 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); @@ -89,14 +91,18 @@ class FileReaderComponent { } public GetFileInfoFromFile(file: File): IFileInfo { - const result = { + const result:IFileInfo = { lastModified: file.lastModified, name: file.name, nonStandardProperties: null, size: file.size, type: file.type }; - const properties: { [propertyName: string]: object } = {}; + + const properties: Record = { + "webkitRelativePath": file.webkitRelativePath + }; + for (const property in file) { if (Object.prototype.hasOwnProperty.call(file, property) && !(property in result)) { properties[property] = file[property]; @@ -126,7 +132,7 @@ class FileReaderComponent { FileReaderJsInterop.initialize(); } - const fileRef: number = this.newFileStreamReference++; + const fileRef = this.newFileStreamReference++; this.fileStreams[fileRef] = file; return fileRef; } @@ -213,8 +219,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 2ab6f2bd..d5162203 100644 --- a/src/Blazor.FileReader/script/Interfaces.ts +++ b/src/Blazor.FileReader/script/Interfaces.ts @@ -2,7 +2,6 @@ invokeMethodAsync(assemblyName: string, methodIdentifier: string, ...args: any[]): Promise; } - interface IBlazor { platform: IBlazorPlatform; } @@ -51,7 +50,7 @@ interface ReadFileSliceResult { interface IFileInfo { name: string; - nonStandardProperties: any; + nonStandardProperties: Record; size: number; type: string; lastModified: number; diff --git a/src/Blazor.FileReader/tsconfig.json b/src/Blazor.FileReader/tsconfig.json index 1e7411e8..0d8bb3f0 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 29c39d8c..efda877c 100644 --- a/src/Blazor.FileReader/wwwroot/FileReaderComponent.js +++ b/src/Blazor.FileReader/wwwroot/FileReaderComponent.js @@ -1,162 +1,247 @@ -(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) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(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 () { + exports.FileReaderJsInterop = void 0; + class FileReaderJsInterop { + static initialize() { FileReaderJsInterop.endTask = - Module.mono_bind_static_method("[" + this.assembly + "] Tewr.Blazor.FileReader.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; + FileReaderJsInterop.assembly = 'Tewr.Blazor.FileReader'; + FileReaderJsInterop.initialized = false; }); 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++) { + 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]; } - 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++) { + 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) { - eligebleAdditions[eligebleAdditions.length] = addition; + eligibleAdditions[eligibleAdditions.length] = addition; } } - for (var 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; } - 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) { + 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 }); - var nameof = function (name) { return name; }; - var dropEvent = nameof("drop"); - var dragOverEvent = nameof("dragover"); + 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) { - var declaredHandler; + 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."); + 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."); + 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_1; + return scriptHandler; } - return function (dragEvent, element, fileReaderComponent) { + return (dragEvent, element, fileReaderComponent) => { declaredHandler(dragEvent, element, fileReaderComponent); - scriptHandler_1(dragEvent, element, fileReaderComponent); + scriptHandler(dragEvent, element, fileReaderComponent); }; } } if (declaredHandler) { return declaredHandler; } - return (function () { }); + 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 file = yield readEntryAsync(webkitQueue[i]); + files.push(...file); + } + files.push(...fileQueue); + return new FileEntryList_1.FileEntryList(files); + }); + } + function readEntryAsync(innerEntry) { + return __awaiter(this, void 0, void 0, function* () { + const files = []; + if (isFile(innerEntry)) { + let fullPath = innerEntry.fullPath; + if (fullPath.charAt(0) === "/" || fullPath.charAt(0) === "\\") + fullPath = fullPath.substring(1); + try { + const file = yield getFile(innerEntry); + files.push(redefineWebkitRelativePath(file, fullPath)); + } + catch (err) { + console.error(`error on ${fullPath}`); + console.error(err); + } + } + else if (isDirectory(innerEntry)) { + try { + const entries = yield getEntries(innerEntry.createReader()); + for (const entry of entries) { + const innerFiles = yield readEntryAsync(entry); + files.push(...innerFiles); + } + } + catch (err2) { + console.error(err2); + } + } + return files; + }); + } + function getEntries(reader) { + return __awaiter(this, void 0, void 0, function* () { + try { + return yield new Promise((resolve, reject) => reader.readEntries(resolve, reject)); + } + catch (err) { + console.error(err); + } + }); + } + function getFile(fileEntry) { + return __awaiter(this, void 0, void 0, function* () { + try { + return new Promise((resolve, reject) => fileEntry.file(resolve, reject)); + } + catch (err) { + console.error(err); + } + }); + } + function redefineWebkitRelativePath(file, fullPath) { + Object.defineProperty(file, "webkitRelativePath", { + get() { + return fullPath; + } + }); + return file; + } + function isDirectory(entry) { + return entry.isDirectory; + } + function isFile(entry) { + return entry.isFile; + } function RegisterDropEvents(element, registerOptions) { - var _this = this; this.LogIfNull(element); - var onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent); - var dropHandler = function (ev) { + const onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent); + const dropHandler = (ev) => __awaiter(this, void 0, void 0, function* () { + var _a; ev.preventDefault(); + this.elementDataTransfers.clear(); if (ev.target instanceof HTMLElement) { - var list = ev.dataTransfer.files; + let files = yield getFilesAsync((ev.dataTransfer)); if (registerOptions.additive) { - var existing = _this.elementDataTransfers.get(element); - if (existing !== undefined && existing.length > 0) { - list = new ConcatFileList_1.ConcatFileList(existing, list); + const existing = (_a = this.elementDataTransfers.get(element)) !== null && _a !== void 0 ? _a : new FileList(); + if (existing.length > 0) { + files = new ConcatFileList_1.ConcatFileList(existing, files); } } - _this.elementDataTransfers.set(element, list); + this.elementDataTransfers.set(element, files); } - onAfterDropHandler(ev, element, _this); - }; - var onAfterDragOverHandler = BuildDragEventHandler(registerOptions.onDragOverMethod, registerOptions.onDragOverScript, dragOverEvent); - var dragOverHandler = function (ev) { + onAfterDropHandler(ev, element, this); + }); + const onAfterDragOverHandler = BuildDragEventHandler(registerOptions.onDragOverMethod, registerOptions.onDragOverScript, dragOverEvent); + const dragOverHandler = (ev) => { ev.preventDefault(); - onAfterDragOverHandler(ev, element, _this); + onAfterDragOverHandler(ev, element, this); }; - var onAfterRegisterHandler = BuildDragEventHandler(registerOptions.onRegisterDropEventsMethod, registerOptions.onRegisterDropEventsScript, 'RegisterDropEvents'); - var eventHandlers = { drop: dropHandler, dragover: dragOverHandler }; + 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); @@ -166,7 +251,7 @@ exports.RegisterDropEvents = RegisterDropEvents; function UnregisterDropEvents(element) { this.LogIfNull(element); - var eventHandlers = this.dragElements.get(element); + const eventHandlers = this.dragElements.get(element); if (eventHandlers) { element.removeEventListener(dropEvent, eventHandlers.drop); element.removeEventListener(dragOverEvent, eventHandlers.dragover); @@ -180,9 +265,9 @@ 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; + exports.FileReaderComponentInstance = exports.FileReaderComponent = void 0; + class FileReaderComponent { + constructor() { this.newFileStreamReference = 0; this.fileStreams = {}; this.dragElements = new Map(); @@ -193,61 +278,61 @@ 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); + this.GetFileCount = (element) => { + this.LogIfNull(element); + const files = this.GetFiles(element); if (!files) { return -1; } - var result = files.length; + const result = files.length; return result; }; - this.ClearValue = function (element) { - _this.LogIfNull(element); + this.ClearValue = (element) => { + this.LogIfNull(element); if (element instanceof HTMLInputElement) { element.value = null; } else { - _this.elementDataTransfers.delete(element); + this.elementDataTransfers.delete(element); } return 0; }; - this.GetFileInfoFromElement = function (element, index) { - _this.LogIfNull(element); - var files = _this.GetFiles(element); + this.GetFileInfoFromElement = (element, index) => { + this.LogIfNull(element); + const files = this.GetFiles(element); if (!files) { return null; } - var file = files.item(index); + const file = files.item(index); if (!file) { return null; } - return _this.GetFileInfoFromFile(file); + return this.GetFileInfoFromFile(file); }; - this.Dispose = function (fileRef) { - return delete (_this.fileStreams[fileRef]); + this.Dispose = (fileRef) => { + return delete (this.fileStreams[fileRef]); }; - this.OpenRead = function (element, fileIndex, useWasmSharedBuffer) { - _this.LogIfNull(element); - var files = _this.GetFiles(element); + this.OpenRead = (element, fileIndex, useWasmSharedBuffer) => { + this.LogIfNull(element); + const files = this.GetFiles(element); if (!files) { throw 'No FileList available.'; } - var file = files.item(fileIndex); + const file = files.item(fileIndex); if (!file) { - throw "No file with index " + fileIndex + " available."; + throw `No file with index ${fileIndex} available.`; } - return _this.OpenReadFile(file, useWasmSharedBuffer); + return this.OpenReadFile(file, useWasmSharedBuffer); }; - this.OpenReadFile = function (file, useWasmSharedBuffer) { + this.OpenReadFile = (file, useWasmSharedBuffer) => { if (useWasmSharedBuffer && !FileReaderJsInterop_2.FileReaderJsInterop.initialized) { FileReaderJsInterop_2.FileReaderJsInterop.initialize(); } - var fileRef = _this.newFileStreamReference++; - _this.fileStreams[fileRef] = file; + const fileRef = this.newFileStreamReference++; + this.fileStreams[fileRef] = file; return fileRef; }; - this.ReadFileParamsPointer = function (readFileParamsPointer) { + this.ReadFileParamsPointer = (readFileParamsPointer) => { return { taskId: Blazor.platform.readUint64Field(readFileParamsPointer, 0), bufferOffset: Blazor.platform.readUint64Field(readFileParamsPointer, 8), @@ -256,61 +341,61 @@ position: Blazor.platform.readUint64Field(readFileParamsPointer, 24) }; }; - this.ReadBufferPointer = function (readBufferPointer) { + this.ReadBufferPointer = (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, { + 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(); - }, function (e) { return reject(e); }); + }, e => reject(e)); }); - asyncCall.then(function () { return FileReaderJsInterop_2.FileReaderJsInterop.endTask(readFileParams.taskId); }, function (error) { + 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 = 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); + 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); - var byteCount = Math.min(data.arrayBuffer.byteLength, data.params.count); + const 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; + 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); - }, function (e) { return reject(e); }); + }, e => reject(e)); }); }; - this.ReadFileSlice = function (readFileParams, method) { - return new Promise(function (resolve, reject) { - var file = _this.fileStreams[readFileParams.fileRef]; + this.ReadFileSlice = (readFileParams, method) => { + return new Promise((resolve, reject) => { + const file = this.fileStreams[readFileParams.fileRef]; try { - var reader = new FileReader(); - reader.onload = (function (r) { - return function () { + const reader = new FileReader(); + reader.onload = ((r) => { + return () => { try { resolve({ result: r.result, file: file }); } - catch (e) { - reject(e); + catch (ex) { + reject(ex); } }; })(reader); @@ -322,81 +407,79 @@ }); }; } - FileReaderComponent.prototype.LogIfNull = function (element) { + LogIfNull(element) { if (element == null) { - console.log(FileReaderJsInterop_2.FileReaderJsInterop.assembly + ": HTMLElement is null. Can't access IFileReaderRef after HTMLElement was removed from DOM."); + 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; + } + GetFiles(element) { + let files = null; if (element instanceof HTMLInputElement) { files = element.files; } else { - var dataTransfer = this.elementDataTransfers.get(element); + const dataTransfer = this.elementDataTransfers.get(element); if (dataTransfer) { files = dataTransfer; } } return files; - }; - FileReaderComponent.prototype.GetJSObjectReference = function (element, fileIndex) { + } + GetJSObjectReference(element, fileIndex) { this.LogIfNull(element); - var files = this.GetFiles(element); + const files = this.GetFiles(element); return files.item(fileIndex); - }; - FileReaderComponent.prototype.GetFileInfoFromFile = function (file) { - var result = { + } + GetFileInfoFromFile(file) { + const result = { lastModified: file.lastModified, name: file.name, nonStandardProperties: null, size: file.size, type: file.type }; - var properties = {}; - for (var property in file) { + const properties = { + "webkitRelativePath": file.webkitRelativePath + }; + for (const 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]; - }); + } + 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; }); - }; - return FileReaderComponent; - }()); + } + } exports.FileReaderComponent = FileReaderComponent; - var FileReaderComponentInstance = new 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) { - var _this = this; this.LogIfNull(element); - var pasteHandler = function (ev) { + const pasteHandler = (ev) => { if (ev.target instanceof HTMLElement) { - var list = ev.clipboardData.files; + let list = ev.clipboardData.files; if (list.length > 0) { ev.preventDefault(); if (registerOptions.additive) { - var existing = _this.elementDataTransfers.get(element); + 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.elementDataTransfers.set(element, list); } }; this.pasteElements.set(element, pasteHandler); @@ -406,7 +489,7 @@ exports.RegisterPasteEvent = RegisterPasteEvent; function UnregisterPasteEvent(element) { this.LogIfNull(element); - var eventHandler = this.pasteElements.get(element); + const eventHandler = this.pasteElements.get(element); if (eventHandler) { element.removeEventListener("paste", eventHandler); } @@ -430,8 +513,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 +523,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 +534,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 6d106830..33a5377e 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/DragnDropCommon.razor b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropCommon.razor index 846f1d5a..744c6789 100644 --- a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropCommon.razor +++ b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropCommon.razor @@ -1,60 +1,69 @@ -@using System.IO; -@inject IFileReaderService fileReaderService -

Hello, dropped files!

- -Welcome to your new filestreaming app. -
-This demo reads files that was dropped in without doing anything particular with it. -
-
-
- @foreach (var item in possibleOptions) - { - - } -
-
-
- -@if (currentOption == "DragnDropDivCommon") -{ - -} -else if (currentOption == "DragnDropInputCommon") -{ - -} - -@code { - - private class PossibleOption { public string Id { get; set; } public string Description { get; set; } public Func IsActive { get; set; } } - List possibleOptions = new List { - new PossibleOption { Id = "DragnDropDivCommon", Description= "Drag and Drop on Element" }, - new PossibleOption { Id = "DragnDropInputCommon", Description= "Drag and Drop on Hidden input" }, - }; - - string defaultClasses = "btn btn-primary"; - string currentOption; - protected override void OnInitialized() - { - currentOption = possibleOptions.First().Id; - foreach (var item in possibleOptions) - { - item.IsActive = () => currentOption == item.Id; - - } - base.OnInitialized(); - } - - public void OnChange(string id) - { - currentOption = id; - StateHasChanged(); - } - -} - - - +@using System.IO; +@inject IFileReaderService fileReaderService +

Hello, dropped files!

+ +Welcome to your new filestreaming app. +
+This demo reads files that was dropped in without doing anything particular with it. +
+
+
+ @foreach (var item in possibleOptions) + { + + } +
+
+
+ +@if (currentOption == "DragnDropDivCommon") +{ + +} +else if (currentOption == "DragnDropInputCommon") +{ + +} + +@code { + public static string WriteFileInfoOutput(IFileInfo fileInfo, string nl) { + var output = string.Empty; + output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Name)}: {fileInfo?.Name}{nl}"; + output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Size)}: {fileInfo?.Size}{nl}"; + output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Type)}: {fileInfo?.Type}{nl}"; + output += $"{nameof(IFileInfo)}.{nameof(fileInfo.LastModifiedDate)}: {fileInfo?.LastModifiedDate?.ToString() ?? "(N/A)"}{nl}"; + output += fileInfo?.NonStandardProperties?.Keys.Aggregate(output, (current, property) => current + $"{nameof(IFileInfo)}.{property} (nonstandard): {fileInfo.NonStandardProperties[property]}{nl}"); + output += $"Reading file...{nl}"; + return output; + } + private class PossibleOption { public string Id { get; set; } public string Description { get; set; } public Func IsActive { get; set; } } + List possibleOptions = new List { + new PossibleOption { Id = "DragnDropDivCommon", Description= "Drag and Drop on Element" }, + new PossibleOption { Id = "DragnDropInputCommon", Description= "Drag and Drop on Hidden input" }, + }; + + string defaultClasses = "btn btn-primary"; + string currentOption; + protected override void OnInitialized() + { + currentOption = possibleOptions.First().Id; + foreach (var item in possibleOptions) + { + item.IsActive = () => currentOption == item.Id; + + } + base.OnInitialized(); + } + + public void OnChange(string id) + { + currentOption = id; + StateHasChanged(); + } + +} + + + diff --git a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor index 7b023078..2dcb19b5 100644 --- a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor +++ b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropDivCommon.razor @@ -1,4 +1,6 @@ @using System.IO; +@using System.Threading +@using Tewr.Blazor.FileReader.DropEvents @inject IFileReaderService fileReaderService; - +Multiple files, directories, or a combination of both may be dropped onto the div element.
@fileInfo.Name +
@fileInfo.NonStandardProperties["webkitRelativePath"] }
- - -


- + @code { ElementReference dropTargetElement; ElementReference dropTargetInput; @@ -50,6 +49,8 @@ IFileReaderRef ipReference; bool Additive { get; set; } + private static readonly string nl = Environment.NewLine; + const string dropTargetDragClass = "droptarget-drag"; const string dropTargetClass = "droptarget"; @@ -95,7 +96,7 @@ public async Task OnDrop(EventArgs e) { - Output += "Dropped a file."; + Output += "Dropped a file.\n"; _dropClasses.Remove(dropTargetDragClass); this.StateHasChanged(); await this.RefreshDropFileList(); @@ -104,7 +105,9 @@ private async Task RefreshDropFileList() { DropFileList.Clear(); - foreach (var file in await dropReference.EnumerateFilesAsync()) + var files = (await dropReference.EnumerateFilesAsync()).ToList(); + Output += $"{files.Count} files.\n"; + foreach (var file in files) { var fileInfo = await file.ReadFileInfoAsync(); DropFileList.Add(fileInfo); @@ -123,30 +126,25 @@ public async Task ReadFile(IFileReaderRef list) { Output = string.Empty; - this.StateHasChanged(); - var nl = Environment.NewLine; + _ = InvokeAsync(StateHasChanged); foreach (var file in await list.EnumerateFilesAsync()) { var fileInfo = await file.ReadFileInfoAsync(); - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Name)}: {fileInfo.Name}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Size)}: {fileInfo.Size}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Type)}: {fileInfo.Type}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.LastModifiedDate)}: {fileInfo.LastModifiedDate?.ToString() ?? "(N/A)"}{nl}"; - Output += $"Reading file..."; - this.StateHasChanged(); - fileInfo.PositionInfo.PositionChanged += (s, e) => { + Output += DragnDropCommon.WriteFileInfoOutput(fileInfo, nl); + _ = InvokeAsync(StateHasChanged); + fileInfo.PositionInfo.PositionChanged += (s, e) => + { Output += $"Read {e.PositionDeltaSinceAcknowledge}, {e.Position} / {fileInfo.Size} ({e.Percentage:0.00}%){nl}"; - this.StateHasChanged(); + _ = InvokeAsync(StateHasChanged); }; - var bufferSize = 20480; using (var ps = new PositionStream()) using (var fs = await file.OpenReadAsync()) { await fs.CopyToAsync(ps, bufferSize); - Output += $"Done reading file {fileInfo.Name}{nl}."; + Output += $"Done reading file {fileInfo.Name}.{nl}{nl}"; } - this.StateHasChanged(); + _ = InvokeAsync(StateHasChanged); } } diff --git a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropInputCommon.razor b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropInputCommon.razor index 72b6e49c..592462cf 100644 --- a/src/Demo/Blazor.FileReader.Demo.Common/DragnDropInputCommon.razor +++ b/src/Demo/Blazor.FileReader.Demo.Common/DragnDropInputCommon.razor @@ -1,4 +1,5 @@ @using System.IO; +@using System.Threading @inject IFileReaderService fileReaderService; +
+ The input allows reading one or more files or a single directory. This applies when browsing or dropping files/directory.
+ Select an option below to set the input to files or directory.
+ Files + Directory +
- Drop Files here or click me. + Drop @webkitCaption here or click me. @foreach (var fileInfo in IpFileList.Select(x => x.FileInfo)) { -
@fileInfo.Name +
+ if (useWebkit) + { + @fileInfo.NonStandardProperties["webkitRelativePath"] + } + else + { + @fileInfo.Name + } }
@@ -53,10 +69,13 @@

- + @code { + string webkitAttribute => useWebkit ? "webkitdirectory=true" : ""; + string webkitCaption => useWebkit ? "Directory" : "Files"; + bool useWebkit = false; ElementReference dropTargetInput; IFileReaderRef ipReference; bool Additive { get; set; } @@ -120,6 +139,8 @@ { await this.ClearAsync(); } + + //await Task.Delay(500); // Do this to let the files finish. foreach (var file in await ipReference.EnumerateFilesAsync()) { var fileInfo = await file.ReadFileInfoAsync(); @@ -132,22 +153,17 @@ public async Task ReadFile(IFileReaderRef list) { Output = string.Empty; - this.StateHasChanged(); + _ = InvokeAsync(StateHasChanged); - foreach (var pair in IpFileList) + foreach (var pair in IpFileList.ToList()) { var fileInfo = pair.FileInfo; - - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Name)}: {fileInfo.Name}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Size)}: {fileInfo.Size}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.Type)}: {fileInfo.Type}{nl}"; - Output += $"{nameof(IFileInfo)}.{nameof(fileInfo.LastModifiedDate)}: {fileInfo.LastModifiedDate?.ToString() ?? "(N/A)"}{nl}"; - Output += $"Reading file..."; - this.StateHasChanged(); + Output += DragnDropCommon.WriteFileInfoOutput(fileInfo, nl); + _ = InvokeAsync(StateHasChanged); fileInfo.PositionInfo.PositionChanged += (s, e) => { Output += $"Read {e.PositionDeltaSinceAcknowledge}, {e.Position} / {fileInfo.Size} ({e.Percentage:0.00}%){nl}"; - this.StateHasChanged(); + _ = InvokeAsync(StateHasChanged); }; var bufferSize = 20480; @@ -155,9 +171,10 @@ using (var fs = pair.Stream) { await fs.CopyToAsync(ps, bufferSize); - Output += $"Done reading file {fileInfo.Name}.{nl}"; + Output += $"Done reading file {fileInfo.Name}.{nl}{nl}"; } - this.StateHasChanged(); + _ = InvokeAsync(StateHasChanged); } } + } diff --git a/src/Demo/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml b/src/Demo/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml index af6b3f9f..97e97fd0 100644 --- a/src/Demo/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml +++ b/src/Demo/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml @@ -21,8 +21,9 @@ - - @(await Html.RenderComponentAsync(RenderMode.Server)) +< + +@(await Html.RenderComponentAsync(RenderMode.Server)) diff --git a/src/Demo/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json b/src/Demo/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json index e203e940..4d275b1d 100644 --- a/src/Demo/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json +++ b/src/Demo/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json @@ -1,9 +1,12 @@ { + "DetailedErrors": true, // turns on CircuitOptions.DetailedErrors "Logging": { "LogLevel": { "Default": "Debug", "System": "Information", - "Microsoft": "Information" + "Microsoft": "Information", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.SignalR": "Debug" // turns on SignalR debugging } } } diff --git a/src/Demo/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg b/src/Demo/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg new file mode 100644 index 00000000..f1f80039 --- /dev/null +++ b/src/Demo/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg @@ -0,0 +1,24 @@ + + + + +Fichier 3 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Demo/Blazor.FileReader.Wasm.Demo/wwwroot/index.html b/src/Demo/Blazor.FileReader.Wasm.Demo/wwwroot/index.html index f5151723..811b7aab 100644 --- a/src/Demo/Blazor.FileReader.Wasm.Demo/wwwroot/index.html +++ b/src/Demo/Blazor.FileReader.Wasm.Demo/wwwroot/index.html @@ -9,7 +9,7 @@ - +
diff --git a/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml index af6b3f9f..4947e04c 100644 --- a/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml +++ b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/Pages/_Host.cshtml @@ -21,7 +21,7 @@ - + @(await Html.RenderComponentAsync(RenderMode.Server)) diff --git a/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json index e203e940..4d275b1d 100644 --- a/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json +++ b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json @@ -1,9 +1,12 @@ { + "DetailedErrors": true, // turns on CircuitOptions.DetailedErrors "Logging": { "LogLevel": { "Default": "Debug", "System": "Information", - "Microsoft": "Information" + "Microsoft": "Information", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.SignalR": "Debug" // turns on SignalR debugging } } } diff --git a/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg new file mode 100644 index 00000000..f1f80039 --- /dev/null +++ b/src/Demo/Blazor3/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg @@ -0,0 +1,24 @@ + + + + +Fichier 3 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Demo/Blazor3/Blazor.FileReader.Wasm.Demo/wwwroot/index.html b/src/Demo/Blazor3/Blazor.FileReader.Wasm.Demo/wwwroot/index.html index f5151723..811b7aab 100644 --- a/src/Demo/Blazor3/Blazor.FileReader.Wasm.Demo/wwwroot/index.html +++ b/src/Demo/Blazor3/Blazor.FileReader.Wasm.Demo/wwwroot/index.html @@ -9,7 +9,7 @@ - +
diff --git a/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/Pages/_Layout.cshtml b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/Pages/_Layout.cshtml index 2f79beed..57e2dcf3 100644 --- a/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/Pages/_Layout.cshtml +++ b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/Pages/_Layout.cshtml @@ -13,7 +13,7 @@ - + @RenderBody()
diff --git a/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json index 770d3e93..4d275b1d 100644 --- a/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json +++ b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/appsettings.Development.json @@ -1,9 +1,12 @@ { - "DetailedErrors": true, + "DetailedErrors": true, // turns on CircuitOptions.DetailedErrors "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Default": "Debug", + "System": "Information", + "Microsoft": "Information", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.SignalR": "Debug" // turns on SignalR debugging } } } diff --git a/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg new file mode 100644 index 00000000..f1f80039 --- /dev/null +++ b/src/Demo/Net6/Blazor.FileReader.ServerSide.Demo/wwwroot/animated-icon.svg @@ -0,0 +1,24 @@ + + + + +Fichier 3 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Demo/Net6/Blazor.FileReader.Wasm.Demo/wwwroot/index.html b/src/Demo/Net6/Blazor.FileReader.Wasm.Demo/wwwroot/index.html index 37ea5c58..0588835d 100644 --- a/src/Demo/Net6/Blazor.FileReader.Wasm.Demo/wwwroot/index.html +++ b/src/Demo/Net6/Blazor.FileReader.Wasm.Demo/wwwroot/index.html @@ -11,7 +11,7 @@ - +