cronapp-cordova-plugin-ionic-webview 4.4.0-RC7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmrc +1 -0
- package/CHANGELOG.md +278 -0
- package/CONTRIBUTING.md +32 -0
- package/LICENSE +202 -0
- package/README.md +184 -0
- package/package.json +75 -0
- package/plugin.xml +80 -0
- package/src/android/com/ionicframework/cordova/webview/AndroidProtocolHandler.java +107 -0
- package/src/android/com/ionicframework/cordova/webview/IonicWebView.java +41 -0
- package/src/android/com/ionicframework/cordova/webview/IonicWebViewEngine.java +172 -0
- package/src/android/com/ionicframework/cordova/webview/UriMatcher.java +183 -0
- package/src/android/com/ionicframework/cordova/webview/WebViewLocalServer.java +645 -0
- package/src/ios/CDVWKProcessPoolFactory.h +27 -0
- package/src/ios/CDVWKProcessPoolFactory.m +49 -0
- package/src/ios/CDVWKWebViewEngine.h +31 -0
- package/src/ios/CDVWKWebViewEngine.m +886 -0
- package/src/ios/CDVWKWebViewUIDelegate.h +28 -0
- package/src/ios/CDVWKWebViewUIDelegate.m +123 -0
- package/src/ios/IONAssetHandler.h +13 -0
- package/src/ios/IONAssetHandler.m +92 -0
- package/src/ios/LICENSE +22 -0
- package/src/ios/wk-plugin.js +39 -0
- package/src/www/ios/ios-wkwebview-exec.js +174 -0
- package/src/www/util.js +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
# license: Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
|
4
|
+
# distributed with this work for additional information
|
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
|
7
|
+
# "License"); you may not use this file except in compliance
|
|
8
|
+
# with the License. You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
|
13
|
+
# software distributed under the License is distributed on an
|
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
# KIND, either express or implied. See the License for the
|
|
16
|
+
# specific language governing permissions and limitations
|
|
17
|
+
# under the License.
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
<!-- TODO: remove beta in README.md and CONTRIBUTING.md -->
|
|
21
|
+
|
|
22
|
+
[//]: # (Updated by magellandevs: 22/05/2026)
|
|
23
|
+
[](https://github.com/semantic-release/semantic-release)
|
|
24
|
+
[](https://dependabot.com)
|
|
25
|
+
[](https://www.npmjs.com/package/cronapp-cordova-plugin-ionic-webview)
|
|
26
|
+
|
|
27
|
+
# Ionic Web View for Cordova
|
|
28
|
+
|
|
29
|
+
A Web View plugin for Cordova, focused on providing the highest performance experience for Ionic apps (but can be used with any Cordova app).
|
|
30
|
+
|
|
31
|
+
This plugin uses WKWebView on iOS and the latest evergreen webview on Android. Additionally, this plugin makes it easy to use HTML5 style routing that web developers expect for building single-page apps.
|
|
32
|
+
|
|
33
|
+
Note: This repo and its documentation are for `cronapp-cordova-plugin-ionic-webview` @ `5.x`, which uses the new features that may not work with all apps. See [Requirements](#plugin-requirements) and [Migrating to 5.x](#migrating-to-5x).
|
|
34
|
+
|
|
35
|
+
2.x documentation can be found [here](https://github.com/ionic-team/cronapp-cordova-plugin-ionic-webview/blob/2.x/README.md).
|
|
36
|
+
|
|
37
|
+
:book: **Documentation**: [https://beta.ionicframework.com/docs/building/webview][ionic-webview-docs]
|
|
38
|
+
|
|
39
|
+
:mega: **Support/Questions?** Please see our [Support Page][ionic-support] for general support questions. The issues on GitHub should be reserved for bug reports and feature requests.
|
|
40
|
+
|
|
41
|
+
:sparkling_heart: **Want to contribute?** Please see [CONTRIBUTING.md](https://github.com/ionic-team/cronapp-cordova-plugin-ionic-webview/blob/master/CONTRIBUTING.md).
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
This plugin has several configuration options that can be set in `config.xml`.
|
|
46
|
+
|
|
47
|
+
### Android and iOS Preferences
|
|
48
|
+
|
|
49
|
+
Preferences available for both iOS and Android
|
|
50
|
+
|
|
51
|
+
#### Hostname
|
|
52
|
+
|
|
53
|
+
`<preference name="Hostname" value="app" />`
|
|
54
|
+
|
|
55
|
+
Default value is `localhost`.
|
|
56
|
+
|
|
57
|
+
Example `ionic://app` on iOS, `http://app` on Android.
|
|
58
|
+
|
|
59
|
+
If you change it, you'll need to add a new `allow-navigation` entry in the `config.xml` for the configured url (i.e `<allow-navigation href="http://app/*"/>` if `Hostname` is set to `app`).
|
|
60
|
+
This is only needed for the Android url when using `http://`, `https://` or a custom scheme. All `ionic://` urls are whitelisted by the plugin.
|
|
61
|
+
|
|
62
|
+
### Android Preferences
|
|
63
|
+
|
|
64
|
+
Preferences only available Android platform
|
|
65
|
+
|
|
66
|
+
#### Scheme
|
|
67
|
+
|
|
68
|
+
```xml
|
|
69
|
+
<preference name="Scheme" value="https" />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Default value is `http`
|
|
73
|
+
|
|
74
|
+
Configures the Scheme the app uses to load the content.
|
|
75
|
+
|
|
76
|
+
#### ResolveServiceWorkerRequests
|
|
77
|
+
|
|
78
|
+
```xml
|
|
79
|
+
<preference name="ResolveServiceWorkerRequests" value="true" />
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Default value is `false`
|
|
83
|
+
|
|
84
|
+
Enable to resolve requests made by Service Workers through the local server.
|
|
85
|
+
|
|
86
|
+
#### MixedContentMode
|
|
87
|
+
|
|
88
|
+
```xml
|
|
89
|
+
<preference name="MixedContentMode" value="2" />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Configures the WebView's behavior when an origin attempts to load a resource from a different origin.
|
|
93
|
+
|
|
94
|
+
Default value is `0` (`MIXED_CONTENT_ALWAYS_ALLOW`), which allows loading resources from other origins.
|
|
95
|
+
|
|
96
|
+
Other possible values are `1` (`MIXED_CONTENT_NEVER_ALLOW`) and `2` (`MIXED_CONTENT_COMPATIBILITY_MODE`)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
[Android documentation](https://developer.android.com/reference/android/webkit/WebSettings.html#setMixedContentMode(int))
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### iOS Preferences
|
|
103
|
+
|
|
104
|
+
Preferences only available for iOS platform
|
|
105
|
+
|
|
106
|
+
#### iosScheme
|
|
107
|
+
|
|
108
|
+
```xml
|
|
109
|
+
<preference name="iosScheme" value="httpsionic" />
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Default value is `ionic`
|
|
113
|
+
|
|
114
|
+
Configures the Scheme the app uses to load the content.
|
|
115
|
+
|
|
116
|
+
Values like `http`, `https` or `file` are not valid and will use default value instead.
|
|
117
|
+
|
|
118
|
+
If you change it, you'll need to add a new `allow-navigation` entry in the `config.xml` for the configured scheme (i.e `<allow-navigation href="httpsionic://*"/>` if `iosScheme` is set to `httpsionic`).
|
|
119
|
+
|
|
120
|
+
#### WKSuspendInBackground
|
|
121
|
+
|
|
122
|
+
```xml
|
|
123
|
+
<preference name="WKSuspendInBackground" value="false" />
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Default value is `true` (suspend).
|
|
127
|
+
|
|
128
|
+
Set to false to stop WKWebView suspending in background too eagerly.
|
|
129
|
+
|
|
130
|
+
#### KeyboardAppearanceDark
|
|
131
|
+
|
|
132
|
+
```xml
|
|
133
|
+
<preference name="KeyboardAppearanceDark" value="false" />
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Whether to use a dark styled keyboard on iOS
|
|
137
|
+
|
|
138
|
+
#### ScrollEnabled
|
|
139
|
+
|
|
140
|
+
```xml
|
|
141
|
+
<preference name="ScrollEnabled" value="true" />
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Ionic apps work better if the WKWebView is not scrollable, so the scroll is disabled by default, but can be enabled with this preference. This only affects the main ScrollView of the WKWebView, so only affects the body, not other scrollable components.
|
|
145
|
+
|
|
146
|
+
## Plugin Requirements
|
|
147
|
+
|
|
148
|
+
* **Cordova CLI**: 7.1.0+
|
|
149
|
+
* **iOS**: iOS 11+ and `cordova-ios` 4+
|
|
150
|
+
* **Android**: Android 5+ and `cordova-android` 6.4+
|
|
151
|
+
|
|
152
|
+
## Migrating to 5.x
|
|
153
|
+
|
|
154
|
+
1. Remove and re-add the Web View plugin:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
cordova plugin rm cronapp-cordova-plugin-ionic-webview
|
|
158
|
+
cordova plugin add cronapp-cordova-plugin-ionic-webview@latest
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
1. If using `cordova-android` < 9, make sure you have `<preference name="android-minSdkVersion" value="21" />` in the config.xml as this version of the plugin only supports Android 5+ (SDK 21+). If using `cordova-android` >= 9 is not neccessary as `cordova-android` 9 only supports Android 5.1+ (SDK 22+)
|
|
162
|
+
|
|
163
|
+
1. Since version 2, apps are served from HTTP on Android by default.
|
|
164
|
+
|
|
165
|
+
* The default origin for requests from the Android WebView is `http://localhost`. If `Hostname` and `Scheme` preferences are set, then origin will be `schemeValue://HostnameValue`.
|
|
166
|
+
|
|
167
|
+
1. Since version 3, apps are served from `ionic://` scheme on iOS by default.
|
|
168
|
+
|
|
169
|
+
* The default origin for requests from the iOS WebView is `ionic://localhost`. If `Hostname` and `iosScheme` preferences are set, then origin will be `iosSchemeValue://HostnameValue`.
|
|
170
|
+
|
|
171
|
+
1. The WebView is not able to display images, videos or other files from file or content protocols or if it doesn't have protocol at all. For those cases use `window.Ionic.WebView.convertFileSrc()` to get the proper url.
|
|
172
|
+
|
|
173
|
+
1. Replace any usages of `window.Ionic.normalizeURL()` and `window.wkRewriteURL()` with `window.Ionic.WebView.convertFileSrc()`.
|
|
174
|
+
|
|
175
|
+
* For Ionic Angular projects, there is an [Ionic Native wrapper](https://beta.ionicframework.com/docs/native/ionic-webview):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
npm install @ionic-native/ionic-webview@latest
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
[ionic-homepage]: https://ionicframework.com
|
|
182
|
+
[ionic-docs]: https://ionicframework.com/docs
|
|
183
|
+
[ionic-webview-docs]: https://beta.ionicframework.com/docs/building/webview
|
|
184
|
+
[ionic-support]: https://ionicframework.com/support
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cronapp-cordova-plugin-ionic-webview",
|
|
3
|
+
"version": "4.4.0-RC7",
|
|
4
|
+
"description": "Ionic Web View Engine Plugin",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"sync_plugin_xml": "sync-cordova-xml package.json plugin.xml --output=plugin.xml",
|
|
7
|
+
"version": "npm run sync_plugin_xml && git add plugin.xml",
|
|
8
|
+
"cz": "git-cz"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/magellandevs/cronapp-cordova-plugin-ionic-webview"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"cordova",
|
|
16
|
+
"wkwebview"
|
|
17
|
+
],
|
|
18
|
+
"author": "magellandevs",
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"engines": {
|
|
21
|
+
"cordovaDependencies": {
|
|
22
|
+
"2.0.0": {
|
|
23
|
+
"cordova-android": ">=6.4.0",
|
|
24
|
+
"cordova-ios": ">=4.0.0-dev"
|
|
25
|
+
},
|
|
26
|
+
"3.1.0": {
|
|
27
|
+
"cordova-android": ">=6.4.0",
|
|
28
|
+
"cordova-ios": ">=4.0.0-dev",
|
|
29
|
+
"cordova": ">=7.1.0"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@semantic-release/changelog": "^3.0.0",
|
|
35
|
+
"@semantic-release/exec": "^3.3.0",
|
|
36
|
+
"@semantic-release/git": "^7.0.4",
|
|
37
|
+
"@semantic-release/github": "^5.0.6",
|
|
38
|
+
"@semantic-release/npm": "^5.0.4",
|
|
39
|
+
"commitizen": "^4.0.3",
|
|
40
|
+
"cz-conventional-changelog": "^3.0.2",
|
|
41
|
+
"semantic-release": "^15.9.17",
|
|
42
|
+
"sync-cordova-xml": "^0.4.0"
|
|
43
|
+
},
|
|
44
|
+
"release": {
|
|
45
|
+
"branch": "stable",
|
|
46
|
+
"verifyConditions": [
|
|
47
|
+
"@semantic-release/changelog",
|
|
48
|
+
"@semantic-release/npm",
|
|
49
|
+
"@semantic-release/git",
|
|
50
|
+
"@semantic-release/github"
|
|
51
|
+
],
|
|
52
|
+
"prepare": [
|
|
53
|
+
"@semantic-release/changelog",
|
|
54
|
+
"@semantic-release/npm",
|
|
55
|
+
"@semantic-release/exec",
|
|
56
|
+
"@semantic-release/git"
|
|
57
|
+
],
|
|
58
|
+
"publish": [
|
|
59
|
+
"@semantic-release/github",
|
|
60
|
+
"@semantic-release/npm"
|
|
61
|
+
],
|
|
62
|
+
"success": [
|
|
63
|
+
"@semantic-release/github"
|
|
64
|
+
],
|
|
65
|
+
"failure": [
|
|
66
|
+
"@semantic-release/github"
|
|
67
|
+
],
|
|
68
|
+
"prepareCmd": "npm run version"
|
|
69
|
+
},
|
|
70
|
+
"config": {
|
|
71
|
+
"commitizen": {
|
|
72
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
package/plugin.xml
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Licensed to the Apache Software Foundation (ASF) under one
|
|
4
|
+
or more contributor license agreements. See the NOTICE file
|
|
5
|
+
distributed with this work for additional information
|
|
6
|
+
regarding copyright ownership. The ASF licenses this file
|
|
7
|
+
to you under the Apache License, Version 2.0 (the
|
|
8
|
+
"License"); you may not use this file except in compliance
|
|
9
|
+
with the License. You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing,
|
|
14
|
+
software distributed under the License is distributed on an
|
|
15
|
+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
+
KIND, either express or implied. See the License for the
|
|
17
|
+
specific language governing permissions and limitations
|
|
18
|
+
under the License.
|
|
19
|
+
--><plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:rim="http://www.blackberry.com/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" id="cronapp-cordova-plugin-ionic-webview" version="4.4.0-RC7">
|
|
20
|
+
<name>cronapp-cordova-plugin-ionic-webview</name>
|
|
21
|
+
<description>Ionic Web View Engine Plugin</description>
|
|
22
|
+
<license>Apache-2.0</license>
|
|
23
|
+
<keywords>cordova,wkwebview</keywords>
|
|
24
|
+
<repo>https://github.com/magellandevs/cronapp-cordova-plugin-ionic-webview</repo>
|
|
25
|
+
|
|
26
|
+
<engines>
|
|
27
|
+
<engine name="cordova" version=">=7.1.0"/>
|
|
28
|
+
<engine name="cordova-ios" version=">=4.0.0-dev"/>
|
|
29
|
+
<engine name="apple-ios" version=">=11.0"/>
|
|
30
|
+
<engine name="cordova-android" version=">=6.4.0"/>
|
|
31
|
+
</engines>
|
|
32
|
+
|
|
33
|
+
<js-module src="src/www/util.js" name="IonicWebView">
|
|
34
|
+
<clobbers target="Ionic.WebView"/>
|
|
35
|
+
</js-module>
|
|
36
|
+
|
|
37
|
+
<platform name="android">
|
|
38
|
+
<config-file target="config.xml" parent="/*">
|
|
39
|
+
<allow-navigation href="http://localhost/*"/>
|
|
40
|
+
<allow-navigation href="https://localhost/*"/>
|
|
41
|
+
<allow-navigation href="ionic://*"/>
|
|
42
|
+
<preference name="webView" value="com.ionicframework.cordova.webview.IonicWebViewEngine"/>
|
|
43
|
+
<feature name="IonicWebView">
|
|
44
|
+
<param name="android-package" value="com.ionicframework.cordova.webview.IonicWebView"/>
|
|
45
|
+
</feature>
|
|
46
|
+
</config-file>
|
|
47
|
+
<source-file src="src/android/com/ionicframework/cordova/webview/IonicWebViewEngine.java" target-dir="src/com/ionicframework/cordova/webview"/>
|
|
48
|
+
<source-file src="src/android/com/ionicframework/cordova/webview/IonicWebView.java" target-dir="src/com/ionicframework/cordova/webview"/>
|
|
49
|
+
<source-file src="src/android/com/ionicframework/cordova/webview/AndroidProtocolHandler.java" target-dir="src/com/ionicframework/cordova/webview"/>
|
|
50
|
+
<source-file src="src/android/com/ionicframework/cordova/webview/UriMatcher.java" target-dir="src/com/ionicframework/cordova/webview"/>
|
|
51
|
+
<source-file src="src/android/com/ionicframework/cordova/webview/WebViewLocalServer.java" target-dir="src/com/ionicframework/cordova/webview"/>
|
|
52
|
+
</platform>
|
|
53
|
+
|
|
54
|
+
<!-- ios -->
|
|
55
|
+
<platform name="ios">
|
|
56
|
+
<js-module src="src/www/ios/ios-wkwebview-exec.js" name="ios-wkwebview-exec">
|
|
57
|
+
<clobbers target="cordova.exec"/>
|
|
58
|
+
</js-module>
|
|
59
|
+
|
|
60
|
+
<config-file target="config.xml" parent="/*">
|
|
61
|
+
<allow-navigation href="ionic://*"/>
|
|
62
|
+
<feature name="IonicWebView">
|
|
63
|
+
<param name="ios-package" value="CDVWKWebViewEngine"/>
|
|
64
|
+
</feature>
|
|
65
|
+
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine"/>
|
|
66
|
+
</config-file>
|
|
67
|
+
|
|
68
|
+
<framework src="WebKit.framework" weak="true"/>
|
|
69
|
+
|
|
70
|
+
<header-file src="src/ios/CDVWKWebViewEngine.h"/>
|
|
71
|
+
<source-file src="src/ios/CDVWKWebViewEngine.m"/>
|
|
72
|
+
<header-file src="src/ios/CDVWKWebViewUIDelegate.h"/>
|
|
73
|
+
<source-file src="src/ios/CDVWKWebViewUIDelegate.m"/>
|
|
74
|
+
<header-file src="src/ios/CDVWKProcessPoolFactory.h"/>
|
|
75
|
+
<source-file src="src/ios/CDVWKProcessPoolFactory.m"/>
|
|
76
|
+
<header-file src="src/ios/IONAssetHandler.h"/>
|
|
77
|
+
<source-file src="src/ios/IONAssetHandler.m"/>
|
|
78
|
+
<asset src="src/ios/wk-plugin.js" target="wk-plugin.js"/>
|
|
79
|
+
</platform>
|
|
80
|
+
</plugin>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package com.ionicframework.cordova.webview;
|
|
2
|
+
|
|
3
|
+
// Copyright 2012 The Chromium Authors. All rights reserved.
|
|
4
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
5
|
+
// found in the LICENSE file.
|
|
6
|
+
|
|
7
|
+
import android.content.Context;
|
|
8
|
+
import android.content.res.AssetManager;
|
|
9
|
+
import android.net.Uri;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
import android.util.TypedValue;
|
|
12
|
+
|
|
13
|
+
import java.io.File;
|
|
14
|
+
import java.io.FileInputStream;
|
|
15
|
+
import java.io.IOException;
|
|
16
|
+
import java.io.InputStream;
|
|
17
|
+
import java.util.List;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
public class AndroidProtocolHandler {
|
|
21
|
+
private static final String TAG = "AndroidProtocolHandler";
|
|
22
|
+
|
|
23
|
+
private Context context;
|
|
24
|
+
|
|
25
|
+
public AndroidProtocolHandler(Context context) {
|
|
26
|
+
this.context = context;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public InputStream openAsset(String path) throws IOException {
|
|
30
|
+
return context.getAssets().open(path, AssetManager.ACCESS_STREAMING);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public InputStream openResource(Uri uri) {
|
|
34
|
+
assert uri.getPath() != null;
|
|
35
|
+
// The path must be of the form ".../asset_type/asset_name.ext".
|
|
36
|
+
List<String> pathSegments = uri.getPathSegments();
|
|
37
|
+
String assetType = pathSegments.get(pathSegments.size() - 2);
|
|
38
|
+
String assetName = pathSegments.get(pathSegments.size() - 1);
|
|
39
|
+
|
|
40
|
+
// Drop the file extension.
|
|
41
|
+
assetName = assetName.split("\\.")[0];
|
|
42
|
+
try {
|
|
43
|
+
// Use the application context for resolving the resource package name so that we do
|
|
44
|
+
// not use the browser's own resources. Note that if 'context' here belongs to the
|
|
45
|
+
// test suite, it does not have a separate application context. In that case we use
|
|
46
|
+
// the original context object directly.
|
|
47
|
+
if (context.getApplicationContext() != null) {
|
|
48
|
+
context = context.getApplicationContext();
|
|
49
|
+
}
|
|
50
|
+
int fieldId = getFieldId(context, assetType, assetName);
|
|
51
|
+
int valueType = getValueType(context, fieldId);
|
|
52
|
+
if (valueType == TypedValue.TYPE_STRING) {
|
|
53
|
+
return context.getResources().openRawResource(fieldId);
|
|
54
|
+
} else {
|
|
55
|
+
Log.e(TAG, "Asset not of type string: " + uri);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
} catch (ClassNotFoundException e) {
|
|
59
|
+
Log.e(TAG, "Unable to open resource URL: " + uri, e);
|
|
60
|
+
return null;
|
|
61
|
+
} catch (NoSuchFieldException e) {
|
|
62
|
+
Log.e(TAG, "Unable to open resource URL: " + uri, e);
|
|
63
|
+
return null;
|
|
64
|
+
} catch (IllegalAccessException e) {
|
|
65
|
+
Log.e(TAG, "Unable to open resource URL: " + uri, e);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public InputStream openFile(String filePath) throws IOException {
|
|
71
|
+
String realPath = filePath.replace(WebViewLocalServer.fileStart, "");
|
|
72
|
+
File localFile = new File(realPath);
|
|
73
|
+
return new FileInputStream(localFile);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public InputStream openContentUrl(Uri uri) throws IOException {
|
|
77
|
+
Integer port = uri.getPort();
|
|
78
|
+
String realPath;
|
|
79
|
+
if (port == -1) {
|
|
80
|
+
realPath = uri.toString().replace(uri.getScheme() + "://" + uri.getHost() + WebViewLocalServer.contentStart, "content:/");
|
|
81
|
+
} else {
|
|
82
|
+
realPath = uri.toString().replace(uri.getScheme() + "://" + uri.getHost() + ":" + port + WebViewLocalServer.contentStart, "content:/");
|
|
83
|
+
}
|
|
84
|
+
InputStream stream = null;
|
|
85
|
+
try {
|
|
86
|
+
stream = context.getContentResolver().openInputStream(Uri.parse(realPath));
|
|
87
|
+
} catch (SecurityException e) {
|
|
88
|
+
Log.e(TAG, "Unable to open content URL: " + uri, e);
|
|
89
|
+
}
|
|
90
|
+
return stream;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private static int getFieldId(Context context, String assetType, String assetName)
|
|
94
|
+
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
|
95
|
+
Class<?> d = context.getClassLoader()
|
|
96
|
+
.loadClass(context.getPackageName() + ".R$" + assetType);
|
|
97
|
+
java.lang.reflect.Field field = d.getField(assetName);
|
|
98
|
+
int id = field.getInt(null);
|
|
99
|
+
return id;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private static int getValueType(Context context, int fieldId) {
|
|
103
|
+
TypedValue value = new TypedValue();
|
|
104
|
+
context.getResources().getValue(fieldId, value, true);
|
|
105
|
+
return value.type;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package com.ionicframework.cordova.webview;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
5
|
+
|
|
6
|
+
import org.apache.cordova.CallbackContext;
|
|
7
|
+
import org.apache.cordova.CordovaPlugin;
|
|
8
|
+
import org.json.JSONArray;
|
|
9
|
+
import org.json.JSONException;
|
|
10
|
+
|
|
11
|
+
public class IonicWebView extends CordovaPlugin {
|
|
12
|
+
|
|
13
|
+
public static final String WEBVIEW_PREFS_NAME = "WebViewSettings";
|
|
14
|
+
public static final String CDV_SERVER_PATH = "serverBasePath";
|
|
15
|
+
|
|
16
|
+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
17
|
+
|
|
18
|
+
if (action.equals("setServerBasePath")) {
|
|
19
|
+
final String path = args.getString(0);
|
|
20
|
+
cordova.getActivity().runOnUiThread(new Runnable() {
|
|
21
|
+
public void run() {
|
|
22
|
+
((IonicWebViewEngine)webView.getEngine()).setServerBasePath(path);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return true;
|
|
26
|
+
} else if (action.equals("getServerBasePath")) {
|
|
27
|
+
callbackContext.success(((IonicWebViewEngine)webView.getEngine()).getServerBasePath());
|
|
28
|
+
return true;
|
|
29
|
+
} else if (action.equals("persistServerBasePath")) {
|
|
30
|
+
String path = ((IonicWebViewEngine)webView.getEngine()).getServerBasePath();
|
|
31
|
+
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
32
|
+
SharedPreferences.Editor editor = prefs.edit();
|
|
33
|
+
editor.putString(CDV_SERVER_PATH, path);
|
|
34
|
+
editor.apply();
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
package com.ionicframework.cordova.webview;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.SharedPreferences;
|
|
6
|
+
import android.content.pm.PackageInfo;
|
|
7
|
+
import android.graphics.Bitmap;
|
|
8
|
+
import android.net.Uri;
|
|
9
|
+
import android.os.Build;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
import android.webkit.ServiceWorkerController;
|
|
12
|
+
import android.webkit.ServiceWorkerClient;
|
|
13
|
+
import android.webkit.WebResourceRequest;
|
|
14
|
+
import android.webkit.WebResourceResponse;
|
|
15
|
+
import android.webkit.WebSettings;
|
|
16
|
+
import android.webkit.WebView;
|
|
17
|
+
import org.apache.cordova.ConfigXmlParser;
|
|
18
|
+
import org.apache.cordova.CordovaInterface;
|
|
19
|
+
import org.apache.cordova.CordovaPreferences;
|
|
20
|
+
import org.apache.cordova.CordovaResourceApi;
|
|
21
|
+
import org.apache.cordova.CordovaWebView;
|
|
22
|
+
import org.apache.cordova.CordovaWebViewEngine;
|
|
23
|
+
import org.apache.cordova.NativeToJsMessageQueue;
|
|
24
|
+
import org.apache.cordova.PluginManager;
|
|
25
|
+
import org.apache.cordova.engine.SystemWebViewClient;
|
|
26
|
+
import org.apache.cordova.engine.SystemWebViewEngine;
|
|
27
|
+
import org.apache.cordova.engine.SystemWebView;
|
|
28
|
+
|
|
29
|
+
public class IonicWebViewEngine extends SystemWebViewEngine {
|
|
30
|
+
public static final String TAG = "IonicWebViewEngine";
|
|
31
|
+
|
|
32
|
+
private WebViewLocalServer localServer;
|
|
33
|
+
private String CDV_LOCAL_SERVER;
|
|
34
|
+
private String scheme;
|
|
35
|
+
private static final String LAST_BINARY_VERSION_CODE = "lastBinaryVersionCode";
|
|
36
|
+
private static final String LAST_BINARY_VERSION_NAME = "lastBinaryVersionName";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Used when created via reflection.
|
|
40
|
+
*/
|
|
41
|
+
public IonicWebViewEngine(Context context, CordovaPreferences preferences) {
|
|
42
|
+
super(new SystemWebView(context), preferences);
|
|
43
|
+
Log.d(TAG, "Ionic Web View Engine Starting Right Up 1...");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public IonicWebViewEngine(SystemWebView webView) {
|
|
47
|
+
super(webView, null);
|
|
48
|
+
Log.d(TAG, "Ionic Web View Engine Starting Right Up 2...");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public IonicWebViewEngine(SystemWebView webView, CordovaPreferences preferences) {
|
|
52
|
+
super(webView, preferences);
|
|
53
|
+
Log.d(TAG, "Ionic Web View Engine Starting Right Up 3...");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Override
|
|
57
|
+
public void init(CordovaWebView parentWebView, CordovaInterface cordova, final CordovaWebViewEngine.Client client,
|
|
58
|
+
CordovaResourceApi resourceApi, PluginManager pluginManager,
|
|
59
|
+
NativeToJsMessageQueue nativeToJsMessageQueue) {
|
|
60
|
+
ConfigXmlParser parser = new ConfigXmlParser();
|
|
61
|
+
parser.parse(cordova.getActivity());
|
|
62
|
+
|
|
63
|
+
String hostname = preferences.getString("Hostname", "localhost");
|
|
64
|
+
scheme = preferences.getString("Scheme", "http");
|
|
65
|
+
CDV_LOCAL_SERVER = scheme + "://" + hostname;
|
|
66
|
+
|
|
67
|
+
localServer = new WebViewLocalServer(cordova.getActivity(), hostname, true, parser, scheme);
|
|
68
|
+
localServer.hostAssets("www");
|
|
69
|
+
|
|
70
|
+
webView.setWebViewClient(new ServerClient(this, parser));
|
|
71
|
+
|
|
72
|
+
super.init(parentWebView, cordova, client, resourceApi, pluginManager, nativeToJsMessageQueue);
|
|
73
|
+
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
74
|
+
final WebSettings settings = webView.getSettings();
|
|
75
|
+
int mode = preferences.getInteger("MixedContentMode", 0);
|
|
76
|
+
settings.setMixedContentMode(mode);
|
|
77
|
+
}
|
|
78
|
+
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(IonicWebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
79
|
+
String path = prefs.getString(IonicWebView.CDV_SERVER_PATH, null);
|
|
80
|
+
if (!isDeployDisabled() && !isNewBinary() && path != null && !path.isEmpty()) {
|
|
81
|
+
setServerBasePath(path);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
boolean setAsServiceWorkerClient = preferences.getBoolean("ResolveServiceWorkerRequests", false);
|
|
85
|
+
ServiceWorkerController controller = null;
|
|
86
|
+
|
|
87
|
+
if (setAsServiceWorkerClient && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
|
88
|
+
controller = ServiceWorkerController.getInstance();
|
|
89
|
+
controller.setServiceWorkerClient(new ServiceWorkerClient(){
|
|
90
|
+
@Override
|
|
91
|
+
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
|
|
92
|
+
return localServer.shouldInterceptRequest(request.getUrl(), request);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private boolean isNewBinary() {
|
|
99
|
+
String versionCode = "";
|
|
100
|
+
String versionName = "";
|
|
101
|
+
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(IonicWebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
|
|
102
|
+
String lastVersionCode = prefs.getString(LAST_BINARY_VERSION_CODE, null);
|
|
103
|
+
String lastVersionName = prefs.getString(LAST_BINARY_VERSION_NAME, null);
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
PackageInfo pInfo = this.cordova.getActivity().getPackageManager().getPackageInfo(this.cordova.getActivity().getPackageName(), 0);
|
|
107
|
+
versionCode = Integer.toString(pInfo.versionCode);
|
|
108
|
+
versionName = pInfo.versionName;
|
|
109
|
+
} catch(Exception ex) {
|
|
110
|
+
Log.e(TAG, "Unable to get package info", ex);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!versionCode.equals(lastVersionCode) || !versionName.equals(lastVersionName)) {
|
|
114
|
+
SharedPreferences.Editor editor = prefs.edit();
|
|
115
|
+
editor.putString(LAST_BINARY_VERSION_CODE, versionCode);
|
|
116
|
+
editor.putString(LAST_BINARY_VERSION_NAME, versionName);
|
|
117
|
+
editor.putString(IonicWebView.CDV_SERVER_PATH, "");
|
|
118
|
+
editor.apply();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private boolean isDeployDisabled() {
|
|
125
|
+
return preferences.getBoolean("DisableDeploy", false);
|
|
126
|
+
}
|
|
127
|
+
private class ServerClient extends SystemWebViewClient {
|
|
128
|
+
private ConfigXmlParser parser;
|
|
129
|
+
|
|
130
|
+
public ServerClient(SystemWebViewEngine parentEngine, ConfigXmlParser parser) {
|
|
131
|
+
super(parentEngine);
|
|
132
|
+
this.parser = parser;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@Override
|
|
136
|
+
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
|
|
137
|
+
return localServer.shouldInterceptRequest(request.getUrl(), request);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Override
|
|
141
|
+
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
|
142
|
+
super.onPageStarted(view, url, favicon);
|
|
143
|
+
String launchUrl = parser.getLaunchUrl();
|
|
144
|
+
if (!launchUrl.contains(WebViewLocalServer.httpsScheme) && !launchUrl.contains(WebViewLocalServer.httpScheme) && url.equals(launchUrl)) {
|
|
145
|
+
view.stopLoading();
|
|
146
|
+
// When using a custom scheme the app won't load if server start url doesn't end in /
|
|
147
|
+
String startUrl = CDV_LOCAL_SERVER;
|
|
148
|
+
if (!scheme.equalsIgnoreCase(WebViewLocalServer.httpsScheme) && !scheme.equalsIgnoreCase(WebViewLocalServer.httpScheme)) {
|
|
149
|
+
startUrl += "/";
|
|
150
|
+
}
|
|
151
|
+
view.loadUrl(startUrl);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@Override
|
|
156
|
+
public void onPageFinished(WebView view, String url) {
|
|
157
|
+
super.onPageFinished(view, url);
|
|
158
|
+
view.loadUrl("javascript:(function() { " +
|
|
159
|
+
"window.WEBVIEW_SERVER_URL = '" + CDV_LOCAL_SERVER + "';" +
|
|
160
|
+
"})()");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public void setServerBasePath(String path) {
|
|
165
|
+
localServer.hostFiles(path);
|
|
166
|
+
webView.loadUrl(CDV_LOCAL_SERVER);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public String getServerBasePath() {
|
|
170
|
+
return this.localServer.getBasePath();
|
|
171
|
+
}
|
|
172
|
+
}
|