Extend NativeScript's default WebViewClient implementation


#1

What I did was move the WebViewClient implementation class outside the initializeWebViewClient funtion and export it in order to allow users to extend it withouth loosing NativeScript’s WebView events.

A good example of where this might be needed would be to add the onReceivedSslError or onProgressChanged to check WebView loading progress.

Having the class exported, I have the following JS code in my app:

const {WebViewClientImpl} = require("tns-core-modules/ui/web-view");

WebViewClientImpl.prototype.onReceivedSslError = function (view, handler) {
	handler.proceed();
};

webview.android.setWebViewClient(new WebViewClientImpl(webview));

The problem is that the webview events work as intended, but my onReceivedSslError seems to be ignored.

Any ideas what I’m missing here ?

Thank you in advance :wink:


#2

@surdu

As of now, you can’t dynamically change the implementation of JS-extended Android/Java classes.


#4

Unfortunately at this time you can’t modify a native Java class by updating it’s prototype chain.

May be just as it is not possible in Java, you have to always create a new class by extending parent class to add / override methods.

I would expect Nativescript team to export the internal native classes, here for instance export the WebViewClientImpl so at least we can extend that with a new class to add our own methods and reset the WebView client by then we won’t loose the events exposed by WebView module.


#5

@manojdcoder This is just what I did. The code provided above imports that class that I exported in my local version of tns-core-modules and adds the onReceivedSslError method to it, but the above code doesn’t work, at least in JS (didn’t try TypeScript yet because I need it to work in JS)


#6

If you check the code here WebViewClientImpl is not exported by the web view module, that class can be used only within that same file. So I would propose NativeScript team to export such classes to make it easy to extend for app developers.

Once they have them exported, we can extend it but absolutely not the way you are doing - by updating the prototype chain. It works only for a JavaScript object but not to the internal Java class.

It should be something like below. Here the extend is a special function exposed by NativeScript and not the one comes in JavaScript Core.

TypeScript

class MyWebViewClientImpl extends MyWebViewClientImpl {
...
}

JavaScript

MyWebViewClientImpl.extend({...});

Update: If you are looking for an example how you can extend WebViewClient for SSL errors without loosing core events fired by WebView, here you go.

If you are using more than one WebView in your app in different pages, you may think of cleaning up the code a bit may be by updating the createNativeView method in it’s prototype chain to call your method where you would inject your WebViewClient implementation.


#7

@surdu has supposedly done that himself so he can work with the WebViewClientImpl. However it is a known limitation that you cannot extend generated Java classes, that have already been extended in JavaScript.


#8

@manojdcoder i knew about that solution, but I didn’t like it because we will lose further fixes and improvements made to NS’ WebViewClientImpl. I guess we’ll have to live we that for now …

@Pete.K Thank you for the clarification. I will close my PR for now …