[macOS] NRE in WebViewRenderer (#4188) fixes #4001

* https://github.com/xamarin/Xamarin.Forms/issues/4001

* fixed build
This commit is contained in:
Andrei 2018-10-24 17:33:13 +03:00 коммит произвёл Rui Marinho
Родитель 0d40cecdb9
Коммит 140388aae3
3 изменённых файлов: 84 добавлений и 14 удалений

Просмотреть файл

@ -0,0 +1,63 @@
using System;
using System.Linq;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using NUnit.Framework;
using Xamarin.UITest;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 4001, "[MacOS] NullRef in WebViewRenderer", PlatformAffected.macOS, NavigationBehavior.PushAsync)]
public class Issue4001 : TestContentPage
{
protected override void Init()
{
Content = new StackLayout
{
Children = {
new Button
{
HeightRequest = 100,
BackgroundColor = Color.Red,
FontSize = 25,
FontAttributes = FontAttributes.Bold,
TextColor = Color.Black,
Text = "Click Me and wait at least 5 sec [No crash expected]",
Command = new Command(() => {
Navigation.PushAsync(new ContentPage());
})
}
}
};
}
protected override void OnAppearing()
{
base.OnAppearing();
(Content as StackLayout).Children.Insert(0, new WebView
{
Source = "https://github.com/xamarin/Xamarin.Forms/issues/4001",
HeightRequest = 400
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
var webView = (Content as StackLayout).Children.First() as WebView;
webView.Source = "https://en.wikipedia.org/wiki/Xamarin";
(Content as StackLayout).Children.Remove(webView);
}
#if UITEST
#endif
}
}

Просмотреть файл

@ -817,6 +817,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue3525.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3275.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3884.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue4001.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">

Просмотреть файл

@ -116,6 +116,12 @@ namespace Xamarin.Forms.Platform.MacOS
Element.GoBackRequested -= OnGoBackRequested;
Element.GoForwardRequested -= OnGoForwardRequested;
Element.ReloadRequested -= OnReloadRequested;
if (Control?.FrameLoadDelegate is FormsWebFrameDelegate frameDelegate)
frameDelegate.Renderer = null;
Control.FrameLoadDelegate = null;
Control.PolicyDelegate = null;
}
base.Dispose(disposing);
}
@ -184,38 +190,38 @@ namespace Xamarin.Forms.Platform.MacOS
internal class FormsWebFrameDelegate : WebKit.WebFrameLoadDelegate
{
WebViewRenderer _renderer;
internal WebViewRenderer Renderer { private get; set; }
internal FormsWebFrameDelegate(WebViewRenderer renderer)
{
_renderer = renderer;
Renderer = renderer;
}
public override void FinishedLoad(WebKit.WebView sender, WebFrame forFrame)
{
_renderer._sentNavigating = false;
Renderer._sentNavigating = false;
if (_renderer.Control.IsLoading)
if (Renderer.Control.IsLoading)
return;
_renderer._ignoreSourceChanges = true;
_renderer.Element?.SetValueFromRenderer(WebView.SourceProperty, new UrlWebViewSource { Url = _renderer.Control.MainFrameUrl });
_renderer._ignoreSourceChanges = false;
Renderer._ignoreSourceChanges = true;
Renderer.Element?.SetValueFromRenderer(WebView.SourceProperty, new UrlWebViewSource { Url = Renderer.Control.MainFrameUrl });
Renderer._ignoreSourceChanges = false;
_renderer._lastEvent = _renderer._lastBackForwardEvent;
_renderer.Element?.SendNavigated(new WebNavigatedEventArgs(_renderer._lastEvent, _renderer.Element?.Source, _renderer.Control.MainFrameUrl, WebNavigationResult.Success));
Renderer._lastEvent = Renderer._lastBackForwardEvent;
Renderer.Element?.SendNavigated(new WebNavigatedEventArgs(Renderer._lastEvent, Renderer.Element?.Source, Renderer.Control.MainFrameUrl, WebNavigationResult.Success));
_renderer.UpdateCanGoBackForward();
Renderer.UpdateCanGoBackForward();
}
public override void FailedLoadWithError(WebKit.WebView sender, NSError error, WebFrame forFrame)
{
_renderer._sentNavigating = false;
Renderer._sentNavigating = false;
_renderer._lastEvent = _renderer._lastBackForwardEvent;
Renderer._lastEvent = Renderer._lastBackForwardEvent;
_renderer.Element?.SendNavigated(new WebNavigatedEventArgs(_renderer._lastEvent, new UrlWebViewSource { Url = _renderer.Control.MainFrameUrl }, _renderer.Control.MainFrameUrl, WebNavigationResult.Failure));
Renderer.Element?.SendNavigated(new WebNavigatedEventArgs(Renderer._lastEvent, new UrlWebViewSource { Url = Renderer.Control.MainFrameUrl }, Renderer.Control.MainFrameUrl, WebNavigationResult.Failure));
_renderer.UpdateCanGoBackForward();
Renderer.UpdateCanGoBackForward();
}
}
}