Git Product home page Git Product logo

xam.plugin.webview's Introduction

WebView Plugin for Xamarin

Lightweight cross platform WebView designed to leverage the native WebView components in Android, iOS, and Windows to provide enhanced functionality over the base control.

Xamarin Forums Link

Version 2.0.0!

Finally! in alignment with the MacOS and netstandard support in Xamarin.Forms, here is the new release of Xam.Plugins.WebView. Yes there are many changes, but all of these are designed to make less changes in the future with only stable from here on in.

Warning

This build has many changes, please read migration before deciding to make the jump.

Whats new!

  1. netstandard support
  2. MacOS support
  3. Local and Global Headers
  4. Various fixes for bugs on the issue tracker
  5. The ability to evaluate Javascript directly without needing a callback
  6. Massively improved sample application, designed to help you with implementation

Migration

  1. WinRT (Desktop and Phone) are no longer supported! This is to align with Xamarin Forms.
  2. FormsWebViewRenderer.Init is now called FormsWebViewRenderer.Initialize. This is as not to hide a default property in the MacOS renderer.
  3. Headers now have to be applied globally or locally via GlobalRegisteredHeaders and LocalRegisteredHeaders. All previous calls will no longer work.
  4. OnNavigationRequest no longer requires a return response
  5. InjectJavascript is now called InjectJavascriptAsync as to allow the string response mentioned earlier
  6. The assembly name is now Xam.Plugin.WebView. This is to align with the namespaces in the plugin
  7. Callbacks are now added by calling AddLocalCallback and AddGlobalCallback
  8. OnControlChanging has been removed, OnControlChanged is still there. This will be called after the renderer has finished setting up the plugin.
  9. OnJavascriptResponse has been removed as it was no longer needed with the callbacks and string response.

Anything I forgot? Let me know in the issues!

Why I made this?

Hybrid WebViews are common across many applications these days with many different implementations available on the Web. Unfortunately for Xamarin, generally the only common HybridWebView is included as part of the XLabs toolset which gives the user the extra bloat of the additional components, as well as the problems associated with setting up this framework.

Forms WebView is designed to be a lightweight alternative with only minor configuration needed to be performed by the developer before giving them access to a denser API allowing them more flexibility in creating hybrid applications in the Xamarin platform.

Setup

/// <summary>
/// Please call this before Forms is initialized to make sure assemblies link properly.
/// Make sure to perform this step on each platform.
/// </summary>
FormsWebViewRenderer.Initialize();
Xamarin.Forms.Forms.Init(e);

Build Status

  • Jenkins build history can be found here: TBA

Platform Support

Please note: I have only put in platforms I have tested myself.

  • Xamarin.iOS : iOS 9 +
  • Xamarin.MacOS : All
  • Xamarin.Droid : API 17 +
  • Windows UWP : 10 +

Known Limitations

  • Android API level 22 and below will not be able to report HTTPErrors correctly. This is down to the lack of API support from Google up until this release. If you need a way around this, you can add in a hack using System.Web during the OnNavigationRequest.

API Usage

New!

/// <summary>
/// Bind an action to a Javascript function
/// </summary>
FormsWebView WebView = new FormsWebView();
WebView.AddLocalCallback("test", (str) => Debug.WriteLine(str));
WebView.RemoveLocalCallback("test");
/// <summary>
/// Initialize the WebView, Navigation will occur when the Source is changed so make sure to set the BaseUrl and ContentType prior.
/// </summary>
FormsWebView WebView = new FormsWebView() {
    ContentType = WebContentType.Internet,
    Source = "http://www.somewebsite.com"
}
/// <summary>
/// If you wish to further modify the native control, then you can bind to these events in your platform specific code.
/// These events will be called when the control is preparing and ready.
/// </summary>
FormsWebViewRenderer.OnControlChanged += ModifyControlAfterReady;
/// <summary>
/// Attach events using a instance of the WebView.
/// </summary>
WebView.OnNavigationStarted += OnNavigationStarted;
WebView.OnNavigationCompleted += OnNavigationComplete;
WebView.OnContentLoaded += OnContentLoaded;
/// <summary>
/// You can cancel a URL from being loaded by returning a delegate with the cancel boolean set to true.
/// </summary>
private void OnNavigationStarted(NavigationRequestedDelegate eventObj)
{
    if (eventObj.Source == "www.somebadwebsite.com")
        eventObj.Cancel = true;
}
/// <summary>
/// To return a string to c#, simple invoke the csharp(str) method.
/// </summary>
private void OnNavigationComplete(NavigationCompletedDelegate eventObj)
{
    System.Diagnostics.Debug.WriteLine(string.Format("Load Complete: {0}", eventObj.Sender.Source));
}

/// <summary>
/// RUN ALL JAVASCRIPT HERE
/// </summary>
private void OnContentLoaded(ContentLoadedDelegate eventObj)
{
    System.Diagnostics.Debug.WriteLine(string.Format("DOM Ready: {0}", eventObj.Sender.Source));
    eventObj.Sender.InjectJavascript("csharp('Testing');");
}

Local File Locations To modify the file locations, change the BaseUrl in each platforms renderer

  • iOS: Resources Folder as a bundle resource
  • Android: Assets folder as an Android Asset
  • Windows: Root folder as content
  • MacOS: Resources Folder as a bundle resource

Feature Requests

DM me on LinkedIn: http://linkedin.radsrc.com

Notes

For iOS 9 onwards and MacOS, if you wish to access unsecure sites you may need to configure or disable ATS

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>

For Android make sure to add the "Internet" property to your manifest.

For Windows make sure to add the websites to your appxmanifest ContentUris to allow JS invoking.

xam.plugin.webview's People

Contributors

depechie avatar drmashu avatar kristofferberge avatar ngumby avatar skln-rad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xam.plugin.webview's Issues

NuGet Import Error

Hi!
Upon building of the sample project I get this error:
/Users/matthias/Desktop/Xam.Plugin.Webview-master/WebViewPlugin/WebView.Plugin.Abstractions/WebView.Plugin.Abstractions.csproj(5,5): Error: This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is ../../../../vistair-xamarin/vistair-docunet/trunk/packages/Xamarin.Forms.2.3.4.247/build/portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20/Xamarin.Forms.targets. (WebView.Plugin.Abstractions)

Equivalent to XLabs HybridWebView RegisterCallback()

Hi there,

First of all thank you for your work. I think that your Webview will become increasingly popular now that XLabs officially states that their Forms project is no longer maintained. I do not know if you've started working on some documentation, but I think it could really help with adoption, especially for developers who start working on Xamarin.Forms (like me).

The XLabs HybridWebView provides a RegisterCallback() function. When the Native() function is called within Javascript, we use the RegisterCallback function to assign it to a C#/VB function.

Surely there is an equivalent in your Webview?

Thank you for your time!

401 on Android Device, but iOS is working fine

Hi,
I'm trying to add header token to request.
iOS is working fine.

I have Internet permission on my my droid project and did initialise on beginning.

MainActivity
`
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        FormsWebViewRenderer.Initialize();
        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());
    }

`

Still I'm getting 401 on emulator and device.

Any clue what I've missed? Thanks

Late callbacks

I have an issue with the RegisterGlobalCallback function.

When I load my webpage in it tries to find some functions I have registered in the DOMContentLoaded event but fails to find it at that moment. When the page is finished loading I execute the JS in the console to check why the functions are not found but this time it finds them.

The weird thing about this is that i call RegisterGlobalCallback before i set the site source.

Do I need an even later event to check whether the js functions are available?

onReceivedSslError in Android (Xamarin Forms)

Hi I've written a little app to wrap a web site and its working fine to the live web site but when it tries to browse to a development web site on a development server, it gets a certificate error

I/X509Util(32515): Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

I can't quite explain this as the certificate appears to be the same and hence should be installed on the device. As this is only a dev version of the app connecting to a dev server on an intranet, I'm not bothered about ignoring all certificate errors. The problem is, I can't get the event to fire to show a certificate error has occurred. I've seen from a web site post elsewhere that I need something like this:

public override void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er)
        {
            handler.proceed();
            // Ignore SSL certificate errors
        }

The problem is, I don't know where to put the above code. I tried in WebView.Plugin.Shared FormsWebViewRenderer.cs (it does compile in there) but the above event never fires. I set a break point and it is not hit and I still get the certificate error shown in the debugger.
I tried placing it in other similar modules (eg WebView.Plugin.Droid FormsWebViewRenderer.cs and FormsWebViewClient.cs but I get compilation errors in those. EG No sensible method found to override.

Do you know where this override should go?

Thank you
John.

Callbacks in Android doesn't work

Hi,
First of all congratulations for this great plugin!
We've encountered a problem we can't seem to solve, maybe someone can help us!
We have a TabbedPage App with NavigationPage. In every tab a ListView calls the same page model with different data. In this page we dynamically create some HTML code which goes to the 'abstractions:FormsWebView' through 'xamlWebView.Source = HTML_CODE'.
On the 'OnContentLoaded' event we register all the callbacks with 'xamlWebView.RegisterLocalCallback' in order to call C# from the WebView.
In iOS everything works flawlessly, in Android the callback doesn't respond, as if the javascript bridge is completely missing in the webview...

The only error we get is:
[chromium] [INFO:CONSOLE(1)] "Uncaught ReferenceError: bridge is not defined", source: (1)

Everything else works fine, the App doesn't crash and all the natives functions works but the callback just won't respond..
Thanks!

NuGet Package Manager - Error

Hello there,

When I open the NuGet package manager and go to the "Installed" tab, it displays an "Error occurred" notice. In the output I get errors like:

Item has already been added. Key in dictionary: 'lib/win81/WebView.Plugin.Abstractions.dll' Key being added: 'lib/win81/WebView.Plugin.Abstractions.dll'
Item has already been added. Key in dictionary: 'lib/win81/WebView.Plugin.Abstractions.dll' Key being added: 'lib/win81/WebView.Plugin.Abstractions.dll'
Item has already been added. Key in dictionary: 'lib/win81/WebView.Plugin.Abstractions.dll' Key being added: 'lib/win81/WebView.Plugin.Abstractions.dll'
Item has already been added. Key in dictionary: 'lib/win81/WebView.Plugin.Abstractions.dll' Key being added: 'lib/win81/WebView.Plugin.Abstractions.dll'

I was getting this on a project and thought that I had messed something up, but my test project (https://github.com/acicovic/FormsWebViewTests) has the same issue so I think it might have to do with the plugin?

Thank you for your work!

Navigation stack

Is there anyway I can have control or access the navigation stack? (.CanGoBack, GoBack(), etc)
I can see that the hybridview derives from View and not from Webview.

Events Such as OnScrolDown or ScrolUp

Hi Ryan,

I hope you are fine

i am using your plugin from it first version and it seems every time it better than before

i would ask for a request such as scroll events on web view so I can trigger events when user i scrolling down or up

Thank you

Regards

Elin Doughouz

c# objects bridge

Ability to create objects with methods and properties and to transmit them through js bridge into HTML page context in order to manage C# objects with the page's js-scripts

Crash if popped before loading completely.

Push a screen that contains this plugin, then pop the view before it finishes loading. This crashes.

IOS:

System.NullReferenceException Object reference not set to an instance of an object

at Xam.Plugin.iOS.Extras.FormsWKNavigationDelegate.DidFinishNavigation (WebKit.WKWebView webView, WebKit.WKNavigation navigation) <0x1e9431c + 0x00138> in <14f56fe3ba0541f6adc893777e01d113#dc95e517d089235d9194a0279e54dbb4>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) <0xb903a8 + 0x00033> in <82393c1969274a079dfefb3c07b134ad#dc95e517d089235d9194a0279e54dbb4>:0
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) <0xb902d0 + 0x000cb> in <82393c1969274a079dfefb3c07b134ad#dc95e517d089235d9194a0279e54dbb4>:0
at MyApp.iOS.Application.Main (System.String[] args) <0xfe05c + 0x0002f> in <fcdbc0df473044c9a2ca137e8b33a568#dc95e517d089235d9194a0279e54dbb4>:0

Android:

System.NullReferenceException Object reference not set to an instance of an object

at Xam.Plugin.Droid.Extras.FormsWebViewClient.OnPageFinished (Android.Webkit.WebView view, System.String url) [0x000a0] in :0
at Android.Webkit.WebViewClient.n_OnPageFinished_Landroid_webkit_WebView_Ljava_lang_String_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_view, System.IntPtr native_url) [0x00017] in <5005b598e813426186204f9e67a55da5>:0
at (wrapper dynamic-method) System.Object:039968b1-fc69-46e5-b4c1-bd85b2a720d9 (intptr,intptr,intptr,intptr)

osx

Is is possible to make a webview that works on mac also ?

Compilation error: Xam.Plugin.WebView.Droid.dll.mdb does not match assembly

Hi,

I have an error when I try to compile for Android :

Mono.CompilerServices.SymbolWriter.MonoSymbolFileException: Symbol file `D:...\Xam.Plugin.WebView.Droid.dll.mdb' does not match assembly
à Mono.CompilerServices.SymbolWriter.MonoSymbolFile.ReadSymbolFile(String mdbFilename, Guid assemblyGuid)
à Mono.Cecil.Mdb.MdbReaderProvider.GetSymbolReader(ModuleDefinition module, String fileName)
à Mono.Cecil.Cil.DefaultSymbolReaderProvider.GetSymbolReader(ModuleDefinition module, String fileName)
à Mono.Cecil.ModuleReader.ReadSymbols(ModuleDefinition module, ReaderParameters parameters)
à Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters)
à Mono.Cecil.ModuleDefinition.ReadModule(String fileName, ReaderParameters parameters)
à Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.ReadAssembly(String file)

I don't understand why ? My minSdkVersion in the manifest is 21.

Any ideas ?

Thank you !
Régis

DecisionHandlerDelegate does not provide full URL on iOS

Suppose in my WebView, I am working with https://example.com, and I have the following event handler for the OnNavigationStarted event:

private void OnNavigationStarted(object sender, DecisionHandlerDelegate e) { }

When this handler is triggered, the Uri provided inside the DecisionHandlerDelegate is always just the base domain URL. As an example, if I am trying to navigate to https://example.com/settings, e.Uri only ever equals https://example.com, and loses the remainder of the URL.

Android and UWP work perfectly, providing the entire URL being navigated to. Also, this issue appeared only after upgrading to 2.0+. Versions before 2.0 worked properly, but they were using a different delegate.

InputTransparent?

Is it possible to get the InputTransparent property working on Xam.Plugin.Webview?
This would allow preventing users from interacting with static content (scroll, select) and allow adding TappedGestureRecognizers to the webview.

Currently it is not working on Windows 8.1, not tested on iOS and Anrdoid.

Callback dictionaries

Currently there is a static dictionary RegisteredActions: Dictionary<object, Dictionary<string, Action<string>>> for both global and local callbacks.

More natural would be:

  • a static Dictionary<string, Action<string>> for the global callbacks
  • instance Dictionary<string, Action<string>>s for local callbacks

Pros:

  • Avoids memory management / memory leaks. Currently callbacks have to be deregistered manually when webviews are no longer needed. Without doing this, the static dictionary will grow, and if the dictionary references the unneeded webview, the webview will not be garbage collected. Having a local dictionary should allow garbage collection of a webview's dictionary.

Are there technical hurdles to this that led to the current approach?
Shall I try this change and send a PR?

Full handle alert and confirmation dialogs on UWP

As with Android and iOS.
Tests need to be created to verify this functionality on UWP and WinRT. Any bugs found during testing should be patched and updated here.

For the time being, use the work around by overriding the window.alert event and binding to C#

Scrolling and visibility

Hi Ryan. I have a problem which at first I thought was a general Xamarin problem but I tried replacing your webview with the standard webview and the problem went away. What I'm trying to achieve is the following.
A header at the top of the page containing a button. The webview taking up the body of the page and a footer at the bottom of the page also containing a button. The idea is that to start with the footer is invisible and when I tap the button in the header, the footer appears and when I tap the button in the footer the footer disappears. So I can toggle on and off seeing the footer.
If I set the footer to be invisible at startup time, it never appears when I set it to visible. Also, scrolling of the webview stops when I make the footer visible. Until then scrolling works fine.
If I set the footer to be visible at startup, scrolling is fine until I tap the footer button and make the footer invisible. Then webview scrolling stops again
I read a bit about problems with scrolling and making things invisible so I tried leaving the footer always visible but toggling its height between 0 and 100. As soon as the footer height is zero, the webview scrolling stops and the footer never reappears.
I expected this to be a weird xamarin problem but if I use a normal Xamarin webview it all works as I'd expect.
I've included some of my code below to show the setup. I'm new to Xamarin so it may be a simple problem of how I'm creating or initialising the views but I've tried everything I can think of.
Thanks, John.

` public WebViewPage()
{

        WebViewContentType contentType = WebViewContentType.Internet;
        //WebViewContentType contentType = WebViewContentType.StringData;

        //string url = getURL(contentType);
        string url = "http://www.bbc.co.uk";

        WebView = new FormsWebView()
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            ContentType = contentType,
            Source = url
        };
        WebView.RegisterCallback("OnLoadPhotoHandlerCS", OnLoadPhotoHandlerCS);

        //var webview = new Xamarin.Forms.WebView
        //{
        //    HorizontalOptions = LayoutOptions.Center,
        //    VerticalOptions = LayoutOptions.CenterAndExpand,
        //    Source = url
        //};


        var btnShowFooter = new Button
        {
            Text = "Show Footer",
            Font = Font.SystemFontOfSize(NamedSize.Large),
            BorderWidth = 1,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand
        };
        btnShowFooter.Clicked += OnShowFooterClicked;

        var btnClose = new Button
        {
            Text = "Close",
            Font = Font.SystemFontOfSize(NamedSize.Large),
            BorderWidth = 1,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand
        };
        btnClose.Clicked += OnCloseClicked;

        var header = new StackLayout
        {
            BackgroundColor = Color.Green,
            HeightRequest = 50,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.Start,
            Children = {
                    btnShowFooter
                }
        };

        footer = new StackLayout
        {
            BackgroundColor = Color.LightCyan,
            HeightRequest = 100,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.End,
            //IsVisible = true,
            Children = {
                    btnClose
                }
        };


        Content = new StackLayout
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
            BackgroundColor = Color.Red,
            Children = {
                    header,
                    WebView,
                    //webView,
                    footer
                }
        };


        WebView.OnNavigationStarted += OnNavigationStarted;
        WebView.OnNavigationCompleted += OnNavigationComplete;
        WebView.OnContentLoaded += OnContentLoaded;
        WebView.OnJavascriptResponse += OnJavascriptResponse;

        NavigationPage.SetHasNavigationBar(this, false);
        this.Appearing += Content_Appearing;


    }

    private void OnShowFooterClicked(object sender, EventArgs e)
    {
        Debug.WriteLine("OnShowFooterClicked");

        this.footer.IsVisible = true;
        this.footer.HeightRequest = 100;

        //var mediaChooserPage = new MediaChooserPage();
        //await Navigation.PushModalAsync(mediaChooserPage);

    }


    private void OnCloseClicked(object sender, EventArgs e)
    {
        Debug.WriteLine("OnCloseClicked");

        //this.footer.IsVisible = false;
        this.footer.HeightRequest = 0;

    }

`

InjectJavascriptAsync working on android, but not on UWP

Here is a very simple example:

fwebView.ContentType = Xam.Plugin.WebView.Abstractions.Enumerations.WebViewContentType.StringData;
fwebView.Source = @"<html>
  <body>
	<div id='player'></div>

	<script>
	  var tag = document.createElement('script');

	  tag.src = 'https://www.youtube.com/iframe_api';
	  var firstScriptTag = document.getElementsByTagName('script')[0];
	  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

	  var player;
	  function onYouTubeIframeAPIReady() {
		player = new YT.Player('player', {
		  height: '390',
		  width: '640',
		  videoId: 'M7lc1UVf-VE',
		  events: {
			'onReady': onPlayerReady,
		  }
		});
	  }

	  function onPlayerReady(event) {
		event.target.playVideo();
	  }

	function myStop() {
		player.stopVideo();
		return 'x'; 
	  }
	</script>
  </body>
</html>";

Then you try to call

fwebView.InjectJavascriptAsync("myStop()");

It works on Android, but not on UWP. (no error though)

Feature Request: LoadContent function

Hi Ryan,

Today I was experimenting with loading a local image into the WebView by calling it in HTML code. As it currently stands (if I'm not mistaken), in order to load local content we must Use the approach described here and then set the WebView's BasePath property.

This works but it takes some steps to write code within platform-specific projects so it would be nice to have something like a LoadContent(string content, string baseUri) function which would get the platform's basepath for us, append to it the BaseUri specified in the arguments and then push the string content into the WebView.

Besides making things a bit easier, I think that it is also semantically better as WebView.Uri is not that semantic when we want to load HTML.

XLabs HybridWebView provides a LoadContent method if you want to take a peek at it, although If I recall correctly it still needed special handling for iOS (which again complicates things a bit and would be best avoided if possible). I think that a lot of people coming from XLabs HybridWebView will find it a lot easier if you provide an equivalent function.

Well, thank you for all your work!

Handle BaseUrl for StringData in Windows based projects

Given I am a developer
When I want to use Javascript/Css on my string html data
Then I should be able to set a baseUrl for this to be picked up on the system.

This feature is a requirement for Razor Templating to work correctly with StringData.
At the moment, Windows does not publicly expose any API's to accomplish this however an investigation should be done regardless to see if a workaround can be used in place.

[INFO:CONSOLE(1)] "Uncaught ReferenceError: csharp is not defined", source: (1)

What did I do wrong? Sorry if this is a stupid question.
webView.InjectJavascript("csharp(document.body.innerHTML);") as used in the OnNavigationComplete method below...

        private void OnNavigationComplete(NavigationCompletedDelegate eventObj)
        {
            var webView = eventObj.Sender as FormsWebView;
            string uri = eventObj.Uri;

            Debug.WriteLine(uri);

            if (uri == PORTAL_LOGIN_URL)
            {
                if (loggedOut == false)
                {
                    loggedOut = true;
                    webView.Source = PORTAL_LOGOUT_URL;
                }
                else
                {
                    webView.InjectJavascript(string.Format("void(document.getElementById('loginUsername').value = '{0}');", username));
                    webView.InjectJavascript(string.Format("void(document.getElementById('loginPassword').value = '{0}');", password));
                    webView.InjectJavascript("void(document.getElementById('loginSubmit').click());");
                }
            }
            else if (uri == PORTAL_NOTICES_URL)
                webView.Source = PORTAL_TIMETABLE_URL;
            else if (uri == PORTAL_TIMETABLE_URL)
                webView.InjectJavascript("csharp(document.body.innerHTML);"); // This doesn't work.
        }
        
        private void OnJavascriptResponse(JavascriptResponseDelegate eventObj)
        {
            timetable = ParseHtmlToTimetable(eventObj.Data);
        }

...throws this error: [INFO:CONSOLE(1)] "Uncaught ReferenceError: csharp is not defined", source: (1)

Cheers.

FormsWebView has transparent background somehow. e

Is this normal? It looks cool though. The background is the default background I use in the MainPageTemplate ControlTemplate. I'm not complaining because I'm planning on making a background webview task that is invisible. But I thought I'd bring this up.

image

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TheDayAhead.TimetablePage"
             ControlTemplate="{StaticResource MainPageTemplate}"
             xmlns:local="clr-namespace:TheDayAhead;assembly=TheDayAhead"
             xmlns:controls="clr-namespace:Xam.Plugin.Abstractions;assembly=WebView.Plugin.Abstractions"
             NavigationPage.HasNavigationBar="false">

    <StackLayout x:Name="sl">
        <controls:FormsWebView x:Name="FormsWebView_Main"
                      HorizontalOptions="FillAndExpand"
                      VerticalOptions="FillAndExpand"
                      Source="http://www.google.com"/>
    </StackLayout>
</ContentPage>

Control does not work in iOS 11

Repro: https://www.dropbox.com/s/ita46u7sxbb0s9d/webviewbug.zip?dl=0

To repro, load the app on a device running iOS 11. Note that the page is empty with a yellow background. Change the main page to NormalWebViewPage, which uses Xamarin's WebView, do a clean/rebuild, note that the webviews load.

I know that iOS 11 is still in beta, but it should be released fully soon. I can't use a normal webview because of all the memory leak issues, if you could take a look at this I'd greatly appreciate it.

Thanks

Cookie and Cache

Hi :)
I can't find a way to clear cookie and/or cache.

is there a way to do it programmatically?

Android EventObj.uri gives whole WebView Source

Hi and thanks for your work on this webview! We are trying to use add_OnNavigationStarted to communicate from javascript to fsharp. (In passing if the register callback method is to be prefered please let me know!) Our method starts by calling some javascript to navigate the page:

<script>
    function getHeight() {
        var main = $('#mainUniqueName');
        var h = main.height();
        window.location = 'http://comm/?HWVHeight=' + h.toString();
    }
</script>

then we catch this and decode the uri string:

t.add_OnNavigationStarted
        (
            fun e ->
                let s = e.Uri
                Debug.WriteLine("Navigating to: "+e.Uri+" . ")
                if s.StartsWith("http://comm/?") then
                    e.Cancel <- true
                    let instr = "http://comm/?"+name+"="
                    let n = instr.Length
                    if s.StartsWith(instr) then
                        let decoded = s.[n..s.Length-1] |> System.Uri.UnescapeDataString
                        decoded |> f
                e
                )

On UWP this works exactly as expected and the Debug.WriteLine above gives:

Navigating to: http://comm/?HWVHeight=602 . 

However on Android the whole source of the WebView is appearing:

Navigating to: 
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="utf-8"/>
    <script src="file:///android_asset/miniMathJax/MathJax.js?config=TeX-AMS_SVG"></script>
    <script>MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$']]},imageFont: null, messageStyle:"none"});</script>
    <script type="text/javascript" src="file:///android_asset/jsxgraphcore.js"></script>
    <script src="file:///android_asset/jquery.js"></script>
    <style>
        * {
            font-size: 18pt;
        }
        </style>
  </head>
  <body>
        <div id='mainUniqueName'> 
            ... some long html string here... </div>
        <script>
            function getHeight() {
                var main = $('#mainUniqueName');
                var h = main.height();
                window.location = 'http://comm/?HWVHeight=' + h.toString();
            }
        </script>
    </body>
</html>
 . 

(Please note the trailing full stop - this isn't some other debug output.) Is this expected behaviour, or I have made some kind of mistake? I can provide more details if required.

Setting request headers

I really enjoy having this plugin available, however, is it possible to set a header value for a given request, perhaps in an OnNavigationStarted event handler? Or is there any other current or potential way to handle this?

Queue Javascript Injection if inject is called before the bridge is ready (OnNavigationComplete for example)

Hi!

In iOS, when calling InjectJavascript() within OnNavigationCompleted event handler, this throws an exception. For Android this does not seem to pose a problem.

This might be happening with other calls as well (I have not tested). Note that when you debug and wait a bit before the InjectJavascript(), the crash is not happening, so it's probably related to InjectJavascript clashing with something which is in progress at that moment and has not completed.

I am aware that we should use OnContentLoaded. I am just reporting this just in case there's a way to avoid the crash.

Please Add on next update OnReceivedError

Hi Thank you for your plugin

I have a suggestion if you can add it on next update
because i need it soo much in my application and i am using your Plugin at the main time

its fast not like the Xlabs hybrid view it leaks the memory in mobile devices.

i cannot figure it out how to handle error connection during the browsing
but i have the code but cannot implement it on your plugin

if you can tell me how can i handel it i will be very thankful

if i should wait tell next update i will be also thankful .

` public override void OnReceivedError(Android.Webkit.WebView view, ClientError errorCode, string description, string failingUrl)
{
base.OnReceivedError(view, errorCode, description, failingUrl);
System.Console.WriteLine("\nIn AppName.Droid.FormsWebViewRenderer - Error\nError Code: {0}\nDescription: {1}\nFailing URL: {2}\n", errorCode, description, failingUrl); //TODO: Do something more useful

            //view.LoadData(/* Add your custom error message here along with the 'description' parameter or whatever */, "text/html", "UTF-8");                                         //Load custom errors
        }`

Regards

Allen

Cancelling Navigation

I'm using your plugin specifically to disable navigation to specific urls. I have the webview setup and I'm receiving the OnNavigationStarted events. However when I cancel the navigation I still receive the message "ERR_UNKNOWN_URL_SCHEME.
My hope is that your plugin can support this and I've just implemented it wrong.
internetContent.OnNavigationStarted += OnNavigationStarted;

private NavigationRequestedDelegate OnNavigationStarted(NavigationRequestedDelegate eventObj) { Console.WriteLine(eventObj.Uri); if (eventObj.Uri.StartsWith("plaidlink://")) eventObj.Cancel = true; return eventObj; }
image

Qussion About RegisterCallback respone parameter

Hi

Thank you for this nice plugin

my problem is i want to pass some parameter via javascript function
Here is my code for RegisterCallback

PostWebLoader.RegisterCallback("test", (str) => { Parmeter = str; Debug.WriteLine(str);
});`

and in my website i am using the function as like this >>
csharp(test,somthing)

So How i can pass the somthing to my respond and fire it on OnJavascriptResponse

Regards

Calling a JavaScript function from CSharp

Hi, I've been using your plugin very successfully to inject javascript and call C# from the injected javascript. I also have the need to call one of the injected javascript functions from C# and just wanted to make sure I've not missed some functionality provided by the plugin. I have managed to call a JavaScript function myself from C# but it is quite complex especially if you need to asynchronously wait for a response.
My questions are, is this already provided and if not do you have any plans to add this functionality?
Thank you, John.

How to change BaseUrl

Hi Ryan,

I am running 1.3.0.

In one of my tests iOS crashes, and I suspect that changing the BaseUrl will fix the issue. However, I am unable to understand how to change the BaseUrl. I went into AppDelegate.cs and attempt to change BaseUrl after the FormsWebViewRenderer.Init() call (I figured there would be some FormsWebViewRenderer.BaseUrl property), but the property does not show up.

I am obviously doing something wrong. Can you provide me an example or tell me where to look at?

Thanks!

Catching NSErrorException

Hi there.

Is it possible to add try/catch block into InjectJS method so that NSErrorException could be caught and some event with info which particular script led to the exception raised?

Feature Request: ContentFinishedLoading() Event

Hi, I hope that all is well!

Once my WebView has finished loading its contents, I need to execute a C# function which in turn calls InjectJavascript() with specific arguments. This must be done at that point in time to modify content within the WebView. I did not find a function/event for that (If I'm not mistaken, the XForms equivalent is the LoadFinished() event).

In my case I could probably initiate this from javascript when everything has been loaded (JS to C# and then C# back to JS) but still, this would be a useful feature to have if it's not difficult to implement.

Thanks!

How to call C# from Javascript

Hi,

First of all congratulations and thank you for this wonderful plugin. I want to use this plugin to show a multiple choice question (as labels can't show HTML content), but I am having difficulty on how to get value in C# from Javascript.
My sample HTML code with Javascript is -


<html>
<body>

<div id="question">What is your age?</div>
<div id="options">
<label><input type="radio" name="option" value="1" onclick="CallCSharpFunction()"> 10 years</label>
<label><input type="radio" name="option" value="2" onclick="CallCSharpFunction()"> 20 years</label>
<label><input type="radio" name="option" value="3" onclick="CallCSharpFunction()"> 30 years</label>
<label><input type="radio" name="option" value="4" onclick="CallCSharpFunction()"> 40 years</label>
</div>

<p id="selectedOption"></p>

<script>
function CallCSharpFunction() {
	var options = document.getElementsByName('option');
	var option_value;
	for(var i = 0; i < options.length; i++){
		if(options[i].checked){
			option_value = options[i].value;
		}
	}
	document.getElementById("selectedOption").innerHTML = option_value;
	//What should I do to inform C# the selected option's value?
}
</script>

</body>
</html>

I am sorry to ask this lame question, but I am quite new in programming. From the above HTML sample code, how to should should I receive the selected option's value in C# for further use?

Thanks

Atul

Handling Back Button

Hi Ryan,
Firstly, thank you for making this available and providing support. Mine is more of a question than an issue. Is there a better place to ask questions? I'm a mobile developer but do not have much experience of either Xamarin or webviews so my problem could be a simple one but I'm struggling to figure this out. I suspect my question is not really an issue with your webview.

I need to handle the back button with some kind of intelligence. Currently, if I press the hardware back button in Android I'm taken back to the android home screen. For Android, I think I need to do something like this in the android project

public override void OnBackPressed()
        {
            var webView1 = FindViewById<Android.Webkit.WebView>(Resource.Id.webView);
            if (webView1.CanGoBack())
                webView1.GoBack();
            else
            {
                base.OnBackPressed();
            }
        }

The above could be completely wrong in the context of your webview. My test program is basically your sample where the webview is created in the portable app.cs and I can't figure out how to reference the WebView in Android's MainActivity.cs.
Thanks

Request for adding MIT license

Hi,

I'm developing the mobile application using Xamarin.Forms and i need to use you WebView plugin and it perfectly suits to my requirements. But i can't use it since there is no MIT license provided explicitly.

So, Can you add MIT license for this plugin?

Thanks,
Karthik

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.