bug fixes, fix #450, updated integration tests
This commit is contained in:
parent
0b0bce66aa
commit
f886f2f1e5
CHANGELOG.md
android/src/main/java/com/pichillilorenzo/flutter_inappwebview
example
ios/Classes
lib/src
@ -1,4 +1,4 @@
|
||||
## 5.0.0-nullsafety.0
|
||||
## 5.0.0
|
||||
|
||||
- Added support for Dart null-safety feature
|
||||
- Added Android Hybrid Composition support "Use PlatformViewLink widget for Android WebView" [#462](https://github.com/pichillilorenzo/flutter_inappwebview/pull/462) (thanks to [plateaukao](https://github.com/plateaukao) and [tneotia](https://github.com/tneotia))
|
||||
@ -32,6 +32,7 @@
|
||||
- Merge "Add ChromeSafariBrowser support for Android 11" [#538](https://github.com/pichillilorenzo/flutter_inappwebview/pull/538) (thanks to [DRSchlaubi](https://github.com/DRSchlaubi))
|
||||
- Merge "fix(iOS): missing implementation of method zoomBy" [#670](https://github.com/pichillilorenzo/flutter_inappwebview/pull/670) (thanks to [pcqpcq](https://github.com/pcqpcq))
|
||||
- Merge "[mod] Fix all issues relate to long click in Android version 7.0 (#657, #527)" [#671](https://github.com/pichillilorenzo/flutter_inappwebview/pull/671) (thanks to [MrNinja](https://github.com/MrNinja))
|
||||
- Merge "Fix ViewGroup.removeView NullPointerException (#450)" [#683](https://github.com/pichillilorenzo/flutter_inappwebview/pull/683) (thanks to [toda-bps](https://github.com/toda-bps))
|
||||
- Fixed missing properties initialization when using InAppWebViewController.fromInAppBrowser
|
||||
- Fixed "Issue in Flutter web: 'Unsupported operation: Platform._operatingSystem'" [#507](https://github.com/pichillilorenzo/flutter_inappwebview/issues/507)
|
||||
- Fixed "window.flutter_inappwebview.callHandler is not a function" [#218](https://github.com/pichillilorenzo/flutter_inappwebview/issues/218)
|
||||
|
@ -73,7 +73,7 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||
break;
|
||||
case "loadFile":
|
||||
if (webView != null) {
|
||||
String assetFilePath = (String) call.argument("url");
|
||||
String assetFilePath = (String) call.argument("assetFilePath");
|
||||
try {
|
||||
webView.loadFile(assetFilePath);
|
||||
} catch (IOException e) {
|
||||
@ -458,7 +458,7 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||
Integer index = (Integer) call.argument("index");
|
||||
Map<String, Object> userScriptMap = (Map<String, Object>) call.argument("userScript");
|
||||
UserScript userScript = UserScript.fromMap(userScriptMap);
|
||||
result.success(webView.userContentController.removePluginScriptAt(index, userScript.getInjectionTime()));
|
||||
result.success(webView.userContentController.removeUserOnlyScriptAt(index, userScript.getInjectionTime()));
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
|
@ -460,7 +460,9 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
|
||||
Shared.activityPluginBinding.removeActivityResultListener(webView.inAppWebViewChromeClient);
|
||||
}
|
||||
ViewGroup vg = (ViewGroup) (webView.getParent());
|
||||
vg.removeView(webView);
|
||||
if (vg != null) {
|
||||
vg.removeView(webView);
|
||||
}
|
||||
webView.setWebChromeClient(new WebChromeClient());
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
|
@ -81,8 +81,8 @@ public class InAppBrowserOptions implements Options<InAppBrowserActivity> {
|
||||
@Override
|
||||
public Map<String, Object> getRealOptions(InAppBrowserActivity inAppBrowserActivity) {
|
||||
Map<String, Object> realOptions = toMap();
|
||||
realOptions.put("hideToolbarTop", inAppBrowserActivity.actionBar.isShowing());
|
||||
realOptions.put("hideUrlBar", inAppBrowserActivity.menu.findItem(R.id.menu_search).isVisible());
|
||||
realOptions.put("hideToolbarTop", !inAppBrowserActivity.actionBar.isShowing());
|
||||
realOptions.put("hideUrlBar", !inAppBrowserActivity.menu.findItem(R.id.menu_search).isVisible());
|
||||
realOptions.put("hideProgressBar", inAppBrowserActivity.progressBar.getMax() == 0);
|
||||
return realOptions;
|
||||
}
|
||||
|
@ -1037,7 +1037,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
}
|
||||
|
||||
public void injectCSSCode(String source) {
|
||||
String jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %s; d.body.appendChild(style); })(document);";
|
||||
String jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %s; d.head.appendChild(style); })(document);";
|
||||
injectDeferredObject(source, null, jsWrapper, null);
|
||||
}
|
||||
|
||||
|
@ -672,10 +672,16 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
||||
public void onProgressChanged(WebView view, int progress) {
|
||||
super.onProgressChanged(view, progress);
|
||||
|
||||
InAppWebView webView = (InAppWebView) view;
|
||||
|
||||
if (inAppBrowserDelegate != null) {
|
||||
inAppBrowserDelegate.didChangeProgress(progress);
|
||||
}
|
||||
|
||||
if (webView.inAppWebViewClient != null) {
|
||||
webView.inAppWebViewClient.loadCustomJavaScriptOnPageStarted(view);
|
||||
}
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("progress", progress);
|
||||
channel.invokeMethod("onProgressChanged", obj);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -216,11 +217,6 @@ public class UserContentController {
|
||||
return this.pluginScripts.get(pluginScript.getInjectionTime()).remove(pluginScript);
|
||||
}
|
||||
|
||||
public boolean removePluginScriptAt(int index, UserScriptInjectionTime injectionTime) {
|
||||
PluginScript pluginScript = new ArrayList<>(this.pluginScripts.get(injectionTime)).get(index);
|
||||
return this.removePluginScript(pluginScript);
|
||||
}
|
||||
|
||||
public void removeAllPluginScripts() {
|
||||
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START).clear();
|
||||
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_END).clear();
|
||||
@ -356,9 +352,5 @@ public class UserContentController {
|
||||
|
||||
private static final String DOCUMENT_READY_WRAPPER_JS_SOURCE = "if (document.readyState === 'interactive' || document.readyState === 'complete') { " +
|
||||
" " + PluginScriptsUtil.VAR_PLACEHOLDER_VALUE +
|
||||
"} else {" +
|
||||
" document.addEventListener('DOMContentLoaded', function() {" +
|
||||
" " + PluginScriptsUtil.VAR_PLACEHOLDER_VALUE +
|
||||
" });" +
|
||||
"}";
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-22 12:12:06.265826","version":"1.27.0-5.0.pre.90"}
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-22 23:35:30.325662","version":"1.27.0-5.0.pre.90"}
|
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,8 @@
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoadsInWebContent</key>
|
||||
<true/>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
|
@ -102,7 +102,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
key: webViewKey,
|
||||
// contextMenu: contextMenu,
|
||||
initialUrlRequest: URLRequest(
|
||||
url: Uri.parse("https://github.com")
|
||||
url: Uri.parse("https://flutter.dev")
|
||||
),
|
||||
// initialFile: "assets/index.html",
|
||||
initialUserScripts: UnmodifiableListView<UserScript>([
|
||||
@ -140,9 +140,6 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
|
||||
return NavigationActionPolicy.ALLOW;
|
||||
},
|
||||
onLoadResource: (controller, resource) {
|
||||
// print(resource);
|
||||
},
|
||||
onLoadStop: (controller, url) async {
|
||||
print("onLoadStop $url");
|
||||
setState(() {
|
||||
|
@ -71,6 +71,7 @@ flutter:
|
||||
- test_assets/in_app_webview_on_console_message_test.html
|
||||
- test_assets/in_app_webview_on_create_window_test.html
|
||||
- test_assets/in_app_webview_on_js_dialog_test.html
|
||||
- test_assets/js/
|
||||
- test_assets/css/
|
||||
- test_assets/images/
|
||||
- test_assets/favicon.ico
|
||||
|
3
example/test_assets/css/blue-body.css
Normal file
3
example/test_assets/css/blue-body.css
Normal file
@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: rgb(0, 0, 255);
|
||||
}
|
2
example/test_assets/js/jquery-3.3.1.min.js
vendored
Normal file
2
example/test_assets/js/jquery-3.3.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -426,7 +426,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
||||
searchBar.isHidden = newOptions.hideUrlBar
|
||||
}
|
||||
|
||||
if newOptionsMap["toolbarTop"] != nil, browserOptions?.hideToolbarTop != newOptions.hideToolbarTop {
|
||||
if newOptionsMap["hideToolbarTop"] != nil, browserOptions?.hideToolbarTop != newOptions.hideToolbarTop {
|
||||
navigationController?.navigationBar.isHidden = newOptions.hideToolbarTop
|
||||
}
|
||||
|
||||
|
@ -1323,7 +1323,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
}
|
||||
|
||||
public func injectCSSCode(source: String) {
|
||||
let jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %@; d.body.appendChild(style); })(document);"
|
||||
let jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %@; d.head.appendChild(style); })(document);"
|
||||
injectDeferredObject(source: source, withWrapper: jsWrapper, completionHandler: nil)
|
||||
}
|
||||
|
||||
@ -1356,7 +1356,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
cssLinkAttributes += " link.title = '\(titleAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||
}
|
||||
}
|
||||
let jsWrapper = "(function(d) { var link = d.createElement('link'); link.rel='\(alternateStylesheet)stylesheet', link.type='text/css'; \(cssLinkAttributes) link.href = %@; d.body.appendChild(link); })(document);"
|
||||
let jsWrapper = "(function(d) { var link = d.createElement('link'); link.rel='\(alternateStylesheet)stylesheet', link.type='text/css'; \(cssLinkAttributes) link.href = %@; d.head.appendChild(link); })(document);"
|
||||
injectDeferredObject(source: urlFile, withWrapper: jsWrapper, completionHandler: nil)
|
||||
}
|
||||
|
||||
|
@ -260,8 +260,8 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||
break
|
||||
case "pauseTimers":
|
||||
webView?.pauseTimers()
|
||||
result(true)
|
||||
break
|
||||
result(true)
|
||||
break
|
||||
case "resumeTimers":
|
||||
webView?.resumeTimers()
|
||||
result(true)
|
||||
@ -383,16 +383,19 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||
result(webView?.getCertificate()?.toMap())
|
||||
break
|
||||
case "addUserScript":
|
||||
let userScriptMap = arguments!["userScript"] as! [String: Any?]
|
||||
let userScript = UserScript.fromMap(map: userScriptMap, windowId: webView?.windowId)!
|
||||
webView?.configuration.userContentController.addUserOnlyScript(userScript)
|
||||
if let webView = webView {
|
||||
let userScriptMap = arguments!["userScript"] as! [String: Any?]
|
||||
let userScript = UserScript.fromMap(map: userScriptMap, windowId: webView.windowId)!
|
||||
webView.configuration.userContentController.addUserOnlyScript(userScript)
|
||||
webView.configuration.userContentController.sync(scriptMessageHandler: webView)
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "removeUserScript":
|
||||
let index = arguments!["index"] as! Int
|
||||
let userScriptMap = arguments!["userScript"] as! [String: Any?]
|
||||
let userScript = UserScript.fromMap(map: userScriptMap, windowId: webView?.windowId)!
|
||||
webView?.configuration.userContentController.removeUserOnlyScript(at: index, userOnlyScript: userScript)
|
||||
webView?.configuration.userContentController.removeUserOnlyScript(at: index, injectionTime: userScript.injectionTime)
|
||||
result(true)
|
||||
break
|
||||
case "removeUserScriptsByGroupName":
|
||||
@ -463,12 +466,12 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||
break
|
||||
case "isSecureContext":
|
||||
if let webView = webView {
|
||||
result(webView.isSecureContext(completionHandler: { (isSecureContext) in
|
||||
webView.isSecureContext(completionHandler: { (isSecureContext) in
|
||||
result(isSecureContext)
|
||||
}))
|
||||
})
|
||||
}
|
||||
else {
|
||||
result(nil)
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
default:
|
||||
|
@ -178,9 +178,10 @@ extension WKUserContentController {
|
||||
removeUserScript(scriptToRemove: userOnlyScript)
|
||||
}
|
||||
|
||||
public func removeUserOnlyScript(at index: Int, userOnlyScript: UserScript) {
|
||||
userOnlyScripts[userOnlyScript.injectionTime]!.removeObject(at: index)
|
||||
removeUserScript(scriptToRemove: userOnlyScript)
|
||||
public func removeUserOnlyScript(at index: Int, injectionTime: WKUserScriptInjectionTime) {
|
||||
let scriptToRemove = userOnlyScripts[injectionTime]![index]
|
||||
userOnlyScripts[injectionTime]!.removeObject(at: index)
|
||||
removeUserScript(scriptToRemove: scriptToRemove)
|
||||
}
|
||||
|
||||
public func removeAllUserOnlyScripts() {
|
||||
|
@ -6,6 +6,30 @@ import 'package:flutter/services.dart';
|
||||
import '../_uuid_generator.dart';
|
||||
import 'chrome_safari_browser_options.dart';
|
||||
|
||||
class ChromeSafariBrowserAlreadyOpenedException implements Exception {
|
||||
final dynamic message;
|
||||
|
||||
ChromeSafariBrowserAlreadyOpenedException([this.message]);
|
||||
|
||||
String toString() {
|
||||
Object? message = this.message;
|
||||
if (message == null) return "ChromeSafariBrowserAlreadyOpenedException";
|
||||
return "ChromeSafariBrowserAlreadyOpenedException: $message";
|
||||
}
|
||||
}
|
||||
|
||||
class ChromeSafariBrowserNotOpenedException implements Exception {
|
||||
final dynamic message;
|
||||
|
||||
ChromeSafariBrowserNotOpenedException([this.message]);
|
||||
|
||||
String toString() {
|
||||
Object? message = this.message;
|
||||
if (message == null) return "ChromeSafariBrowserNotOpenedException";
|
||||
return "ChromeSafariBrowserNotOpenedException: $message";
|
||||
}
|
||||
}
|
||||
|
||||
///This class uses native [Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android
|
||||
///and [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.
|
||||
///
|
||||
@ -120,7 +144,7 @@ class ChromeSafariBrowser {
|
||||
|
||||
void throwIsAlreadyOpened({String message = ''}) {
|
||||
if (this.isOpened()) {
|
||||
throw Exception([
|
||||
throw ChromeSafariBrowserAlreadyOpenedException([
|
||||
'Error: ${(message.isEmpty) ? '' : message + ' '}The browser is already opened.'
|
||||
]);
|
||||
}
|
||||
@ -128,7 +152,7 @@ class ChromeSafariBrowser {
|
||||
|
||||
void throwIsNotOpened({String message = ''}) {
|
||||
if (!this.isOpened()) {
|
||||
throw Exception([
|
||||
throw ChromeSafariBrowserNotOpenedException([
|
||||
'Error: ${(message.isEmpty) ? '' : message + ' '}The browser is not opened.'
|
||||
]);
|
||||
}
|
||||
|
@ -13,6 +13,30 @@ import '../in_app_webview/in_app_webview_options.dart';
|
||||
|
||||
import 'in_app_browser_options.dart';
|
||||
|
||||
class InAppBrowserAlreadyOpenedException implements Exception {
|
||||
final dynamic message;
|
||||
|
||||
InAppBrowserAlreadyOpenedException([this.message]);
|
||||
|
||||
String toString() {
|
||||
Object? message = this.message;
|
||||
if (message == null) return "InAppBrowserAlreadyOpenedException";
|
||||
return "InAppBrowserAlreadyOpenedException: $message";
|
||||
}
|
||||
}
|
||||
|
||||
class InAppBrowserNotOpenedException implements Exception {
|
||||
final dynamic message;
|
||||
|
||||
InAppBrowserNotOpenedException([this.message]);
|
||||
|
||||
String toString() {
|
||||
Object? message = this.message;
|
||||
if (message == null) return "InAppBrowserNotOpenedException";
|
||||
return "InAppBrowserNotOpenedException: $message";
|
||||
}
|
||||
}
|
||||
|
||||
///This class uses the native WebView of the platform.
|
||||
///The [webViewController] field can be used to access the [InAppWebViewController] API.
|
||||
class InAppBrowser {
|
||||
@ -76,7 +100,7 @@ class InAppBrowser {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('urlRequest', () => urlRequest.toMap());
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap());
|
||||
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
|
||||
args.putIfAbsent('windowId', () => windowId);
|
||||
args.putIfAbsent('initialUserScripts', () => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
|
||||
@ -127,7 +151,7 @@ class InAppBrowser {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('assetFilePath', () => assetFilePath);
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap());
|
||||
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
|
||||
args.putIfAbsent('windowId', () => windowId);
|
||||
args.putIfAbsent('initialUserScripts', () => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
|
||||
@ -154,12 +178,12 @@ class InAppBrowser {
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
||||
args.putIfAbsent('options', () => options?.toMap() ?? InAppBrowserClassOptions().toMap());
|
||||
args.putIfAbsent('data', () => data);
|
||||
args.putIfAbsent('mimeType', () => mimeType);
|
||||
args.putIfAbsent('encoding', () => encoding);
|
||||
args.putIfAbsent('baseUrl', () => baseUrl ?? Uri.parse("about:blank"));
|
||||
args.putIfAbsent('historyUrl', () => androidHistoryUrl ?? Uri.parse("about:blank"));
|
||||
args.putIfAbsent('baseUrl', () => baseUrl?.toString() ?? "about:blank");
|
||||
args.putIfAbsent('historyUrl', () => androidHistoryUrl?.toString() ?? "about:blank");
|
||||
args.putIfAbsent('contextMenu', () => contextMenu?.toMap() ?? {});
|
||||
args.putIfAbsent('windowId', () => windowId);
|
||||
args.putIfAbsent('initialUserScripts', () => initialUserScripts?.map((e) => e.toMap()).toList() ?? []);
|
||||
@ -768,7 +792,7 @@ class InAppBrowser {
|
||||
|
||||
void throwIfAlreadyOpened({String message = ''}) {
|
||||
if (this.isOpened()) {
|
||||
throw Exception([
|
||||
throw InAppBrowserAlreadyOpenedException([
|
||||
'Error: ${(message.isEmpty) ? '' : message + ' '}The browser is already opened.'
|
||||
]);
|
||||
}
|
||||
@ -776,7 +800,7 @@ class InAppBrowser {
|
||||
|
||||
void throwIfNotOpened({String message = ''}) {
|
||||
if (!this.isOpened()) {
|
||||
throw Exception([
|
||||
throw InAppBrowserNotOpenedException([
|
||||
'Error: ${(message.isEmpty) ? '' : message + ' '}The browser is not opened.'
|
||||
]);
|
||||
}
|
||||
|
@ -39,40 +39,40 @@ class BrowserOptions {
|
||||
///Class that represents the options that can be used for an [InAppBrowser] WebView.
|
||||
class InAppBrowserClassOptions {
|
||||
///Cross-platform options.
|
||||
InAppBrowserOptions? crossPlatform;
|
||||
late InAppBrowserOptions crossPlatform;
|
||||
|
||||
///Android-specific options.
|
||||
AndroidInAppBrowserOptions? android;
|
||||
late AndroidInAppBrowserOptions android;
|
||||
|
||||
///iOS-specific options.
|
||||
IOSInAppBrowserOptions? ios;
|
||||
late IOSInAppBrowserOptions ios;
|
||||
|
||||
///WebView options.
|
||||
InAppWebViewGroupOptions? inAppWebViewGroupOptions;
|
||||
late InAppWebViewGroupOptions inAppWebViewGroupOptions;
|
||||
|
||||
InAppBrowserClassOptions(
|
||||
{this.crossPlatform,
|
||||
this.android,
|
||||
this.ios,
|
||||
this.inAppWebViewGroupOptions}) {
|
||||
this.crossPlatform = this.crossPlatform ?? InAppBrowserOptions();
|
||||
this.android = this.android ?? AndroidInAppBrowserOptions();
|
||||
this.ios = this.ios ?? IOSInAppBrowserOptions();
|
||||
{InAppBrowserOptions? crossPlatform,
|
||||
AndroidInAppBrowserOptions? android,
|
||||
IOSInAppBrowserOptions? ios,
|
||||
InAppWebViewGroupOptions? inAppWebViewGroupOptions}) {
|
||||
this.crossPlatform = crossPlatform ?? InAppBrowserOptions();
|
||||
this.android = android ?? AndroidInAppBrowserOptions();
|
||||
this.ios = ios ?? IOSInAppBrowserOptions();
|
||||
this.inAppWebViewGroupOptions =
|
||||
this.inAppWebViewGroupOptions ?? InAppWebViewGroupOptions();
|
||||
inAppWebViewGroupOptions ?? InAppWebViewGroupOptions();
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> options = {};
|
||||
|
||||
options.addAll(this.crossPlatform?.toMap() ?? {});
|
||||
options.addAll(this.inAppWebViewGroupOptions?.crossPlatform.toMap() ?? {});
|
||||
options.addAll(this.crossPlatform.toMap());
|
||||
options.addAll(this.inAppWebViewGroupOptions.crossPlatform.toMap());
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
options.addAll(this.android?.toMap() ?? {});
|
||||
options.addAll(this.inAppWebViewGroupOptions?.android.toMap() ?? {});
|
||||
options.addAll(this.android.toMap());
|
||||
options.addAll(this.inAppWebViewGroupOptions.android.toMap());
|
||||
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
|
||||
options.addAll(this.ios?.toMap() ?? {});
|
||||
options.addAll(this.inAppWebViewGroupOptions?.ios.toMap() ?? {});
|
||||
options.addAll(this.ios.toMap());
|
||||
options.addAll(this.inAppWebViewGroupOptions.ios.toMap());
|
||||
}
|
||||
|
||||
return options;
|
||||
@ -95,16 +95,16 @@ class InAppBrowserClassOptions {
|
||||
InAppBrowserOptions.fromMap(options);
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions =
|
||||
InAppWebViewGroupOptions();
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions!.crossPlatform =
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions.crossPlatform =
|
||||
InAppWebViewOptions.fromMap(options);
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
inAppBrowserClassOptions.android =
|
||||
AndroidInAppBrowserOptions.fromMap(options);
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions!.android =
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions.android =
|
||||
AndroidInAppWebViewOptions.fromMap(options);
|
||||
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
|
||||
inAppBrowserClassOptions.ios = IOSInAppBrowserOptions.fromMap(options);
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions!.ios =
|
||||
inAppBrowserClassOptions.inAppWebViewGroupOptions.ios =
|
||||
IOSInAppWebViewOptions.fromMap(options);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class InAppWebViewController {
|
||||
MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id');
|
||||
this._channel.setMethodCallHandler(handleMethod);
|
||||
this._webview = webview;
|
||||
this._userScripts = List<UserScript>.from(webview.initialUserScripts ?? []);
|
||||
this._userScripts = List<UserScript>.from(webview.initialUserScripts ?? <UserScript>[]);
|
||||
this._init();
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ class InAppWebViewController {
|
||||
this._inAppBrowserUuid = uuid;
|
||||
this._channel = channel;
|
||||
this._inAppBrowser = inAppBrowser;
|
||||
this._userScripts = List<UserScript>.from(initialUserScripts ?? []);
|
||||
this._userScripts = List<UserScript>.from(initialUserScripts ?? <UserScript>[]);
|
||||
this._init();
|
||||
}
|
||||
|
||||
@ -982,6 +982,8 @@ class InAppWebViewController {
|
||||
///Specify the same value as the URL parameter to prevent WebView from reading any other content.
|
||||
///Specify a directory to give WebView permission to read additional files in the specified directory.
|
||||
///
|
||||
///**NOTE for Android**: when loading an URL Request using "POST" method, headers are ignored.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String)
|
||||
///
|
||||
///**Official iOS API**:
|
||||
@ -1037,8 +1039,8 @@ class InAppWebViewController {
|
||||
args.putIfAbsent('data', () => data);
|
||||
args.putIfAbsent('mimeType', () => mimeType);
|
||||
args.putIfAbsent('encoding', () => encoding);
|
||||
args.putIfAbsent('baseUrl', () => baseUrl ?? Uri.parse("about:blank"));
|
||||
args.putIfAbsent('historyUrl', () => androidHistoryUrl ?? Uri.parse("about:blank"));
|
||||
args.putIfAbsent('baseUrl', () => baseUrl?.toString() ?? "about:blank");
|
||||
args.putIfAbsent('historyUrl', () => androidHistoryUrl?.toString() ?? "about:blank");
|
||||
await _channel.invokeMethod('loadData', args);
|
||||
}
|
||||
|
||||
@ -1376,31 +1378,8 @@ class InAppWebViewController {
|
||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/1414977-backforwardlist
|
||||
Future<WebHistory?> getCopyBackForwardList() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
Map<dynamic, dynamic>? result =
|
||||
await _channel.invokeMethod('getCopyBackForwardList', args);
|
||||
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
result = result.cast<String, dynamic>();
|
||||
|
||||
List<dynamic> historyListMap = result["history"];
|
||||
historyListMap = historyListMap.cast<LinkedHashMap<dynamic, dynamic>>();
|
||||
|
||||
int currentIndex = result["currentIndex"];
|
||||
|
||||
List<WebHistoryItem> historyList = [] as List<WebHistoryItem>;
|
||||
for (var i = 0; i < historyListMap.length; i++) {
|
||||
LinkedHashMap<dynamic, dynamic> historyItem = historyListMap[i];
|
||||
historyList.add(WebHistoryItem(
|
||||
originalUrl: historyItem["originalUrl"] != null ? Uri.parse(historyItem["originalUrl"]) : null,
|
||||
title: historyItem["title"],
|
||||
url: historyItem["url"] != null ? Uri.parse(historyItem["url"]) : null,
|
||||
index: i,
|
||||
offset: i - currentIndex));
|
||||
}
|
||||
return WebHistory(list: historyList, currentIndex: currentIndex);
|
||||
Map<String, dynamic>? result = (await _channel.invokeMethod('getCopyBackForwardList', args))?.cast<String, dynamic>();
|
||||
return WebHistory.fromMap(result);
|
||||
}
|
||||
|
||||
///Clears all the webview's cache.
|
||||
|
@ -618,6 +618,8 @@ abstract class WebView {
|
||||
iosShouldAllowDeprecatedTLS;
|
||||
|
||||
///Initial url request that will be loaded.
|
||||
///
|
||||
///**NOTE for Android**: when loading an URL Request using "POST" method, headers are ignored.
|
||||
final URLRequest? initialUrlRequest;
|
||||
|
||||
///Initial asset file that will be loaded. See [InAppWebViewController.loadFile] for explanation.
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:convert';
|
||||
@ -144,17 +145,19 @@ class InAppWebViewInitialData {
|
||||
///The URL to use as the page's base URL. The default value is `about:blank`.
|
||||
late Uri baseUrl;
|
||||
|
||||
///The URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL. This parameter is used only on Android.
|
||||
late Uri historyUrl;
|
||||
///The URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL.
|
||||
///
|
||||
///This parameter is used only on Android.
|
||||
late Uri androidHistoryUrl;
|
||||
|
||||
InAppWebViewInitialData(
|
||||
{required this.data,
|
||||
this.mimeType = "text/html",
|
||||
this.encoding = "utf8",
|
||||
Uri? baseUrl,
|
||||
Uri? historyUrl}) {
|
||||
Uri? androidHistoryUrl}) {
|
||||
this.baseUrl = baseUrl == null ? Uri.parse("about:blank") : baseUrl;
|
||||
this.historyUrl = historyUrl == null ? Uri.parse("about:blank") : historyUrl;
|
||||
this.androidHistoryUrl = androidHistoryUrl == null ? Uri.parse("about:blank") : androidHistoryUrl;
|
||||
}
|
||||
|
||||
Map<String, String> toMap() {
|
||||
@ -163,7 +166,7 @@ class InAppWebViewInitialData {
|
||||
"mimeType": mimeType,
|
||||
"encoding": encoding,
|
||||
"baseUrl": baseUrl.toString(),
|
||||
"historyUrl": historyUrl.toString()
|
||||
"historyUrl": androidHistoryUrl.toString()
|
||||
};
|
||||
}
|
||||
|
||||
@ -397,6 +400,30 @@ class WebHistory {
|
||||
|
||||
WebHistory({this.list, this.currentIndex});
|
||||
|
||||
static WebHistory? fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<LinkedHashMap<dynamic, dynamic>>? historyListMap = map["history"]?.cast<LinkedHashMap<dynamic, dynamic>>();
|
||||
int currentIndex = map["currentIndex"];
|
||||
|
||||
List<WebHistoryItem> historyList = <WebHistoryItem>[];
|
||||
if (historyListMap != null) {
|
||||
for (var i = 0; i < historyListMap.length; i++) {
|
||||
var historyItem = historyListMap[i];
|
||||
historyList.add(WebHistoryItem(
|
||||
originalUrl: historyItem["originalUrl"] != null ? Uri.parse(historyItem["originalUrl"]) : null,
|
||||
title: historyItem["title"],
|
||||
url: historyItem["url"] != null ? Uri.parse(historyItem["url"]) : null,
|
||||
index: i,
|
||||
offset: i - currentIndex));
|
||||
}
|
||||
}
|
||||
|
||||
return WebHistory(list: historyList, currentIndex: currentIndex);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {"list": list, "currentIndex": currentIndex};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user