Skip to content

Commit 3c06726

Browse files
committed
Move Mono.WebAssembly.Interop to blazor-wasm branch
1 parent d6c88a3 commit 3c06726

File tree

9 files changed

+220
-6
lines changed

9 files changed

+220
-6
lines changed

eng/ProjectReferences.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<ProjectReferenceProvider Include="GetDocument.Insider" ProjectPath="$(RepoRoot)src\Tools\GetDocumentInsider\src\GetDocumentInsider.csproj" />
1616
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepoRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
1717
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepoRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
18+
<ProjectReferenceProvider Include="Mono.WebAssembly.Interop" ProjectPath="$(RepoRoot)src\Components\Blazor\Mono.WebAssembly.Interop\src\Mono.WebAssembly.Interop.csproj" />
1819
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.DataAnnotations.Validation" ProjectPath="$(RepoRoot)src\Components\Blazor\Validation\src\Microsoft.AspNetCore.Blazor.DataAnnotations.Validation.csproj" />
1920
<ProjectReferenceProvider Include="Ignitor" ProjectPath="$(RepoRoot)src\Components\Ignitor\src\Ignitor.csproj" />
2021
<ProjectReferenceProvider Include="BlazorServerApp" ProjectPath="$(RepoRoot)src\Components\Samples\BlazorServerApp\BlazorServerApp.csproj" />

eng/Version.Details.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,6 @@
289289
<Uri>https://github.com/aspnet/Extensions</Uri>
290290
<Sha>4ebd75b961136c7ca331866eed3403becda75681</Sha>
291291
</Dependency>
292-
<Dependency Name="Mono.WebAssembly.Interop" Version="3.1.0-preview4.19568.3" CoherentParentDependency="Microsoft.EntityFrameworkCore">
293-
<Uri>https://github.com/aspnet/Extensions</Uri>
294-
<Sha>4ebd75b961136c7ca331866eed3403becda75681</Sha>
295-
</Dependency>
296292
<Dependency Name="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
297293
<Uri>https://github.com/dotnet/corefx</Uri>
298294
<Sha>0f7f38c4fd323b26da10cce95f857f77f0f09b48</Sha>

eng/Versions.props

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@
158158
<MicrosoftExtensionsWebEncodersPackageVersion>3.1.0</MicrosoftExtensionsWebEncodersPackageVersion>
159159
<MicrosoftInternalExtensionsRefsPackageVersion>3.1.0-rtm.19568.3</MicrosoftInternalExtensionsRefsPackageVersion>
160160
<MicrosoftJSInteropPackageVersion>3.1.0</MicrosoftJSInteropPackageVersion>
161-
<MonoWebAssemblyInteropPackageVersion>3.1.0-preview4.19568.3</MonoWebAssemblyInteropPackageVersion>
162161
<!-- Packages from aspnet/EntityFrameworkCore -->
163162
<dotnetefPackageVersion>3.1.0</dotnetefPackageVersion>
164163
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>3.1.0</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>

src/Components/Blazor/Http/src/Microsoft.AspNetCore.Blazor.HttpClient.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.1</TargetFramework>
4+
<TargetFramework>netstandard2.0</TargetFramework>
55
<Description>Provides experimental support for using System.Text.Json with HttpClient. Intended for use with Blazor running under WebAssembly.</Description>
66
<IsShippingPackage>true</IsShippingPackage>
77
</PropertyGroup>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Runtime.CompilerServices;
5+
6+
namespace WebAssembly.JSInterop
7+
{
8+
/// <summary>
9+
/// Methods that map to the functions compiled into the Mono WebAssembly runtime,
10+
/// as defined by 'mono_add_internal_call' calls in driver.c
11+
/// </summary>
12+
internal class InternalCalls
13+
{
14+
// The exact namespace, type, and method names must match the corresponding entries
15+
// in driver.c in the Mono distribution
16+
17+
// We're passing asyncHandle by ref not because we want it to be writable, but so it gets
18+
// passed as a pointer (4 bytes). We can pass 4-byte values, but not 8-byte ones.
19+
[MethodImpl(MethodImplOptions.InternalCall)]
20+
public static extern string InvokeJSMarshalled(out string exception, ref long asyncHandle, string functionIdentifier, string argsJson);
21+
22+
[MethodImpl(MethodImplOptions.InternalCall)]
23+
public static extern TRes InvokeJSUnmarshalled<T0, T1, T2, TRes>(out string exception, string functionIdentifier, T0 arg0, T1 arg1, T2 arg2);
24+
}
25+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.1</TargetFramework>
5+
<Description>Abstractions and features for interop between Mono WebAssembly and JavaScript code.</Description>
6+
<PackageTags>wasm;javascript;interop</PackageTags>
7+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
8+
<IsPackable>true</IsPackable>
9+
<IsShipping>true</IsShipping>
10+
<HasReferenceAssembly>false</HasReferenceAssembly>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<Reference Include="Microsoft.JSInterop" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using Microsoft.JSInterop;
7+
using Microsoft.JSInterop.Infrastructure;
8+
using WebAssembly.JSInterop;
9+
10+
namespace Mono.WebAssembly.Interop
11+
{
12+
/// <summary>
13+
/// Provides methods for invoking JavaScript functions for applications running
14+
/// on the Mono WebAssembly runtime.
15+
/// </summary>
16+
public class MonoWebAssemblyJSRuntime : JSInProcessRuntime
17+
{
18+
/// <summary>
19+
/// Gets the <see cref="MonoWebAssemblyJSRuntime"/> used to perform operations using <see cref="DotNetDispatcher"/>.
20+
/// </summary>
21+
private static MonoWebAssemblyJSRuntime Instance { get; set; }
22+
23+
/// <summary>
24+
/// Initializes the <see cref="MonoWebAssemblyJSRuntime"/> to be used to perform operations using <see cref="DotNetDispatcher"/>.
25+
/// </summary>
26+
/// <param name="jsRuntime">The <see cref="MonoWebAssemblyJSRuntime"/> instance.</param>
27+
protected static void Initialize(MonoWebAssemblyJSRuntime jsRuntime)
28+
{
29+
if (Instance != null)
30+
{
31+
throw new InvalidOperationException("MonoWebAssemblyJSRuntime has already been initialized.");
32+
}
33+
34+
Instance = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime));
35+
}
36+
37+
/// <inheritdoc />
38+
protected override string InvokeJS(string identifier, string argsJson)
39+
{
40+
var noAsyncHandle = default(long);
41+
var result = InternalCalls.InvokeJSMarshalled(out var exception, ref noAsyncHandle, identifier, argsJson);
42+
return exception != null
43+
? throw new JSException(exception)
44+
: result;
45+
}
46+
47+
/// <inheritdoc />
48+
protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson)
49+
{
50+
InternalCalls.InvokeJSMarshalled(out _, ref asyncHandle, identifier, argsJson);
51+
}
52+
53+
// Invoked via Mono's JS interop mechanism (invoke_method)
54+
private static string InvokeDotNet(string assemblyName, string methodIdentifier, string dotNetObjectId, string argsJson)
55+
{
56+
var callInfo = new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId == null ? default : long.Parse(dotNetObjectId), callId: null);
57+
return DotNetDispatcher.Invoke(Instance, callInfo, argsJson);
58+
}
59+
60+
// Invoked via Mono's JS interop mechanism (invoke_method)
61+
private static void EndInvokeJS(string argsJson)
62+
=> DotNetDispatcher.EndInvokeJS(Instance, argsJson);
63+
64+
// Invoked via Mono's JS interop mechanism (invoke_method)
65+
private static void BeginInvokeDotNet(string callId, string assemblyNameOrDotNetObjectId, string methodIdentifier, string argsJson)
66+
{
67+
// Figure out whether 'assemblyNameOrDotNetObjectId' is the assembly name or the instance ID
68+
// We only need one for any given call. This helps to work around the limitation that we can
69+
// only pass a maximum of 4 args in a call from JS to Mono WebAssembly.
70+
string assemblyName;
71+
long dotNetObjectId;
72+
if (char.IsDigit(assemblyNameOrDotNetObjectId[0]))
73+
{
74+
dotNetObjectId = long.Parse(assemblyNameOrDotNetObjectId);
75+
assemblyName = null;
76+
}
77+
else
78+
{
79+
dotNetObjectId = default;
80+
assemblyName = assemblyNameOrDotNetObjectId;
81+
}
82+
83+
var callInfo = new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId, callId);
84+
DotNetDispatcher.BeginInvokeDotNet(Instance, callInfo, argsJson);
85+
}
86+
87+
protected override void EndInvokeDotNet(DotNetInvocationInfo callInfo, in DotNetInvocationResult dispatchResult)
88+
{
89+
// For failures, the common case is to call EndInvokeDotNet with the Exception object.
90+
// For these we'll serialize as something that's useful to receive on the JS side.
91+
// If the value is not an Exception, we'll just rely on it being directly JSON-serializable.
92+
var resultOrError = dispatchResult.Success ? dispatchResult.Result : dispatchResult.Exception.ToString();
93+
94+
// We pass 0 as the async handle because we don't want the JS-side code to
95+
// send back any notification (we're just providing a result for an existing async call)
96+
var args = JsonSerializer.Serialize(new[] { callInfo.CallId, dispatchResult.Success, resultOrError }, JsonSerializerOptions);
97+
BeginInvokeJS(0, "DotNet.jsCallDispatcher.endInvokeDotNetFromJS", args);
98+
}
99+
100+
#region Custom MonoWebAssemblyJSRuntime methods
101+
102+
/// <summary>
103+
/// Invokes the JavaScript function registered with the specified identifier.
104+
/// </summary>
105+
/// <typeparam name="TRes">The .NET type corresponding to the function's return value type.</typeparam>
106+
/// <param name="identifier">The identifier used when registering the target function.</param>
107+
/// <returns>The result of the function invocation.</returns>
108+
public TRes InvokeUnmarshalled<TRes>(string identifier)
109+
=> InvokeUnmarshalled<object, object, object, TRes>(identifier, null, null, null);
110+
111+
/// <summary>
112+
/// Invokes the JavaScript function registered with the specified identifier.
113+
/// </summary>
114+
/// <typeparam name="T0">The type of the first argument.</typeparam>
115+
/// <typeparam name="TRes">The .NET type corresponding to the function's return value type.</typeparam>
116+
/// <param name="identifier">The identifier used when registering the target function.</param>
117+
/// <param name="arg0">The first argument.</param>
118+
/// <returns>The result of the function invocation.</returns>
119+
public TRes InvokeUnmarshalled<T0, TRes>(string identifier, T0 arg0)
120+
=> InvokeUnmarshalled<T0, object, object, TRes>(identifier, arg0, null, null);
121+
122+
/// <summary>
123+
/// Invokes the JavaScript function registered with the specified identifier.
124+
/// </summary>
125+
/// <typeparam name="T0">The type of the first argument.</typeparam>
126+
/// <typeparam name="T1">The type of the second argument.</typeparam>
127+
/// <typeparam name="TRes">The .NET type corresponding to the function's return value type.</typeparam>
128+
/// <param name="identifier">The identifier used when registering the target function.</param>
129+
/// <param name="arg0">The first argument.</param>
130+
/// <param name="arg1">The second argument.</param>
131+
/// <returns>The result of the function invocation.</returns>
132+
public TRes InvokeUnmarshalled<T0, T1, TRes>(string identifier, T0 arg0, T1 arg1)
133+
=> InvokeUnmarshalled<T0, T1, object, TRes>(identifier, arg0, arg1, null);
134+
135+
/// <summary>
136+
/// Invokes the JavaScript function registered with the specified identifier.
137+
/// </summary>
138+
/// <typeparam name="T0">The type of the first argument.</typeparam>
139+
/// <typeparam name="T1">The type of the second argument.</typeparam>
140+
/// <typeparam name="T2">The type of the third argument.</typeparam>
141+
/// <typeparam name="TRes">The .NET type corresponding to the function's return value type.</typeparam>
142+
/// <param name="identifier">The identifier used when registering the target function.</param>
143+
/// <param name="arg0">The first argument.</param>
144+
/// <param name="arg1">The second argument.</param>
145+
/// <param name="arg2">The third argument.</param>
146+
/// <returns>The result of the function invocation.</returns>
147+
public TRes InvokeUnmarshalled<T0, T1, T2, TRes>(string identifier, T0 arg0, T1 arg1, T2 arg2)
148+
{
149+
var result = InternalCalls.InvokeJSUnmarshalled<T0, T1, T2, TRes>(out var exception, identifier, arg0, arg1, arg2);
150+
return exception != null
151+
? throw new JSException(exception)
152+
: result;
153+
}
154+
155+
#endregion
156+
}
157+
}

src/Components/Components.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor
246246
EndProject
247247
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.DataAnnotations.Validation.Tests", "Blazor\Validation\test\Microsoft.AspNetCore.Blazor.DataAnnotations.Validation.Tests.csproj", "{A5617A9D-C71E-44DE-936C-27611EB40A02}"
248248
EndProject
249+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mono.WebAssembly.Interop", "Mono.WebAssembly.Interop", "{21BB9C13-20C1-4F2B-80E4-D7C64AA3BD05}"
250+
EndProject
251+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.WebAssembly.Interop", "Blazor\Mono.WebAssembly.Interop\src\Mono.WebAssembly.Interop.csproj", "{D141CFEE-D10A-406B-8963-F86FA13732E3}"
252+
EndProject
249253
Global
250254
GlobalSection(SolutionConfigurationPlatforms) = preSolution
251255
Debug|Any CPU = Debug|Any CPU
@@ -1516,6 +1520,18 @@ Global
15161520
{A5617A9D-C71E-44DE-936C-27611EB40A02}.Release|x64.Build.0 = Release|Any CPU
15171521
{A5617A9D-C71E-44DE-936C-27611EB40A02}.Release|x86.ActiveCfg = Release|Any CPU
15181522
{A5617A9D-C71E-44DE-936C-27611EB40A02}.Release|x86.Build.0 = Release|Any CPU
1523+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1524+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
1525+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|x64.ActiveCfg = Debug|Any CPU
1526+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|x64.Build.0 = Debug|Any CPU
1527+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|x86.ActiveCfg = Debug|Any CPU
1528+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Debug|x86.Build.0 = Debug|Any CPU
1529+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
1530+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|Any CPU.Build.0 = Release|Any CPU
1531+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|x64.ActiveCfg = Release|Any CPU
1532+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|x64.Build.0 = Release|Any CPU
1533+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|x86.ActiveCfg = Release|Any CPU
1534+
{D141CFEE-D10A-406B-8963-F86FA13732E3}.Release|x86.Build.0 = Release|Any CPU
15191535
EndGlobalSection
15201536
GlobalSection(SolutionProperties) = preSolution
15211537
HideSolutionNode = FALSE
@@ -1629,6 +1645,8 @@ Global
16291645
{FD9BD646-9D50-42ED-A3E1-90558BA0C6B2} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
16301646
{B70F90C7-2696-4050-B24E-BF0308F4E059} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
16311647
{A5617A9D-C71E-44DE-936C-27611EB40A02} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
1648+
{21BB9C13-20C1-4F2B-80E4-D7C64AA3BD05} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
1649+
{D141CFEE-D10A-406B-8963-F86FA13732E3} = {21BB9C13-20C1-4F2B-80E4-D7C64AA3BD05}
16321650
EndGlobalSection
16331651
GlobalSection(ExtensibilityGlobals) = postSolution
16341652
SolutionGuid = {CC3C47E1-AD1A-4619-9CD3-E08A0148E5CE}

src/Components/ComponentsNoDeps.slnf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"Blazor\\Templates\\src\\Microsoft.AspNetCore.Blazor.Templates.csproj",
1818
"Blazor\\Validation\\src\\Microsoft.AspNetCore.Blazor.DataAnnotations.Validation.csproj",
1919
"Blazor\\Validation\\test\\Microsoft.AspNetCore.Blazor.DataAnnotations.Validation.Tests.csproj",
20+
"Blazor\\Mono.WebAssembly.Interop\\src\\Mono.WebAssembly.Interop.csproj",
2021
"Blazor\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj",
2122
"Blazor\\testassets\\HostedInAspNet.Server\\HostedInAspNet.Server.csproj",
2223
"Blazor\\testassets\\Microsoft.AspNetCore.Blazor.E2EPerformance\\Microsoft.AspNetCore.Blazor.E2EPerformance.csproj",

0 commit comments

Comments
 (0)