mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 18:38:27 +03:00
hybrid webview
This commit is contained in:
parent
bfa336b72d
commit
23f27282d6
5 changed files with 176 additions and 0 deletions
|
@ -43,6 +43,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Mono.Android" />
|
<Reference Include="Mono.Android" />
|
||||||
|
<Reference Include="Mono.Android.Export" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
@ -87,6 +88,7 @@
|
||||||
<Compile Include="Renderers\CustomEntryRenderer.cs" />
|
<Compile Include="Renderers\CustomEntryRenderer.cs" />
|
||||||
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
|
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
|
||||||
<Compile Include="Renderers\ExtendedListViewRenderer.cs" />
|
<Compile Include="Renderers\ExtendedListViewRenderer.cs" />
|
||||||
|
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||||
<Compile Include="SplashActivity.cs" />
|
<Compile Include="SplashActivity.cs" />
|
||||||
<Compile Include="Renderers\BoxedView\BoxedViewRecyclerAdapter.cs" />
|
<Compile Include="Renderers\BoxedView\BoxedViewRecyclerAdapter.cs" />
|
||||||
<Compile Include="Renderers\BoxedView\BoxedViewRenderer.cs" />
|
<Compile Include="Renderers\BoxedView\BoxedViewRenderer.cs" />
|
||||||
|
|
88
src/Android/Renderers/HybridWebViewRenderer.cs
Normal file
88
src/Android/Renderers/HybridWebViewRenderer.cs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
using System;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.Android;
|
||||||
|
using Android.Webkit;
|
||||||
|
using AWebkit = Android.Webkit;
|
||||||
|
using Java.Interop;
|
||||||
|
using Android.Content;
|
||||||
|
using Bit.Droid.Renderers;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
|
||||||
|
namespace Bit.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, AWebkit.WebView>
|
||||||
|
{
|
||||||
|
private const string JSFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
|
||||||
|
|
||||||
|
private readonly Context _context;
|
||||||
|
|
||||||
|
public HybridWebViewRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if(Control == null)
|
||||||
|
{
|
||||||
|
var webView = new AWebkit.WebView(_context);
|
||||||
|
webView.Settings.JavaScriptEnabled = true;
|
||||||
|
webView.SetWebViewClient(new JSWebViewClient(string.Format("javascript: {0}", JSFunction)));
|
||||||
|
SetNativeControl(webView);
|
||||||
|
}
|
||||||
|
if(e.OldElement != null)
|
||||||
|
{
|
||||||
|
Control.RemoveJavascriptInterface("jsBridge");
|
||||||
|
var hybridWebView = e.OldElement as HybridWebView;
|
||||||
|
hybridWebView.Cleanup();
|
||||||
|
}
|
||||||
|
if(e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
|
||||||
|
Control.LoadUrl(Element.Uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JSBridge : Java.Lang.Object
|
||||||
|
{
|
||||||
|
private readonly WeakReference<HybridWebViewRenderer> _hybridWebViewRenderer;
|
||||||
|
|
||||||
|
public JSBridge(HybridWebViewRenderer hybridRenderer)
|
||||||
|
{
|
||||||
|
_hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JavascriptInterface]
|
||||||
|
[Export("invokeAction")]
|
||||||
|
public void InvokeAction(string data)
|
||||||
|
{
|
||||||
|
if(_hybridWebViewRenderer != null &&
|
||||||
|
_hybridWebViewRenderer.TryGetTarget(out HybridWebViewRenderer hybridRenderer))
|
||||||
|
{
|
||||||
|
hybridRenderer.Element.InvokeAction(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JSWebViewClient : WebViewClient
|
||||||
|
{
|
||||||
|
private readonly string _javascript;
|
||||||
|
|
||||||
|
public JSWebViewClient(string javascript)
|
||||||
|
{
|
||||||
|
_javascript = javascript;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnPageFinished(AWebkit.WebView view, string url)
|
||||||
|
{
|
||||||
|
base.OnPageFinished(view, url);
|
||||||
|
view.EvaluateJavascript(_javascript, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/App/Controls/HybridWebView.cs
Normal file
34
src/App/Controls/HybridWebView.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Bit.App.Controls
|
||||||
|
{
|
||||||
|
public class HybridWebView : View
|
||||||
|
{
|
||||||
|
private Action<string> _func;
|
||||||
|
|
||||||
|
public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: nameof(Uri),
|
||||||
|
returnType: typeof(string), declaringType: typeof(HybridWebView), defaultValue: default(string));
|
||||||
|
|
||||||
|
public string Uri
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(UriProperty); }
|
||||||
|
set { SetValue(UriProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterAction(Action<string> callback)
|
||||||
|
{
|
||||||
|
_func = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cleanup()
|
||||||
|
{
|
||||||
|
_func = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvokeAction(string data)
|
||||||
|
{
|
||||||
|
_func?.Invoke(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
src/iOS/Renderers/HybridWebViewRenderer.cs
Normal file
51
src/iOS/Renderers/HybridWebViewRenderer.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using Foundation;
|
||||||
|
using WebKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.iOS;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Bit.iOS.Renderers;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
|
||||||
|
namespace Bit.iOS.Renderers
|
||||||
|
{
|
||||||
|
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
|
||||||
|
{
|
||||||
|
private const string JSFunction =
|
||||||
|
"function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
|
||||||
|
|
||||||
|
private WKUserContentController _userController;
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if(Control == null)
|
||||||
|
{
|
||||||
|
_userController = new WKUserContentController();
|
||||||
|
var script = new WKUserScript(new NSString(JSFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
|
||||||
|
_userController.AddUserScript(script);
|
||||||
|
_userController.AddScriptMessageHandler(this, "invokeAction");
|
||||||
|
|
||||||
|
var config = new WKWebViewConfiguration { UserContentController = _userController };
|
||||||
|
var webView = new WKWebView(Frame, config);
|
||||||
|
SetNativeControl(webView);
|
||||||
|
}
|
||||||
|
if(e.OldElement != null)
|
||||||
|
{
|
||||||
|
_userController.RemoveAllUserScripts();
|
||||||
|
_userController.RemoveScriptMessageHandler("invokeAction");
|
||||||
|
var hybridWebView = e.OldElement as HybridWebView;
|
||||||
|
hybridWebView.Cleanup();
|
||||||
|
}
|
||||||
|
if(e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.LoadRequest(new NSUrlRequest(new NSUrl(Element.Uri)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
|
||||||
|
{
|
||||||
|
Element.InvokeAction(message.Body.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -92,6 +92,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Main.cs" />
|
<Compile Include="Main.cs" />
|
||||||
<Compile Include="AppDelegate.cs" />
|
<Compile Include="AppDelegate.cs" />
|
||||||
|
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||||
<Compile Include="Services\DeviceActionService.cs" />
|
<Compile Include="Services\DeviceActionService.cs" />
|
||||||
<None Include="Entitlements.plist" />
|
<None Include="Entitlements.plist" />
|
||||||
<None Include="Info.plist" />
|
<None Include="Info.plist" />
|
||||||
|
|
Loading…
Reference in a new issue