summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT
diff options
context:
space:
mode:
authorE.Z. Hart <hartez@users.noreply.github.com>2016-08-03 21:22:14 (GMT)
committerJason Smith <jason.smith@xamarin.com>2016-08-03 21:22:14 (GMT)
commitb186254d1f4a0547c67f4fd30669df9d4cf36b65 (patch)
tree6278a0f3217c726aed4e29c2027b10eb61522aeb /Xamarin.Forms.Platform.WinRT
parentb60fa6acf84d897d6283310e58b1c6c6365c391c (diff)
downloadxamarin-forms-b186254d1f4a0547c67f4fd30669df9d4cf36b65.zip
xamarin-forms-b186254d1f4a0547c67f4fd30669df9d4cf36b65.tar.gz
xamarin-forms-b186254d1f4a0547c67f4fd30669df9d4cf36b65.tar.bz2
Enable WebView to render local HTML files on WinRT platforms (#277)
* Enable WebView to render local HTML files on WinRT platforms * Add test to demonstrate that the solution works even if <head> isn't in the HTML string
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT')
-rw-r--r--Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs59
1 files changed, 52 insertions, 7 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/WebViewRenderer.cs
index 78d69ab..e3fcb89 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 <base> 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 = $"<base href=\"{baseUrl}\"></base>";
+
+ 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 <base> tag
+ internalWebView.NavigationCompleted += async (sender, args) =>
+ {
+ // Generate a version of the <base> script with the correct <base> 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;