Skip to content

Commit ac09178

Browse files
committed
Expose _framework/hybridwebview.js
Now that the _framework/hybridwebview.js file is embedded, we can make it available for consumption by the app. It is not required to use this URL, but it is now available. This being embedded makes things easier to update and keep in sync with the implementation of the HybridWebView.
1 parent e106339 commit ac09178

File tree

9 files changed

+61
-12
lines changed

9 files changed

+61
-12
lines changed

src/Controls/samples/Controls.Sample/Maui.Controls.Sample.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
<ItemGroup>
7878
<EmbeddedResource Include="Resources\Embedded\*" />
7979
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
80-
<MauiAsset Include="..\..\..\Core\src\Handlers\HybridWebView\HybridWebView.js" LogicalName="HybridSamplePage\scripts\HybridWebView.js" />
8180
<MauiImage Include="Resources\Images\*" />
8281
<MauiImage Update="Resources\Images\*.gif" Resize="false" />
8382
<MauiIcon Include="Resources\AppIcons\appicon.svg" ForegroundFile="Resources\AppIcons\appicon_foreground.svg" />

src/Controls/samples/Controls.Sample/Resources/Raw/HybridSamplePage/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<title></title>
77
<link rel="icon" href="data:,">
88
<link rel="stylesheet" href="styles/app.css">
9-
<script src="scripts/HybridWebView.js"></script>
9+
<script src="_framework/hybridwebview.js"></script>
1010
<script>
1111
function LogMessage(msg) {
1212
var messageLog = document.getElementById("messageLog");

src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
<!-- Raw Assets for HybridWebView tests (removes the "Resources\Raw" prefix, to mimic what project templates do) -->
3535
<None Remove="Resources\Raw\**" />
3636
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
37-
<MauiAsset Include="..\..\..\Core\src\Handlers\HybridWebView\HybridWebView.js" LogicalName="HybridTestRoot\scripts\HybridWebView.js" />
3837
</ItemGroup>
3938

4039
<PropertyGroup>

src/Controls/tests/DeviceTests/Resources/Raw/HybridTestRoot/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8" />
66
<title></title>
77
<link rel="icon" href="data:,">
8-
<script src="scripts/HybridWebView.js"></script>
8+
<script src="_framework/hybridwebview.js"></script>
99

1010
<!-- test helper functions-->
1111
<script>

src/Controls/tests/DeviceTests/Resources/Raw/HybridTestRoot/invokedotnettests.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8" />
66
<title></title>
77
<link rel="icon" href="data:,">
8-
<script src="scripts/HybridWebView.js"></script>
8+
<script src="_framework/hybridwebview.js"></script>
99
<script>
1010
window.addEventListener(
1111
"HybridWebViewMessageReceived",

src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,19 @@ private async void OnWebResourceRequested(CoreWebView2 sender, CoreWebView2WebRe
173173
{
174174
var relativePath = AppOriginUri.MakeRelativeUri(uri).ToString().Replace('/', '\\');
175175

176-
// 1. Try special InvokeDotNet path
176+
// 1.a. Try the special "_framework/hybridwebview.js" path
177+
if (relativePath == HybridWebViewDotJsPath)
178+
{
179+
logger?.LogDebug("Request for {Url} will return the hybrid web view script.", url);
180+
var jsStream = GetEmbeddedStream(HybridWebViewDotJsPath);
181+
if (jsStream is not null)
182+
{
183+
var ras = await CopyContentToRandomAccessStreamAsync(jsStream);
184+
return (Stream: ras, ContentType: "application/javascript", StatusCode: 200, Reason: "OK");
185+
}
186+
}
187+
188+
// 1.b. Try special InvokeDotNet path
177189
if (relativePath == InvokeDotNetPath)
178190
{
179191
logger?.LogDebug("Request for {Url} will be handled by the .NET method invoker.", url);

src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public partial class HybridWebViewHandler : IHybridWebViewHandler
6666
internal static readonly Uri AppOriginUri = new(AppOrigin);
6767

6868
internal const string InvokeDotNetPath = "__hwvInvokeDotNet";
69+
internal const string HybridWebViewDotJsPath = "_framework\\hybridwebview.js";
6970

7071
public static IPropertyMapper<IHybridWebView, IHybridWebViewHandler> Mapper = new PropertyMapper<IHybridWebView, IHybridWebViewHandler>(ViewHandler.ViewMapper)
7172
{
@@ -493,6 +494,22 @@ await handler.InvokeAsync(nameof(IHybridWebView.EvaluateJavaScriptAsync),
493494
return await FileSystem.OpenAppPackageFileAsync(assetPath);
494495
}
495496

497+
internal static Stream? GetEmbeddedStream(string embeddedPath)
498+
{
499+
var assembly = typeof(HybridWebViewHandler).Assembly;
500+
501+
var resourceName = assembly
502+
.GetManifestResourceNames()
503+
.FirstOrDefault(name => name.Equals(embeddedPath.Replace('\\', '/'), StringComparison.OrdinalIgnoreCase));
504+
505+
if (resourceName is null)
506+
{
507+
return null;
508+
}
509+
510+
return assembly.GetManifestResourceStream(resourceName);
511+
}
512+
496513
#if !NETSTANDARD
497514
internal static readonly FileExtensionContentTypeProvider ContentTypeProvider = new();
498515
#endif

src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.iOS.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public async void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSche
203203
// 2.c. Return the body
204204
if (bytes?.Length > 0)
205205
{
206-
urlSchemeTask.DidReceiveData(NSData.FromArray(bytes));
206+
urlSchemeTask.DidReceiveData(bytes);
207207
}
208208

209209
// 2.d. Finish the task
@@ -217,7 +217,7 @@ public async void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSche
217217
logger?.LogDebug("Request for {Url} was not handled.", url);
218218
}
219219

220-
private async Task<(byte[]? ResponseBytes, string? ContentType, int StatusCode)> GetResponseBytesAsync(string url, ILogger? logger)
220+
private async Task<(NSData? ResponseBytes, string? ContentType, int StatusCode)> GetResponseBytesAsync(string url, ILogger? logger)
221221
{
222222
if (Handler is null)
223223
{
@@ -233,7 +233,18 @@ public async void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSche
233233

234234
var bundleRootDir = Path.Combine(NSBundle.MainBundle.ResourcePath, Handler.VirtualView.HybridRoot!);
235235

236-
// 1. Try special InvokeDotNet path
236+
// 1.a. Try the special "_framework/hybridwebview.js" path
237+
if (relativePath == HybridWebViewDotJsPath)
238+
{
239+
logger?.LogDebug("Request for {Url} will return the hybrid web view script.", url);
240+
var jsStream = GetEmbeddedStream(HybridWebViewDotJsPath);
241+
if (jsStream is not null)
242+
{
243+
return (NSData.FromStream(jsStream), ContentType: "application/javascript", StatusCode: 200);
244+
}
245+
}
246+
247+
// 1.b. Try special InvokeDotNet path
237248
if (relativePath == InvokeDotNetPath)
238249
{
239250
logger?.LogDebug("Request for {Url} will be handled by the .NET method invoker.", url);
@@ -243,7 +254,7 @@ public async void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSche
243254
var contentBytes = await Handler.InvokeDotNetAsync(invokeQueryString);
244255
if (contentBytes is not null)
245256
{
246-
return (contentBytes, "application/json", StatusCode: 200);
257+
return (NSData.FromArray(contentBytes), "application/json", StatusCode: 200);
247258
}
248259
}
249260

@@ -271,7 +282,7 @@ public async void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSche
271282
// 2.a. If something was found, return the content
272283
logger?.LogDebug("Request for {Url} will return an app package file.", url);
273284

274-
return (File.ReadAllBytes(assetPath), contentType, StatusCode: 200);
285+
return (NSData.FromFile(assetPath), contentType, StatusCode: 200);
275286
}
276287
}
277288

src/Core/src/Platform/Android/MauiHybridWebViewClient.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,18 @@ public MauiHybridWebViewClient(HybridWebViewHandler handler)
101101

102102
var relativePath = HybridWebViewHandler.AppOriginUri.MakeRelativeUri(uri).ToString().Replace('/', '\\');
103103

104-
// 1. Try special InvokeDotNet path
104+
// 1.a. Try the special "_framework/hybridwebview.js" path
105+
if (relativePath == HybridWebViewHandler.HybridWebViewDotJsPath)
106+
{
107+
logger?.LogDebug("Request for {Url} will return the hybrid web view script.", fullUrl);
108+
var jsStream = HybridWebViewHandler.GetEmbeddedStream(HybridWebViewHandler.HybridWebViewDotJsPath);
109+
if (jsStream is not null)
110+
{
111+
return new WebResourceResponse("application/json", "UTF-8", 200, "OK", GetHeaders("application/json"), jsStream);
112+
}
113+
}
114+
115+
// 1.b. Try special InvokeDotNet path
105116
if (relativePath == HybridWebViewHandler.InvokeDotNetPath)
106117
{
107118
logger?.LogDebug("Request for {Url} will be handled by the .NET method invoker.", fullUrl);

0 commit comments

Comments
 (0)