Skip to content

Commit

Permalink
How to trigger webview loadStatedEvent after insert custom header #5
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyVerbruggen committed Mar 4, 2018
1 parent fa86679 commit 5e2b296
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 9 deletions.
10 changes: 10 additions & 0 deletions demo/app/main-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ export function webViewForUserAgentLoaded(args: observable.EventData) {
const wv: WebView = <WebView>args.object;
WebViewUtils.setUserAgent(wv, "My Super Duper User-Agent!");
}

export function webViewLoadStarted(args: any) {
const wv: WebView = <WebView>args.object;
console.log(`>>>>>>>> webViewLoadStarted, navigationType for url: ${args.url} = ${args.navigationType}`);
}

export function webViewLoadFinished(args: any) {
const wv: WebView = <WebView>args.object;
console.log(`>>>>>>>> webViewLoadFinished, url: ${args.url}`);
}
6 changes: 3 additions & 3 deletions demo/app/main-page.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<StackLayout class="p-20">

<Label text="Default headers, according to https://httpbin.org/headers:" class="t-20 text-center c-black" textWrap="true"/>
<WebView height="320" src="https://httpbin.org/headers"/>
<WebView height="320" src="https://httpbin.org/headers?wv=1"/>

<Label text="And now with custom headers:" class="t-20 text-center c-black" textWrap="true"/>
<WebView loaded="webViewLoaded" height="370" src="https://httpbin.org/headers"/>
<WebView loaded="webViewLoaded" loadStarted="webViewLoadStarted" loadFinished="webViewLoadFinished" height="370" src="https://httpbin.org/headers?wv=2"/>

<Label text="Set custom User Agent (on iOS this affects ALL webviews of your app)" class="t-20 text-center c-black" textWrap="true"/>
<WebView loaded="webViewForUserAgentLoaded" height="320" src="https://httpbin.org/headers"/>
<WebView loaded="webViewForUserAgentLoaded" height="320" src="https://httpbin.org/headers?wv=3"/>

</StackLayout>
</ScrollView>
Expand Down
4 changes: 2 additions & 2 deletions demo/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"nativescript": {
"id": "org.nativescript.demo",
"tns-android": {
"tns-ios": {
"version": "3.4.1"
},
"tns-ios": {
"tns-android": {
"version": "3.4.1"
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nativescript-webview-utils",
"version": "1.2.1",
"version": "1.3.0",
"description": "Add custom headers to a NativeScript WebView. Perhaps more utils later.",
"main": "webview-utils",
"typings": "index.d.ts",
Expand Down
47 changes: 46 additions & 1 deletion src/webview-utils.android.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { WebView } from "tns-core-modules/ui/web-view";
import { onLoadStarted, onLoadFinished } from "./webview-utils-common";

export class WebViewUtils extends android.webkit.WebViewClient {
// Note that using a static property limits usage of multiple webviews on one page with different headers,
// but I don't think that is ever a real usecase for anyone.
private static headers: Map<string, string>;
private static wv: WebView;
private headersAddedTo: Set<string> = new Set<string>();

// hackilish flag to make sure we don't fire the onLoadFinished event twice
private isFirstLoad = true;

private _view: any;
private _origClient: any; // WebViewClient

Expand All @@ -14,6 +19,7 @@ export class WebViewUtils extends android.webkit.WebViewClient {
}

public static addHeaders(wv: WebView, headers: Map<string, string>) {
WebViewUtils.wv = wv;
WebViewUtils.headers = headers;
// Wrap this in a timeout for Android, otherwise webview.android might not be initialized
setTimeout(() => {
Expand Down Expand Up @@ -42,9 +48,48 @@ export class WebViewUtils extends android.webkit.WebViewClient {

public onPageStarted(view: android.webkit.WebView, url: string, favicon: android.graphics.Bitmap): void {
super.onPageStarted(view, url, favicon);
if (this._view && url.indexOf("http") === 0 && !this.headersAddedTo.has(url)) {
const headersAdded = this.headersAddedTo.has(url);
if (this._view && url.indexOf("http") === 0 && !headersAdded) {
this._view.android.loadUrl(url, this.getAdditionalHeadersForUrl(url));
}
if (headersAdded && WebViewUtils.wv) {
onLoadStarted(WebViewUtils.wv, url, undefined);
}
}

public onPageFinished(view: android.webkit.WebView, url: string) {
super.onPageFinished(view, url);
if (!this.isFirstLoad && WebViewUtils.wv) {
onLoadFinished(WebViewUtils.wv, url, undefined);
this.isFirstLoad = true;
} else {
this.isFirstLoad = false;
}
}

public onReceivedError() {
let view: android.webkit.WebView = arguments[0];

if (arguments.length === 4) {
let errorCode: number = arguments[1];
let description: string = arguments[2];
let failingUrl: string = arguments[3];
super.onReceivedError(view, errorCode, description, failingUrl);

if (WebViewUtils.wv) {
onLoadFinished(WebViewUtils.wv, failingUrl, description + "(" + errorCode + ")");
}
} else {
let request: any = arguments[1];
let error: any = arguments[2];

super.onReceivedError(view, request, error);

const headersAdded = error.getUrl && this.headersAddedTo.has(error.getUrl());
if (headersAdded && WebViewUtils.wv) {
onLoadFinished(WebViewUtils.wv, error.getUrl && error.getUrl(), error.getDescription() + "(" + error.getErrorCode() + ")");
}
}
}

private getAdditionalHeadersForUrl(url: string): java.util.Map<String, String> {
Expand Down
49 changes: 47 additions & 2 deletions src/webview-utils.ios.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { WebView } from "tns-core-modules/ui/web-view";
import { NavigationType, WebView } from "tns-core-modules/ui/web-view";
import { onLoadFinished, onLoadStarted } from "./webview-utils-common";

class WebviewUtilsWKNavigationDelegateImpl extends NSObject implements WKNavigationDelegate {
private headers: Map<string, string>;
Expand All @@ -13,7 +14,8 @@ class WebviewUtilsWKNavigationDelegateImpl extends NSObject implements WKNavigat
private _owner: WeakRef<WebView>;

webViewDecidePolicyForNavigationActionDecisionHandler(webView: WKWebView, navigationAction: WKNavigationAction, decisionHandler: (p1: WKNavigationActionPolicy) => void): void {
if (!navigationAction.request.URL) {
const owner = this._owner.get();
if (!owner || !navigationAction.request.URL) {
return;
}

Expand Down Expand Up @@ -43,6 +45,49 @@ class WebviewUtilsWKNavigationDelegateImpl extends NSObject implements WKNavigat
webView.loadRequest(customRequest);
} else {
decisionHandler(WKNavigationActionPolicy.Allow);

let navType: NavigationType = "other";

switch (navigationAction.navigationType) {
case WKNavigationType.LinkActivated:
navType = "linkClicked";
break;
case WKNavigationType.FormSubmitted:
navType = "formSubmitted";
break;
case WKNavigationType.BackForward:
navType = "backForward";
break;
case WKNavigationType.Reload:
navType = "reload";
break;
case WKNavigationType.FormResubmitted:
navType = "formResubmitted";
break;
}
onLoadStarted(owner, navigationAction.request.URL.absoluteString, navType);
}
}

public webViewDidFinishNavigation(webView: WKWebView, navigation: WKNavigation): void {
const owner = this._owner.get();
if (owner) {
let src = owner.src;
if (webView.URL) {
src = webView.URL.absoluteString;
}
onLoadFinished(owner, src);
}
}

public webViewDidFailNavigationWithError(webView: WKWebView, navigation: WKNavigation, error: NSError): void {
const owner = this._owner.get();
if (owner) {
let src = owner.src;
if (webView.URL) {
src = webView.URL.absoluteString;
}
onLoadFinished(owner, src, error.localizedDescription);
}
}
}
Expand Down

0 comments on commit 5e2b296

Please sign in to comment.