зеркало из https://github.com/DeGsoft/maui-linux.git
* [Android] Fixes cancel Webview Navigation * - added fix 4891 - refactoring * Fix obsolete message Co-authored-by: Ralph Brackert <brackert@baselineconnect.com>
This commit is contained in:
Родитель
c2752977d4
Коммит
6a3a10afea
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.ManualReview)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 4891, "[Android] WebView Navigating Cancel property not working with custom scheme", PlatformAffected.Android)]
|
||||
public class Issue4891 : TestContentPage // or TestMasterDetailPage, etc ...
|
||||
{
|
||||
Button _back;
|
||||
WebView _myWebView;
|
||||
Label _log;
|
||||
ScrollView _logScrollView;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
|
||||
_back = new Button
|
||||
{
|
||||
Text = "Back"
|
||||
};
|
||||
_back.Clicked += Back_Clicked;
|
||||
|
||||
_myWebView = new WebView
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand,
|
||||
VerticalOptions = LayoutOptions.Start,
|
||||
HeightRequest = 240
|
||||
};
|
||||
_myWebView.Navigating += MyWebView_Navigating;
|
||||
_myWebView.Navigated += MyWebView_Navigated;
|
||||
_myWebView.Source = new HtmlWebViewSource()
|
||||
{
|
||||
Html = "<html><body>Click on the link below. Expected results:<br/>1. Navigating event logged.<br/>2. Navigated event NOT logged.<br/>3. This page stays loaded in the WebView control.<br/><br/><a href='xamforms4223://custom'>Navigate to Custom xamforms4223 scheme</a></body></html>"
|
||||
};
|
||||
|
||||
_log = new Label
|
||||
{
|
||||
VerticalOptions = LayoutOptions.StartAndExpand,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
Text = ""
|
||||
};
|
||||
|
||||
_logScrollView = new ScrollView
|
||||
{
|
||||
VerticalOptions = LayoutOptions.StartAndExpand,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
Content = _log
|
||||
};
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Children =
|
||||
{
|
||||
_myWebView,
|
||||
_back,
|
||||
_logScrollView
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void MyWebView_Navigating(object sender, WebNavigatingEventArgs e)
|
||||
{
|
||||
LogToScreen($"Navigating: {e.Url}");
|
||||
if (e.Url.StartsWith("xamforms4223", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LogToScreen("Caught custom scheme, cancelling navigation.");
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MyWebView_Navigated(object sender, WebNavigatedEventArgs e)
|
||||
{
|
||||
LogToScreen($"Navigated: ({e.Result}) {e.Url}");
|
||||
}
|
||||
|
||||
void LogToScreen(string text)
|
||||
{
|
||||
_log.Text += $"{text}\n";
|
||||
|
||||
InvalidateMeasure();
|
||||
_logScrollView.ScrollToAsync(_log, ScrollToPosition.End, false);
|
||||
}
|
||||
|
||||
void Back_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (_myWebView.CanGoBack)
|
||||
{
|
||||
_myWebView.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 4919, "Webview Navigation cancel not working", PlatformAffected.Android)]
|
||||
public class Issue4919 : TestContentPage // or TestMasterDetailPage, etc ...
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
var url = "https://www.microsoft.com/";
|
||||
var cancel = true;
|
||||
var log = new Label
|
||||
{
|
||||
VerticalOptions = LayoutOptions.StartAndExpand,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
Text = ""
|
||||
};
|
||||
var webView = new WebView()
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Fill,
|
||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||
Source = url
|
||||
};
|
||||
webView.Navigating += (_, e) =>
|
||||
{
|
||||
e.Cancel = cancel;
|
||||
var resultText = cancel ? "[Canceled]" : "[OK]";
|
||||
log.Text += $"{resultText} {e.Url}{System.Environment.NewLine}";
|
||||
};
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label { Text = "WebView must be empty on init" },
|
||||
webView,
|
||||
new Button
|
||||
{
|
||||
Text = "Go to github",
|
||||
Command = new Command(() => webView.Source = "https://github.com/xamarin/Xamarin.Forms")
|
||||
},
|
||||
new Button
|
||||
{
|
||||
Text = "Toggle cancel navigation",
|
||||
Command = new Command(() => cancel = !cancel)
|
||||
},
|
||||
new ScrollView
|
||||
{
|
||||
VerticalOptions = LayoutOptions.EndAndExpand,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
Content = log
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
<DependentUpon>Bugzilla60787.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue4919.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue5461.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue2102.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue1588.xaml.cs">
|
||||
|
@ -133,6 +134,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla37601.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38105.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue3652.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue4891.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38723.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38770.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38827.xaml.cs">
|
||||
|
@ -1123,4 +1125,4 @@
|
|||
<Generator>MSBuild:Compile</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -1,17 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Webkit;
|
||||
using Android.Widget;
|
||||
using WView = Android.Webkit.WebView;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
|
@ -19,42 +11,50 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
WebNavigationResult _navigationResult = WebNavigationResult.Success;
|
||||
WebViewRenderer _renderer;
|
||||
string _lastUrlNavigatedCancel;
|
||||
|
||||
public FormsWebViewClient(WebViewRenderer renderer)
|
||||
{
|
||||
if (renderer == null)
|
||||
throw new ArgumentNullException("renderer");
|
||||
_renderer = renderer;
|
||||
}
|
||||
=> _renderer = renderer ?? throw new ArgumentNullException("renderer");
|
||||
|
||||
protected FormsWebViewClient(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnPageStarted(global::Android.Webkit.WebView view, string url, Bitmap favicon)
|
||||
bool SendNavigatingCanceled(string url) => _renderer?.SendNavigatingCanceled(url) ?? true;
|
||||
|
||||
[Obsolete("ShouldOverrideUrlLoading(view,url) is obsolete as of version 4.0.0. This method was deprecated in API level 24.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
// api 19-23
|
||||
public override bool ShouldOverrideUrlLoading(WView view, string url)
|
||||
=> SendNavigatingCanceled(url);
|
||||
|
||||
// api 24+
|
||||
public override bool ShouldOverrideUrlLoading(WView view, IWebResourceRequest request)
|
||||
=> SendNavigatingCanceled(request?.Url?.ToString());
|
||||
|
||||
public override void OnPageStarted(WView view, string url, Bitmap favicon)
|
||||
{
|
||||
if (_renderer?.Element == null || url == WebViewRenderer.AssetBaseUrl)
|
||||
if (_renderer == null || string.IsNullOrWhiteSpace(url) || url == WebViewRenderer.AssetBaseUrl)
|
||||
return;
|
||||
|
||||
var args = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = url }, url);
|
||||
var cancel = false;
|
||||
if (!url.Equals(_renderer.UrlCanceled, StringComparison.OrdinalIgnoreCase))
|
||||
cancel = SendNavigatingCanceled(url);
|
||||
_renderer.UrlCanceled = null;
|
||||
|
||||
_renderer.ElementController.SendNavigating(args);
|
||||
_navigationResult = WebNavigationResult.Success;
|
||||
|
||||
_renderer.UpdateCanGoBackForward();
|
||||
|
||||
if (args.Cancel)
|
||||
if (cancel)
|
||||
{
|
||||
_renderer.Control.StopLoading();
|
||||
_navigationResult = WebNavigationResult.Cancel;
|
||||
view.StopLoading();
|
||||
}
|
||||
else
|
||||
{
|
||||
_navigationResult = WebNavigationResult.Success;
|
||||
base.OnPageStarted(view, url, favicon);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPageFinished(global::Android.Webkit.WebView view, string url)
|
||||
public override void OnPageFinished(WView view, string url)
|
||||
{
|
||||
if (_renderer?.Element == null || url == WebViewRenderer.AssetBaseUrl)
|
||||
return;
|
||||
|
@ -64,9 +64,14 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_renderer.ElementController.SetValueFromRenderer(WebView.SourceProperty, source);
|
||||
_renderer.IgnoreSourceChanges = false;
|
||||
|
||||
var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, source, url, _navigationResult);
|
||||
bool navigate = _navigationResult == WebNavigationResult.Failure ? !url.Equals(_lastUrlNavigatedCancel, StringComparison.OrdinalIgnoreCase) : true;
|
||||
_lastUrlNavigatedCancel = _navigationResult == WebNavigationResult.Cancel ? url : null;
|
||||
|
||||
_renderer.ElementController.SendNavigated(args);
|
||||
if (navigate)
|
||||
{
|
||||
var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, source, url, _navigationResult);
|
||||
_renderer.ElementController.SendNavigated(args);
|
||||
}
|
||||
|
||||
_renderer.UpdateCanGoBackForward();
|
||||
|
||||
|
@ -75,7 +80,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
[Obsolete("OnReceivedError is obsolete as of version 2.3.0. This method was deprecated in API level 23.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override void OnReceivedError(global::Android.Webkit.WebView view, ClientError errorCode, string description, string failingUrl)
|
||||
public override void OnReceivedError(WView view, ClientError errorCode, string description, string failingUrl)
|
||||
{
|
||||
_navigationResult = WebNavigationResult.Failure;
|
||||
if (errorCode == ClientError.Timeout)
|
||||
|
@ -85,7 +90,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
#pragma warning restore 618
|
||||
}
|
||||
|
||||
public override void OnReceivedError(global::Android.Webkit.WebView view, IWebResourceRequest request, WebResourceError error)
|
||||
public override void OnReceivedError(WView view, IWebResourceRequest request, WebResourceError error)
|
||||
{
|
||||
_navigationResult = WebNavigationResult.Failure;
|
||||
if (error.ErrorCode == ClientError.Timeout)
|
||||
|
@ -100,4 +105,4 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_renderer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Webkit;
|
||||
using Android.Widget;
|
||||
using Android.OS;
|
||||
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
@ -22,6 +20,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
protected internal IWebViewController ElementController => Element;
|
||||
protected internal bool IgnoreSourceChanges { get; set; }
|
||||
protected internal string UrlCanceled { get; set; }
|
||||
|
||||
public WebViewRenderer(Context context) : base(context)
|
||||
{
|
||||
|
@ -42,7 +41,23 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
public void LoadUrl(string url)
|
||||
{
|
||||
Control.LoadUrl(url);
|
||||
if (!SendNavigatingCanceled(url))
|
||||
Control.LoadUrl(url);
|
||||
}
|
||||
|
||||
protected internal bool SendNavigatingCanceled(string url)
|
||||
{
|
||||
if (Element == null || string.IsNullOrWhiteSpace(url))
|
||||
return true;
|
||||
|
||||
if (url == AssetBaseUrl)
|
||||
return false;
|
||||
|
||||
var args = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = url }, url);
|
||||
ElementController.SendNavigating(args);
|
||||
UpdateCanGoBackForward();
|
||||
UrlCanceled = args.Cancel ? null : url;
|
||||
return args.Cancel;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
|
Загрузка…
Ссылка в новой задаче