Browse Source

Merge pull request #27173 from dotnet-maestro-bot/merge/release/5.0-to-master

[automated] Merge branch 'release/5.0' => 'master'
msftbot[bot] 5 years ago
parent
commit
062237e054

+ 2 - 2
NuGet.config

@@ -3,8 +3,8 @@
   <packageSources>
     <clear />
     <!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
-    <add key="darc-pub-dotnet-runtime-2d8e19f" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-2d8e19f1/nuget/v3/index.json" />
-    <add key="darc-pub-dotnet-efcore-69c4c9d" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-efcore-69c4c9d1/nuget/v3/index.json" />
+    <add key="darc-pub-dotnet-runtime-cf258a1-1" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-cf258a14-1/nuget/v3/index.json" />
+    <add key="darc-pub-dotnet-efcore-73566d1" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-efcore-73566d1f/nuget/v3/index.json" />
     <!--End: Package sources managed by Dependency Flow automation. Do not edit the sources above.-->
     <add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
     <add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />

File diff suppressed because it is too large
+ 0 - 0
src/Components/Web.JS/dist/Release/blazor.server.js


File diff suppressed because it is too large
+ 0 - 0
src/Components/Web.JS/dist/Release/blazor.webassembly.js


+ 5 - 5
src/Components/Web.JS/src/InputFile.ts

@@ -112,11 +112,11 @@ async function readFileData(elem: InputElement, fileId: number, startOffset: num
 function readFileDataSharedMemory(readRequest: any): number {
   const inputFileElementReferenceId = monoPlatform.readStringField(readRequest, 0);
   const inputFileElement = document.querySelector(`[_bl_${inputFileElementReferenceId}]`);
-  const fileId = monoPlatform.readInt32Field(readRequest, 4);
-  const sourceOffset = monoPlatform.readUint64Field(readRequest, 8);
-  const destination = monoPlatform.readInt32Field(readRequest, 16) as unknown as System_Array<number>;
-  const destinationOffset = monoPlatform.readInt32Field(readRequest, 20);
-  const maxBytes = monoPlatform.readInt32Field(readRequest, 24);
+  const fileId = monoPlatform.readInt32Field(readRequest, 8);
+  const sourceOffset = monoPlatform.readUint64Field(readRequest, 12);
+  const destination = monoPlatform.readInt32Field(readRequest, 24) as unknown as System_Array<number>;
+  const destinationOffset = monoPlatform.readInt32Field(readRequest, 32);
+  const maxBytes = monoPlatform.readInt32Field(readRequest, 36);
 
   const sourceArrayBuffer = getFileById(inputFileElement as InputElement, fileId).arrayBuffer as ArrayBuffer;
   const bytesToRead = Math.min(maxBytes, sourceArrayBuffer.byteLength - sourceOffset);

+ 8 - 5
src/Components/Web/src/Forms/InputFile/ReadRequest.cs

@@ -8,22 +8,25 @@ namespace Microsoft.AspNetCore.Components.Forms
     [StructLayout(LayoutKind.Explicit)]
     internal struct ReadRequest
     {
+        // Even though this type is only intended for use on WebAssembly, make it able to
+        // load on 64-bit runtimes by allowing 8 bytes for each reference-typed field.
+
         [FieldOffset(0)]
         public string InputFileElementReferenceId;
 
-        [FieldOffset(4)]
+        [FieldOffset(8)]
         public int FileId;
 
-        [FieldOffset(8)]
+        [FieldOffset(12)]
         public long SourceOffset;
 
-        [FieldOffset(16)]
+        [FieldOffset(24)]
         public byte[] Destination;
 
-        [FieldOffset(20)]
+        [FieldOffset(32)]
         public int DestinationOffset;
 
-        [FieldOffset(24)]
+        [FieldOffset(36)]
         public int MaxBytes;
     }
 }

+ 18 - 0
src/Components/Web/src/Virtualization/Virtualize.cs

@@ -253,6 +253,15 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
         {
             CalcualteItemDistribution(spacerSize, spacerSeparation, containerSize, out var itemsBefore, out var visibleItemCapacity);
 
+            // Since we know the before spacer is now visible, we absolutely have to slide the window up
+            // by at least one element. If we're not doing that, the previous item size info we had must
+            // have been wrong, so just move along by one in that case to trigger an update and apply the
+            // new size info.
+            if (itemsBefore == _itemsBefore && itemsBefore > 0)
+            {
+                itemsBefore--;
+            }
+
             UpdateItemDistribution(itemsBefore, visibleItemCapacity);
         }
 
@@ -262,6 +271,15 @@ namespace Microsoft.AspNetCore.Components.Web.Virtualization
 
             var itemsBefore = Math.Max(0, _itemCount - itemsAfter - visibleItemCapacity);
 
+            // Since we know the after spacer is now visible, we absolutely have to slide the window down
+            // by at least one element. If we're not doing that, the previous item size info we had must
+            // have been wrong, so just move along by one in that case to trigger an update and apply the
+            // new size info.
+            if (itemsBefore == _itemsBefore && itemsBefore < _itemCount - visibleItemCapacity)
+            {
+                itemsBefore++;
+            }
+
             UpdateItemDistribution(itemsBefore, visibleItemCapacity);
         }
 

+ 11 - 0
src/Components/Web/test/Forms/InputFileChangeEventArgsTest.cs

@@ -65,5 +65,16 @@ namespace Microsoft.AspNetCore.Components.Forms
             var ex = Assert.Throws<InvalidOperationException>(() => instance.GetMultipleFiles(1));
             Assert.Equal($"The maximum number of files accepted is 1, but 2 were supplied.", ex.Message);
         }
+
+        [Fact]
+        public void ReadRequestTypeCanBeLoaded()
+        {
+            // Represents https://github.com/dotnet/aspnetcore/issues/26882
+            // Even though the ReadRequest type is only ever used on WebAssembly, developers might
+            // do something that causes the type to be loaded on other environments, for example
+            // using reflection. It's just a DTO with no behaviors so there's nothing to test
+            // except that loading the type doesn't trigger an exception.
+            GC.KeepAlive(new ReadRequest());
+        }
     }
 }

+ 28 - 0
src/Components/test/E2ETest/Tests/VirtualizationTest.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System.Linq;
+using System.Threading.Tasks;
 using BasicTestApp;
 using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
 using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
@@ -216,6 +217,33 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
             Browser.NotEqual(expectedInitialSpacerStyle, () => topSpacer.GetAttribute("style"));
         }
 
+        [Fact]
+        public async Task ToleratesIncorrectItemSize()
+        {
+            Browser.MountTestComponent<VirtualizationComponent>();
+            var topSpacer = Browser.Exists(By.Id("incorrect-size-container")).FindElement(By.TagName("div"));
+            var expectedInitialSpacerStyle = "height: 0px;";
+
+            // Wait until items have been rendered.
+            Browser.True(() => GetItemCount() > 0);
+            Browser.Equal(expectedInitialSpacerStyle, () => topSpacer.GetAttribute("style"));
+
+            // Scroll slowly, in increments of 50px at a time. At one point this would trigger a bug
+            // due to the incorrect item size, whereby it would not realise it's necessary to show more
+            // items because the first time the spacer became visible, the size calculation said that
+            // we're already showing all the items we need to show.
+            for (var pos = 0; pos < 1000; pos += 50)
+            {
+                Browser.ExecuteJavaScript($"document.getElementById('incorrect-size-container').scrollTop = {pos};");
+                await Task.Delay(200);
+            }
+
+            // Validate that the top spacer did change
+            Browser.NotEqual(expectedInitialSpacerStyle, () => topSpacer.GetAttribute("style"));
+
+            int GetItemCount() => Browser.FindElements(By.ClassName("incorrect-size-item")).Count;
+        }
+
         [Fact]
         public void CanMutateDataInPlace_Sync()
         {

+ 9 - 0
src/Components/test/testassets/BasicTestApp/VirtualizationComponent.razor

@@ -28,6 +28,15 @@
     </div>
 </p>
 
+<p>
+    Slightly incorrect item size:<br />
+    <div id="incorrect-size-container" style="background-color: #eee; height: 500px; overflow-y: auto">
+        <Virtualize Items="@fixedItems" ItemSize="50">
+            <div @key="context" class="incorrect-size-item" style="height: 49px; background-color: rgb(@((context % 2) * 255), @((1-(context % 2)) * 255), 255);">Item @context</div>
+        </Virtualize>
+    </div>
+</p>
+
 <p id="viewport-as-root">
     Viewport as root:<br />
     <Virtualize Items="@fixedItems" ItemSize="itemSize">

Some files were not shown because too many files changed in this diff