summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs149
1 files changed, 149 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs b/Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs
new file mode 100644
index 00000000..8d93c2c7
--- /dev/null
+++ b/Xamarin.Forms.Platform.MacOS/Renderers/WebViewRenderer.cs
@@ -0,0 +1,149 @@
+using System;
+using System.ComponentModel;
+using AppKit;
+using Foundation;
+using Xamarin.Forms.Internals;
+
+namespace Xamarin.Forms.Platform.MacOS
+{
+ public class WebViewRenderer : ViewRenderer<WebView, WebKit.WebView>, IWebViewDelegate
+ {
+ bool _disposed;
+ bool _ignoreSourceChanges;
+ WebNavigationEvent _lastBackForwardEvent;
+ WebNavigationEvent _lastEvent;
+
+ IElementController ElementController => Element;
+
+ void IWebViewDelegate.LoadHtml(string html, string baseUrl)
+ {
+ if (html != null)
+ Control.MainFrame.LoadHtmlString(html,
+ baseUrl == null ? new NSUrl(NSBundle.MainBundle.BundlePath, true) : new NSUrl(baseUrl, true));
+ }
+
+ void IWebViewDelegate.LoadUrl(string url)
+ {
+ Control.MainFrame.LoadRequest(new NSUrlRequest(new NSUrl(url)));
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
+ {
+ base.OnElementChanged(e);
+
+ if (e.NewElement != null)
+ {
+ if (Control == null)
+ {
+ SetNativeControl(new WebKit.WebView
+ {
+ AutoresizingMask = NSViewResizingMask.WidthSizable,
+ AutoresizesSubviews = true
+ });
+ Control.OnFinishedLoading += OnNSWebViewFinishedLoad;
+ Control.OnFailedLoading += OnNSWebViewFailedLoadWithError;
+
+ Element.EvalRequested += OnEvalRequested;
+ Element.GoBackRequested += OnGoBackRequested;
+ Element.GoForwardRequested += OnGoForwardRequested;
+
+ Layer.BackgroundColor = NSColor.Clear.CGColor;
+ }
+ }
+
+ Load();
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnElementPropertyChanged(sender, e);
+
+ if (e.PropertyName == WebView.SourceProperty.PropertyName)
+ Load();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && !_disposed)
+ {
+ _disposed = true;
+ Control.OnFinishedLoading -= OnNSWebViewFinishedLoad;
+ Control.OnFailedLoading -= OnNSWebViewFailedLoadWithError;
+ Element.EvalRequested -= OnEvalRequested;
+ Element.GoBackRequested -= OnGoBackRequested;
+ Element.GoForwardRequested -= OnGoForwardRequested;
+ }
+ base.Dispose(disposing);
+ }
+
+ void Load()
+ {
+ if (_ignoreSourceChanges)
+ return;
+
+ Element?.Source?.Load(this);
+
+ UpdateCanGoBackForward();
+ }
+
+ void UpdateCanGoBackForward()
+ {
+ if (Element == null)
+ return;
+ Element.CanGoBack = Control.CanGoBack();
+ Element.CanGoForward = Control.CanGoForward();
+ }
+
+ void OnEvalRequested(object sender, EvalRequested eventArg)
+ {
+ Control?.StringByEvaluatingJavaScriptFromString(eventArg?.Script);
+ }
+
+ void OnGoBackRequested(object sender, EventArgs eventArgs)
+ {
+ if (Control.CanGoBack())
+ {
+ _lastBackForwardEvent = WebNavigationEvent.Back;
+ Control.GoBack();
+ }
+
+ UpdateCanGoBackForward();
+ }
+
+ void OnGoForwardRequested(object sender, EventArgs eventArgs)
+ {
+ if (Control.CanGoForward())
+ {
+ _lastBackForwardEvent = WebNavigationEvent.Forward;
+ Control.GoForward();
+ }
+
+ UpdateCanGoBackForward();
+ }
+
+ void OnNSWebViewFailedLoadWithError(object sender, WebKit.WebResourceErrorEventArgs e)
+ {
+ _lastEvent = _lastBackForwardEvent;
+ Element?.SendNavigated(new WebNavigatedEventArgs(_lastEvent, new UrlWebViewSource { Url = Control.MainFrameUrl },
+ Control.MainFrameUrl, WebNavigationResult.Failure));
+
+ UpdateCanGoBackForward();
+ }
+
+ void OnNSWebViewFinishedLoad(object sender, WebKit.WebResourceCompletedEventArgs e)
+ {
+ if (Control.IsLoading)
+ return;
+
+ _ignoreSourceChanges = true;
+ ElementController?.SetValueFromRenderer(WebView.SourceProperty, new UrlWebViewSource { Url = Control.MainFrameUrl });
+ _ignoreSourceChanges = false;
+
+ _lastEvent = _lastBackForwardEvent;
+ Element?.SendNavigated(new WebNavigatedEventArgs(_lastEvent, Element?.Source, Control.MainFrameUrl,
+ WebNavigationResult.Success));
+
+ UpdateCanGoBackForward();
+ }
+ }
+} \ No newline at end of file