Skip to content

Commit 56ce347

Browse files
committed
Add external link interception
1 parent 572cd01 commit 56ce347

File tree

6 files changed

+84
-6
lines changed

6 files changed

+84
-6
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Add
9+
- Intercept clicks to external links and open them in the system browser
10+
- Patch for webview to open the webview on 'Run' instead of initialization (Windows)
811

912
## [0.5.3] - 2020-04-27
1013
### Changed

examples/DesktopApp/DesktopApp.csproj

+16-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="SharpWebview" Version="0.5.3" />
10+
<ProjectReference Include="..\..\src\SharpWebview\SharpWebview.csproj" />
1111
</ItemGroup>
12+
1213
<ItemGroup>
1314
<None Update="icon.ico">
1415
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -23,4 +24,18 @@
2324
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
2425
</None>
2526
</ItemGroup>
27+
28+
<!-- This is only necessary, because I don't use the nuget in this example! -->
29+
<Target Name="CopyDll" AfterTargets="AfterBuild">
30+
<Copy SourceFiles="..\..\libs\webview.dll" DestinationFolder="$(OutDir)" />
31+
</Target>
32+
<Target Name="CopyDll2" AfterTargets="CopyDll">
33+
<Copy SourceFiles="..\..\libs\WebView2Loader.dll" DestinationFolder="$(OutDir)" />
34+
</Target>
35+
<Target Name="CopyDyLib" AfterTargets="CopyDll2">
36+
<Copy SourceFiles="..\..\libs\libwebview.dylib" DestinationFolder="$(OutDir)" />
37+
</Target>
38+
<Target Name="CopySo" AfterTargets="CopyDyLib">
39+
<Copy SourceFiles="..\..\libs\libwebview.so" DestinationFolder="$(OutDir)" />
40+
</Target>
2641
</Project>

examples/DesktopApp/Program.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ static void Main(string[] args)
1616
var hostedContent = new HostedContent();
1717

1818
// Wrap the usage of the webview into a using block
19-
// Otherwise the native window will not get disposed correctly
20-
using (var webview = new Webview(true))
19+
// Otherwise the native window will not get disposed correctly.
20+
// By setting the second parameter to true, sharpWebview intercepts
21+
// all external links and opens them in the system browser.
22+
using (var webview = new Webview(true, true))
2123
{
2224
webview
2325
// Set the title of the application window

examples/DesktopApp/app/index.html

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
<link rel="stylesheet" href="app.css" />
1111
</head>
1212

13-
<body>
13+
<body>
1414
<button onclick="sendAnswer()">What is the answer?</button>
15-
<div id="answer"></div>
15+
<div id="answer"></div>
16+
17+
<a href="https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy">Travel home! (external link test)</a>
18+
1619
<script src="app.js"></script>
1720
</body>
1821
</html>

src/SharpWebview/SharpWebview.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<ItemGroup>
3535
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
3636
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
37+
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
3738
</ItemGroup>
3839

3940
</Project>

src/SharpWebview/Webview.cs

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Diagnostics;
3+
using Newtonsoft.Json;
24
using SharpWebview.Content;
35

46
namespace SharpWebview
@@ -19,9 +21,16 @@ public class Webview : IDisposable
1921
/// Set to true, to activate a debug view,
2022
/// if the current webview implementation supports it.
2123
/// </param>
22-
public Webview(bool debug = false)
24+
/// <param name="interceptExternalLinks">
25+
/// Set to true, top open external links in system browser.
26+
/// </param>
27+
public Webview(bool debug = false, bool interceptExternalLinks = false)
2328
{
2429
_nativeWebview = Bindings.webview_create(debug ? 1 : 0, IntPtr.Zero);
30+
if(interceptExternalLinks)
31+
{
32+
InterceptExternalLinks();
33+
}
2534
}
2635

2736
/// <summary>
@@ -138,6 +147,51 @@ protected virtual void Dispose(bool disposing)
138147
}
139148
}
140149

150+
private void InterceptExternalLinks()
151+
{
152+
// Bind a native method as javascript
153+
// This method opens the url parameter in the system browser
154+
Bind("openExternalLink", (id, req) =>
155+
{
156+
dynamic args = JsonConvert.DeserializeObject(req);
157+
ProcessStartInfo psi = new ProcessStartInfo
158+
{
159+
FileName = args[0],
160+
UseShellExecute = true
161+
};
162+
Process.Start (psi);
163+
164+
Return(id, RPCResult.Success, "{}");
165+
});
166+
167+
// On Init of the webview we inject some javascript
168+
// This javascript intercepts all click events and checks,
169+
// if the intercepted click is an external link.
170+
// In case on an external link the registered native method is called.
171+
InitScript(@"
172+
function interceptClickEvent(e) {
173+
var href;
174+
var target = e.target || e.srcElement;
175+
if (target.tagName === 'A') {
176+
href = target.getAttribute('href');
177+
if(href.startsWith('http')
178+
&& !href.startsWith('http://localhost')
179+
&& !href.startsWith('http://127.0.0.1')
180+
) {
181+
openExternalLink(href);
182+
e.preventDefault();
183+
}
184+
}
185+
}
186+
187+
if (document.addEventListener) {
188+
document.addEventListener('click', interceptClickEvent);
189+
} else if (document.attachEvent) {
190+
document.attachEvent('onclick', interceptClickEvent);
191+
}
192+
");
193+
}
194+
141195
~Webview() => Dispose(false);
142196
}
143197
}

0 commit comments

Comments
 (0)