diff --git a/Xamarin.Forms.ControlGallery.WP8/local.html b/Xamarin.Forms.ControlGallery.WP8/local.html index b1998a12c..6ef9746b7 100644 --- a/Xamarin.Forms.ControlGallery.WP8/local.html +++ b/Xamarin.Forms.ControlGallery.WP8/local.html @@ -4,7 +4,7 @@

Xamarin.Forms

-

This is a local iOS Html page

+

This is a local HTML page

\ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.Windows/WebImages/XamarinLogo.png b/Xamarin.Forms.ControlGallery.Windows/WebImages/XamarinLogo.png new file mode 100644 index 000000000..361e27822 Binary files /dev/null and b/Xamarin.Forms.ControlGallery.Windows/WebImages/XamarinLogo.png differ diff --git a/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj b/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj index c93c45b98..aa8f862f0 100644 --- a/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj +++ b/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj @@ -189,7 +189,10 @@ + + + diff --git a/Xamarin.Forms.ControlGallery.Windows/default.css b/Xamarin.Forms.ControlGallery.Windows/default.css new file mode 100644 index 000000000..9e32b419b --- /dev/null +++ b/Xamarin.Forms.ControlGallery.Windows/default.css @@ -0,0 +1,2 @@ +html,body{margin:0;padding:10} +body,p,h1{font-family:Chalkduster;font-style: italic;} \ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.Windows/local.html b/Xamarin.Forms.ControlGallery.Windows/local.html new file mode 100644 index 000000000..6ef9746b7 --- /dev/null +++ b/Xamarin.Forms.ControlGallery.Windows/local.html @@ -0,0 +1,10 @@ + + + + + +

Xamarin.Forms

+

This is a local HTML page

+ + + \ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/WebImages/XamarinLogo.png b/Xamarin.Forms.ControlGallery.WindowsPhone/WebImages/XamarinLogo.png new file mode 100644 index 000000000..361e27822 Binary files /dev/null and b/Xamarin.Forms.ControlGallery.WindowsPhone/WebImages/XamarinLogo.png differ diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj b/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj index 16a042b02..a85654338 100644 --- a/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj +++ b/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj @@ -166,7 +166,10 @@ + + +
diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/default.css b/Xamarin.Forms.ControlGallery.WindowsPhone/default.css new file mode 100644 index 000000000..9e32b419b --- /dev/null +++ b/Xamarin.Forms.ControlGallery.WindowsPhone/default.css @@ -0,0 +1,2 @@ +html,body{margin:0;padding:10} +body,p,h1{font-family:Chalkduster;font-style: italic;} \ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/local.html b/Xamarin.Forms.ControlGallery.WindowsPhone/local.html new file mode 100644 index 000000000..6ef9746b7 --- /dev/null +++ b/Xamarin.Forms.ControlGallery.WindowsPhone/local.html @@ -0,0 +1,10 @@ + + + + + +

Xamarin.Forms

+

This is a local HTML page

+ + + \ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/WebImages/XamarinLogo.png b/Xamarin.Forms.ControlGallery.WindowsUniversal/WebImages/XamarinLogo.png new file mode 100644 index 000000000..361e27822 Binary files /dev/null and b/Xamarin.Forms.ControlGallery.WindowsUniversal/WebImages/XamarinLogo.png differ diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj b/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj index d5339b71f..a49520004 100644 --- a/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj +++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj @@ -117,8 +117,11 @@
+ + + bank.png diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/default.css b/Xamarin.Forms.ControlGallery.WindowsUniversal/default.css new file mode 100644 index 000000000..9e32b419b --- /dev/null +++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/default.css @@ -0,0 +1,2 @@ +html,body{margin:0;padding:10} +body,p,h1{font-family:Chalkduster;font-style: italic;} \ No newline at end of file diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/local.html b/Xamarin.Forms.ControlGallery.WindowsUniversal/local.html new file mode 100644 index 000000000..6ef9746b7 --- /dev/null +++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/local.html @@ -0,0 +1,10 @@ + + + + + +

Xamarin.Forms

+

This is a local HTML page

+ + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32033.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32033.cs new file mode 100644 index 000000000..2576525a4 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla32033.cs @@ -0,0 +1,141 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls +{ + [Preserve (AllMembers = true)] + [Issue (IssueTracker.Bugzilla, 32033, "WebView on Windows does not display local HTML files", PlatformAffected.WinRT)] + public class Bugzilla32033 : TestNavigationPage + { + protected override void Init () + { + PushAsync(Menu()); + } + + ContentPage Menu() + { + var page = new ContentPage(); + + var layout = new StackLayout(); + + var buttonLocal = new Button() {Text = "Local HTML file"}; + buttonLocal.Clicked += (sender, args) => Navigation.PushAsync(LocalUrl()); + + var buttonHtmlString = new Button() {Text = "HTML string with links/refs to local files"}; + buttonHtmlString.Clicked += (sender, args) => Navigation.PushAsync(HtmlString()); + + var buttonHtmlStringNoHead = new Button() {Text = "HTML string with links/refs to local files (no )"}; + buttonHtmlStringNoHead.Clicked += (sender, args) => Navigation.PushAsync(HtmlStringNoHead()); + + layout.Children.Add(buttonLocal); + layout.Children.Add(buttonHtmlString); + layout.Children.Add(buttonHtmlStringNoHead); + + page.Content = layout; + + return page; + } + + static ContentPage LocalUrl() + { + var page = new ContentPage(); + + var instructions = new Label + { + Text = @"The WebView below should contain the heading 'Xamarin Forms' and text reading 'This is a local HTML page'. All text should be italicized." + }; + + var webView = new WebView + { + WidthRequest = 300, + HeightRequest = 500, + HorizontalOptions = LayoutOptions.Fill, + VerticalOptions = LayoutOptions.Fill, + Source = new UrlWebViewSource() { Url = "local.html" } + }; + + var layout = new StackLayout { Children = { instructions, webView } }; + page.Content = layout; + + return page; + } + + static ContentPage HtmlString() + { + var page = new ContentPage(); + + var instructions = new Label + { + Text = +@"The WebView below should contain the heading 'Xamarin Forms', display the Xamarin logo, and have a link labeled 'next page'. +Clicking that link should navigate to a page with the heading 'Xamarin Forms' and text reading 'This is a local HTML page'. All text on both pages should be italicized." + }; + + var webView = new WebView + { + WidthRequest = 300, + HeightRequest = 500, + HorizontalOptions = LayoutOptions.Fill, + VerticalOptions = LayoutOptions.Fill, + Source = new HtmlWebViewSource + { + Html = @" + + + + +

Xamarin.Forms

+

The CSS and image are loaded from local files!

+ +

next page

+ +" + } + }; + + + var layout = new StackLayout {HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, Children = { instructions, webView } }; + page.Content = layout; + + return page; + } + + // This test verifies that the injection solution works even if the HTML string doesn't explicitly include a section + static ContentPage HtmlStringNoHead() + { + var page = new ContentPage(); + + var instructions = new Label + { + Text = +@"The WebView below should contain the heading 'Xamarin Forms', display the Xamarin logo, and have a link labeled 'next page'. +Clicking that link should navigate to a page with the heading 'Xamarin Forms' and text reading 'This is a local HTML page'. " + }; + + var webView = new WebView + { + WidthRequest = 300, + HeightRequest = 500, + HorizontalOptions = LayoutOptions.Fill, + VerticalOptions = LayoutOptions.Fill, + Source = new HtmlWebViewSource + { + Html = @" + +

Xamarin.Forms

+

The CSS and image are loaded from local files!

+ +

next page

+ +" + } + }; + + + var layout = new StackLayout {HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, Children = { instructions, webView } }; + page.Content = layout; + + return page; + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 4fdb18fdf..8d1e0b408 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -46,6 +46,7 @@ + diff --git a/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs index 78d69abdc..e3fcb898d 100644 --- a/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs +++ b/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs @@ -1,8 +1,14 @@ using System; +using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; +using System.Threading.Tasks; using Windows.UI.Core; +using Windows.UI.WebUI; using Windows.UI.Xaml.Controls; +using Windows.Web.Http; using Xamarin.Forms.Internals; +using static System.String; #if WINDOWS_UWP @@ -16,19 +22,59 @@ namespace Xamarin.Forms.Platform.WinRT { WebNavigationEvent _eventState; bool _updating; + const string LocalScheme = "ms-appx-web:///"; + + // Script to insert a tag into an HTML document + const string BaseInsertionScript = @" +var head = document.getElementsByTagName('head')[0]; +var bases = head.getElementsByTagName('base'); +if(bases.length == 0){ + head.innerHTML = 'baseTag' + head.innerHTML; +}"; public void LoadHtml(string html, string baseUrl) { - /* - * FIXME: If baseUrl is a file URL, set the Base property to its path. - * Otherwise, it doesn't seem as if WebBrowser can handle it. - */ - Control.NavigateToString(html); + if (IsNullOrEmpty(baseUrl)) + { + baseUrl = LocalScheme; + } + + // Generate a base tag for the document + var baseTag = $""; + + string htmlWithBaseTag; + + // Set up an internal WebView we can use to load and parse the original HTML string + var internalWebView = new Windows.UI.Xaml.Controls.WebView(); + + // When the 'navigation' to the original HTML string is done, we can modify it to include our tag + internalWebView.NavigationCompleted += async (sender, args) => + { + // Generate a version of the script with the correct tag + var script = BaseInsertionScript.Replace("baseTag", baseTag); + + // Run it and retrieve the updated HTML from our WebView + await sender.InvokeScriptAsync("eval", new[] { script }); + htmlWithBaseTag = await sender.InvokeScriptAsync("eval", new[] { "document.documentElement.outerHTML;" }); + + // Set the HTML for the 'real' WebView to the updated HTML + Control.NavigateToString(!IsNullOrEmpty(htmlWithBaseTag) ? htmlWithBaseTag : html); + }; + + // Kick off the initial navigation + internalWebView.NavigateToString(html); } public void LoadUrl(string url) { - Control.Source = new Uri(url); + Uri uri = new Uri(url, UriKind.RelativeOrAbsolute); + + if (!uri.IsAbsoluteUri) + { + uri = new Uri(LocalScheme + url, UriKind.RelativeOrAbsolute); + } + + Control.Source = uri; } protected override void Dispose(bool disposing) @@ -165,7 +211,6 @@ namespace Xamarin.Forms.Platform.WinRT _eventState = WebNavigationEvent.NewPage; } - // Nasty hack because we cant bind this because OneWayToSource isn't a thing in WP8, yay void UpdateCanGoBackForward() { Element.CanGoBack = Control.CanGoBack;