Skip to content

Commit 31d1019

Browse files
triniwizHristo Hristov
authored andcommitted
WebView upgrade [IOS] (NativeScript#5093)
* WebView upgrade [IOS] * lint fixes * Content scaling fix
1 parent 53923d3 commit 31d1019

File tree

3 files changed

+71
-62
lines changed

3 files changed

+71
-62
lines changed

tests/app/ui/web-view/web-view-tests.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,16 @@ export class WebViewTest extends testModule.UITest<webViewModule.WebView> {
5757
// >> (hide)
5858
let actual;
5959
let expectedTitle = 'MyTitle';
60-
let expectedHtml = '<span style="color:red">TestÖ</span>';
6160

6261
if (webView.ios) {
63-
actual = webView.ios.stringByEvaluatingJavaScriptFromString("document.body.innerHTML").trim();
62+
actual = webView.ios.title;
6463
} else if (webView.android) {
6564
actual = webView.android.getTitle();
6665
}
6766

6867
try {
6968
TKUnit.assertNull(args.error, args.error);
70-
TKUnit.assertEqual(actual, webView.ios ? expectedHtml : expectedTitle, "File ~/ui/web-view/test.html not loaded properly.");
69+
TKUnit.assertEqual(actual, expectedTitle, "File ~/ui/web-view/test.html not loaded properly.");
7170
done(null);
7271
}
7372
catch (e) {
@@ -93,17 +92,16 @@ export class WebViewTest extends testModule.UITest<webViewModule.WebView> {
9392
webView.on(webViewModule.WebView.loadFinishedEvent, function (args: webViewModule.LoadEventData) {
9493
let actual;
9594
let expectedTitle = 'MyTitle';
96-
let expectedHtml = '<span style="color:red">TestÖ with Spaces</span>';
9795

9896
if (webView.ios) {
99-
actual = webView.ios.stringByEvaluatingJavaScriptFromString("document.body.innerHTML").trim();
97+
actual = webView.ios.title;
10098
} else if (webView.android) {
10199
actual = webView.android.getTitle();
102100
}
103101

104102
try {
105103
TKUnit.assertNull(args.error, args.error);
106-
TKUnit.assertEqual(actual, webView.ios ? expectedHtml : expectedTitle, "File ~/ui/web-view/test.html not loaded properly.");
104+
TKUnit.assertEqual(actual, expectedTitle, "File ~/ui/web-view/test.html not loaded properly.");
107105
done(null);
108106
}
109107
catch (e) {
@@ -129,14 +127,12 @@ export class WebViewTest extends testModule.UITest<webViewModule.WebView> {
129127
// >> (hide)
130128

131129
let actual;
132-
let expected;
130+
const expected = 'MyTitle';
133131

134132
if (webView.ios) {
135-
actual = webView.ios.stringByEvaluatingJavaScriptFromString("document.body.innerHTML").trim();
136-
expected = '<span style="color:red">TestÖ</span>';
133+
actual = webView.ios.title;
137134
} else if (webView.android) {
138135
actual = webView.android.getTitle();
139-
expected = 'MyTitle';
140136
}
141137

142138
try {

tns-core-modules/ui/web-view/web-view.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ export class WebView extends View {
3535
android: any /* android.webkit.WebView */;
3636

3737
/**
38-
* Gets the native [UIWebView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/) that represents the user interface for this component. Valid only when running on iOS.
38+
* Gets the native [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview/) that represents the user interface for this component. Valid only when running on iOS.
3939
*/
40-
ios: any /* UIWebView */;
40+
ios: any /* WKWebView */;
4141

4242
/**
4343
* Gets or sets the url, local file path or HTML string.

tns-core-modules/ui/web-view/web-view.ios.ts

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,123 @@
11
import { WebViewBase, knownFolders, traceWrite, traceEnabled, traceCategories, NavigationType } from "./web-view-common";
22
import { profile } from "../../profiling";
3-
3+
import { layout } from "../core/view";
44
export * from "./web-view-common";
55

6-
class UIWebViewDelegateImpl extends NSObject implements UIWebViewDelegate {
7-
public static ObjCProtocols = [UIWebViewDelegate];
8-
9-
private _owner: WeakRef<WebView>;
10-
11-
public static initWithOwner(owner: WeakRef<WebView>): UIWebViewDelegateImpl {
12-
let delegate = <UIWebViewDelegateImpl>UIWebViewDelegateImpl.new();
13-
delegate._owner = owner;
14-
return delegate;
6+
class WKNavigationDelegateImpl extends NSObject
7+
implements WKNavigationDelegate {
8+
public static ObjCProtocols = [WKNavigationDelegate];
9+
public static initWithOwner(owner: WeakRef<WebView>): WKNavigationDelegateImpl {
10+
const handler = <WKNavigationDelegateImpl>WKNavigationDelegateImpl.new();
11+
handler._owner = owner;
12+
return handler;
1513
}
14+
private _owner: WeakRef<WebView>;
1615

17-
public webViewShouldStartLoadWithRequestNavigationType(webView: UIWebView, request: NSURLRequest, navigationType: number) {
18-
let owner = this._owner.get();
19-
20-
if (owner && request.URL) {
16+
public webViewDecidePolicyForNavigationActionDecisionHandler(webView: WKWebView, navigationAction: WKNavigationAction, decisionHandler: any): void {
17+
const owner = this._owner.get();
18+
if (owner && navigationAction.request.URL) {
2119
let navType: NavigationType = "other";
2220

23-
switch (navigationType) {
24-
case UIWebViewNavigationType.LinkClicked:
21+
switch (navigationAction.navigationType) {
22+
case WKNavigationType.LinkActivated:
2523
navType = "linkClicked";
2624
break;
27-
case UIWebViewNavigationType.FormSubmitted:
25+
case WKNavigationType.FormSubmitted:
2826
navType = "formSubmitted";
2927
break;
30-
case UIWebViewNavigationType.BackForward:
28+
case WKNavigationType.BackForward:
3129
navType = "backForward";
3230
break;
33-
case UIWebViewNavigationType.Reload:
31+
case WKNavigationType.Reload:
3432
navType = "reload";
3533
break;
36-
case UIWebViewNavigationType.FormResubmitted:
34+
case WKNavigationType.FormResubmitted:
3735
navType = "formResubmitted";
3836
break;
3937
}
38+
decisionHandler(WKNavigationActionPolicy.Allow);
4039

4140
if (traceEnabled()) {
42-
traceWrite("UIWebViewDelegateClass.webViewShouldStartLoadWithRequestNavigationType(" + request.URL.absoluteString + ", " + navigationType + ")", traceCategories.Debug);
41+
traceWrite("WKNavigationDelegateClass.webViewDecidePolicyForNavigationActionDecisionHandler(" + navigationAction.request.URL.absoluteString + ", " + navigationAction.navigationType + ")", traceCategories.Debug);
4342
}
44-
owner._onLoadStarted(request.URL.absoluteString, navType);
43+
owner._onLoadStarted(navigationAction.request.URL.absoluteString, navType);
4544
}
46-
47-
return true;
4845
}
4946

50-
public webViewDidStartLoad(webView: UIWebView) {
47+
public webViewDidStartProvisionalNavigation(webView: WKWebView, navigation: WKNavigation): void {
5148
if (traceEnabled()) {
52-
traceWrite("UIWebViewDelegateClass.webViewDidStartLoad(" + webView.request.URL + ")", traceCategories.Debug);
49+
traceWrite("WKNavigationDelegateClass.webViewDidStartProvisionalNavigation(" + webView.URL + ")", traceCategories.Debug);
5350
}
54-
}
51+
};
5552

56-
public webViewDidFinishLoad(webView: UIWebView) {
53+
public webViewDidFinishNavigation(webView: WKWebView, navigation: WKNavigation): void {
5754
if (traceEnabled()) {
58-
traceWrite("UIWebViewDelegateClass.webViewDidFinishLoad(" + webView.request.URL + ")", traceCategories.Debug);
55+
traceWrite("WKNavigationDelegateClass.webViewDidFinishNavigation(" + webView.URL + ")", traceCategories.Debug);
5956
}
60-
let owner = this._owner.get();
61-
57+
const owner = this._owner.get();
6258
if (owner) {
59+
webView.evaluateJavaScriptCompletionHandler("document.body.height",(val,err)=>{
60+
console.log(val);
61+
});
6362
let src = owner.src;
64-
if (webView.request && webView.request.URL) {
65-
src = webView.request.URL.absoluteString;
63+
if (webView.URL) {
64+
src = webView.URL.absoluteString;
6665
}
6766
owner._onLoadFinished(src);
6867
}
6968
}
7069

71-
public webViewDidFailLoadWithError(webView: UIWebView, error: NSError) {
72-
let owner = this._owner.get();
70+
public webViewDidFailNavigationWithError(webView: WKWebView, navigation: WKNavigation, error: NSError): void {
71+
const owner = this._owner.get();
7372
if (owner) {
7473
let src = owner.src;
75-
if (webView.request && webView.request.URL) {
76-
src = webView.request.URL.absoluteString;
74+
if (webView.URL) {
75+
src = webView.URL.absoluteString;
7776
}
78-
7977
if (traceEnabled()) {
80-
traceWrite("UIWebViewDelegateClass.webViewDidFailLoadWithError(" + error.localizedDescription + ")", traceCategories.Debug);
81-
}
82-
if (owner) {
83-
owner._onLoadFinished(src, error.localizedDescription);
78+
traceWrite("WKNavigationDelegateClass.webViewDidFailNavigationWithError(" + error.localizedDescription + ")", traceCategories.Debug);
8479
}
80+
owner._onLoadFinished(src, error.localizedDescription);
8581
}
8682
}
83+
8784
}
8885

8986
export class WebView extends WebViewBase {
90-
private _ios: UIWebView;
87+
private _ios: WKWebView;
9188
private _delegate: any;
9289

9390
constructor() {
9491
super();
95-
96-
this.nativeViewProtected = this._ios = UIWebView.new();
97-
this._delegate = UIWebViewDelegateImpl.initWithOwner(new WeakRef(this));
92+
const configuration = WKWebViewConfiguration.new();
93+
this._delegate = WKNavigationDelegateImpl.initWithOwner(new WeakRef(this));
94+
const jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);";
95+
const wkUScript = WKUserScript.alloc().initWithSourceInjectionTimeForMainFrameOnly(jScript,WKUserScriptInjectionTime.AtDocumentEnd,true);
96+
const wkUController = WKUserContentController.new();
97+
wkUController.addUserScript(wkUScript);
98+
configuration.userContentController = wkUController;
99+
configuration.preferences.setValueForKey(
100+
true,
101+
'allowFileAccessFromFileURLs'
102+
);
103+
this.nativeViewProtected = this._ios = new WKWebView({
104+
frame: CGRectZero,
105+
configuration:configuration
106+
});
98107
}
99108

100109
@profile
101110
public onLoaded() {
102111
super.onLoaded();
103-
this._ios.delegate = this._delegate;
112+
this._ios.navigationDelegate = this._delegate;
104113
}
105114

106115
public onUnloaded() {
107-
this._ios.delegate = null;
116+
this._ios.navigationDelegate = null;
108117
super.onUnloaded();
109118
}
110119

111-
get ios(): UIWebView {
120+
get ios(): WKWebView {
112121
return this._ios;
113122
}
114123

@@ -117,7 +126,11 @@ export class WebView extends WebViewBase {
117126
}
118127

119128
public _loadUrl(src: string) {
120-
this._ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src)));
129+
if(src.startsWith('file:///')){
130+
this._ios.loadFileURLAllowingReadAccessToURL(NSURL.URLWithString(src), NSURL.URLWithString(src));
131+
}else{
132+
this._ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src)));
133+
}
121134
}
122135

123136
public _loadData(content: string) {

0 commit comments

Comments
 (0)