updated onPermissionRequest event for ios, added DebugSettings
This commit is contained in:
parent
17ed6c881a
commit
28455c696a
@ -7,6 +7,7 @@
|
||||
- Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS`, `forceDarkStrategy` WebView settings
|
||||
- Added `onCameraCaptureStateChanged`, `onMicrophoneCaptureStateChanged` WebView events
|
||||
- Added support for `onPermissionRequest` event on iOS 15.0+
|
||||
- Added `debugSettings` static property for WebView and ChromeSafariBrowser
|
||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes.
|
||||
- Deprecated `onLoadHttpError` for `onReceivedError`. `onReceivedHttpError` will be called also for subframes.
|
||||
|
@ -96,7 +96,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
TextField(
|
||||
decoration: InputDecoration(prefixIcon: Icon(Icons.search)),
|
||||
controller: urlController,
|
||||
keyboardType: TextInputType.url,
|
||||
keyboardType: TextInputType.text,
|
||||
onSubmitted: (value) {
|
||||
var url = Uri.parse(value);
|
||||
if (url.scheme.isEmpty) {
|
||||
|
@ -19,7 +19,7 @@ Future main() async {
|
||||
// await Permission.microphone.request();
|
||||
// await Permission.storage.request();
|
||||
|
||||
WebView.debugLogging = false;
|
||||
WebView.debugSettings.maxLogMessageLength = 500;
|
||||
|
||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
await InAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||
|
@ -669,10 +669,12 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||
if let newValue = change?[.newKey] as? Int {
|
||||
newState = WKMediaCaptureState.init(rawValue: newValue)
|
||||
}
|
||||
if keyPath == #keyPath(WKWebView.cameraCaptureState) {
|
||||
onCameraCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
} else {
|
||||
onMicrophoneCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
if oldState != newState {
|
||||
if keyPath == #keyPath(WKWebView.cameraCaptureState) {
|
||||
onCameraCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
} else {
|
||||
onMicrophoneCaptureStateChanged(oldState: oldState, newState: newState)
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if keyPath == #keyPath(WKWebView.fullscreenState) {
|
||||
@ -1552,10 +1554,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||
onPermissionRequest(request: permissionRequest, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message ?? "")
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
else {
|
||||
var response: [String: Any]
|
||||
@ -1575,7 +1577,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||
}
|
||||
return;
|
||||
}
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1593,10 +1595,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||
onPermissionRequest(request: permissionRequest, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message ?? "")
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
else {
|
||||
var response: [String: Any]
|
||||
@ -1616,7 +1618,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||
}
|
||||
return;
|
||||
}
|
||||
decisionHandler(.deny)
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import 'dart:developer' as developer;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../util.dart';
|
||||
import '../debug_settings.dart';
|
||||
|
||||
import 'chrome_safari_browser_settings.dart';
|
||||
|
||||
@ -44,12 +45,8 @@ class ChromeSafariBrowserNotOpenedException implements Exception {
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
class ChromeSafariBrowser {
|
||||
///Enables [ChromeSafariBrowser] debug logging info.
|
||||
///
|
||||
///The default value is the same value of [kDebugMode],
|
||||
///so it is enabled by default when the application is compiled in debug mode
|
||||
///and disabled when it is not.
|
||||
static bool debugLogging = kDebugMode;
|
||||
///Debug settings.
|
||||
static DebugSettings debugSettings = DebugSettings();
|
||||
|
||||
///View ID used internally.
|
||||
late final String id;
|
||||
@ -70,12 +67,22 @@ class ChromeSafariBrowser {
|
||||
}
|
||||
|
||||
_debugLog(String method, dynamic args) {
|
||||
if (ChromeSafariBrowser.debugLogging) {
|
||||
String message =
|
||||
"ChromeSafariBrowser ID " + id + " calling \"" +
|
||||
method.toString() + "\" using " + args.toString();
|
||||
developer.log(message,
|
||||
name: this.runtimeType.toString());
|
||||
if (ChromeSafariBrowser.debugSettings.enabled) {
|
||||
for (var regExp in ChromeSafariBrowser.debugSettings.excludeFilter) {
|
||||
if (regExp.hasMatch(method)) return;
|
||||
}
|
||||
var maxLogMessageLength =
|
||||
ChromeSafariBrowser.debugSettings.maxLogMessageLength;
|
||||
String message = "ChromeSafariBrowser ID " +
|
||||
id +
|
||||
" calling \"" +
|
||||
method.toString() +
|
||||
"\" using " +
|
||||
args.toString();
|
||||
if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) {
|
||||
message = message.substring(0, maxLogMessageLength) + "...";
|
||||
}
|
||||
developer.log(message, name: this.runtimeType.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
28
lib/src/debug_settings.dart
Normal file
28
lib/src/debug_settings.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'in_app_webview/webview.dart';
|
||||
import 'chrome_safari_browser/chrome_safari_browser.dart';
|
||||
|
||||
///Class that represents the debug settings used by [WebView] and [ChromeSafariBrowser].
|
||||
class DebugSettings {
|
||||
///Enables debug logging info.
|
||||
///
|
||||
///The default value is the same value of [kDebugMode],
|
||||
///so it is enabled by default when the application is compiled in debug mode
|
||||
///and disabled when it is not.
|
||||
bool enabled;
|
||||
|
||||
///Filters used to exclude some logs from logging.
|
||||
List<RegExp> excludeFilter;
|
||||
|
||||
///Max length of the log message.
|
||||
///Set to `-1` to indicate that the log message needs to display the full content.
|
||||
///
|
||||
///The default value is `-1`.
|
||||
int maxLogMessageLength;
|
||||
|
||||
DebugSettings({
|
||||
this.enabled = kDebugMode,
|
||||
this.excludeFilter = const [],
|
||||
this.maxLogMessageLength = -1
|
||||
});
|
||||
}
|
@ -804,10 +804,13 @@ class InAppBrowser {
|
||||
///
|
||||
///[resources] represents the array of resources the web content wants to access.
|
||||
///
|
||||
///**NOTE**: available only on Android 23+.
|
||||
///**NOTE for Android**: available only on Android 23+.
|
||||
///
|
||||
///**NOTE for iOS**: available only on iOS 15.0+. The default [PermissionResponse.action] is [PermissionResponseAction.PROMPT].
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onPermissionRequest](https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)))
|
||||
///- iOS
|
||||
Future<PermissionResponse?>? onPermissionRequest(
|
||||
PermissionRequest permissionRequest) {}
|
||||
|
||||
|
@ -104,7 +104,11 @@ class InAppWebViewController {
|
||||
}
|
||||
|
||||
_debugLog(String method, dynamic args) {
|
||||
if (WebView.debugLogging) {
|
||||
if (WebView.debugSettings.enabled) {
|
||||
for (var regExp in WebView.debugSettings.excludeFilter) {
|
||||
if (regExp.hasMatch(method)) return;
|
||||
}
|
||||
var maxLogMessageLength = WebView.debugSettings.maxLogMessageLength;
|
||||
String viewId = (getViewId() ?? _inAppBrowser?.id).toString();
|
||||
String message = (_inAppBrowser == null ? "WebView" : "InAppBrowser") +
|
||||
" ID " +
|
||||
@ -113,12 +117,15 @@ class InAppWebViewController {
|
||||
method.toString() +
|
||||
"\" using " +
|
||||
args.toString();
|
||||
if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) {
|
||||
message = message.substring(0, maxLogMessageLength) + "...";
|
||||
}
|
||||
developer.log(message, name: this.runtimeType.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> handleMethod(MethodCall call) async {
|
||||
if (WebView.debugLogging && call.method != "onCallJsHandler") {
|
||||
if (WebView.debugSettings.enabled && call.method != "onCallJsHandler") {
|
||||
_debugLog(call.method, call.arguments);
|
||||
}
|
||||
|
||||
@ -163,15 +170,15 @@ class InAppWebViewController {
|
||||
_webview!.onReceivedError!(this, request, error);
|
||||
else if (isForMainFrame) {
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
_webview!.onLoadError!(this, request.url, error.type.toNativeValue(),
|
||||
error.description);
|
||||
_webview!.onLoadError!(this, request.url,
|
||||
error.type.toNativeValue(), error.description);
|
||||
}
|
||||
} else {
|
||||
if (isForMainFrame) {
|
||||
_inAppBrowser!
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.onLoadError(
|
||||
request.url, error.type.toNativeValue(), error.description);
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.onLoadError(request.url, error.type.toNativeValue(),
|
||||
error.description);
|
||||
}
|
||||
_inAppBrowser!.onReceivedError(request, error);
|
||||
}
|
||||
@ -203,9 +210,9 @@ class InAppWebViewController {
|
||||
} else {
|
||||
if (isForMainFrame) {
|
||||
_inAppBrowser!
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
.onLoadHttpError(request.url, errorResponse.statusCode ?? -1,
|
||||
errorResponse.reasonPhrase ?? '');
|
||||
errorResponse.reasonPhrase ?? '');
|
||||
}
|
||||
_inAppBrowser!.onReceivedHttpError(request, errorResponse);
|
||||
}
|
||||
@ -1091,10 +1098,13 @@ class InAppWebViewController {
|
||||
}
|
||||
break;
|
||||
case "onCameraCaptureStateChanged":
|
||||
if ((_webview != null && _webview!.onCameraCaptureStateChanged != null) ||
|
||||
if ((_webview != null &&
|
||||
_webview!.onCameraCaptureStateChanged != null) ||
|
||||
_inAppBrowser != null) {
|
||||
var oldState = MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState = MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
var oldState =
|
||||
MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState =
|
||||
MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
|
||||
if (_webview != null && _webview!.onCameraCaptureStateChanged != null)
|
||||
_webview!.onCameraCaptureStateChanged!(this, oldState, newState);
|
||||
@ -1103,13 +1113,18 @@ class InAppWebViewController {
|
||||
}
|
||||
break;
|
||||
case "onMicrophoneCaptureStateChanged":
|
||||
if ((_webview != null && _webview!.onMicrophoneCaptureStateChanged != null) ||
|
||||
if ((_webview != null &&
|
||||
_webview!.onMicrophoneCaptureStateChanged != null) ||
|
||||
_inAppBrowser != null) {
|
||||
var oldState = MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState = MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
var oldState =
|
||||
MediaCaptureState.fromValue(call.arguments["oldState"]);
|
||||
var newState =
|
||||
MediaCaptureState.fromValue(call.arguments["newState"]);
|
||||
|
||||
if (_webview != null && _webview!.onMicrophoneCaptureStateChanged != null)
|
||||
_webview!.onMicrophoneCaptureStateChanged!(this, oldState, newState);
|
||||
if (_webview != null &&
|
||||
_webview!.onMicrophoneCaptureStateChanged != null)
|
||||
_webview!.onMicrophoneCaptureStateChanged!(
|
||||
this, oldState, newState);
|
||||
else
|
||||
_inAppBrowser!.onMicrophoneCaptureStateChanged(oldState, newState);
|
||||
}
|
||||
@ -3286,8 +3301,7 @@ class InAppWebViewController {
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKWebView.setCameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763097-setcameracapturestate)).
|
||||
Future<void> setCameraCaptureState(
|
||||
{required MediaCaptureState state}) async {
|
||||
Future<void> setCameraCaptureState({required MediaCaptureState state}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('state', () => state.toValue());
|
||||
await _channel.invokeMethod('setCameraCaptureState', args);
|
||||
|
@ -1,8 +1,6 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../pull_to_refresh/pull_to_refresh_controller.dart';
|
||||
|
||||
import '../context_menu.dart';
|
||||
@ -12,14 +10,16 @@ import 'in_app_webview_controller.dart';
|
||||
import 'in_app_webview_settings.dart';
|
||||
import 'headless_in_app_webview.dart';
|
||||
|
||||
import '../debug_settings.dart';
|
||||
|
||||
///Abstract class that represents a WebView. Used by [InAppWebView], [HeadlessInAppWebView] and the WebView of [InAppBrowser].
|
||||
abstract class WebView {
|
||||
///Enables [WebView] debug logging info.
|
||||
///
|
||||
///The default value is the same value of [kDebugMode],
|
||||
///so it is enabled by default when the application is compiled in debug mode
|
||||
///and disabled when it is not.
|
||||
static bool debugLogging = kDebugMode;
|
||||
///Debug settings used by [InAppWebView], [HeadlessInAppWebView] and [InAppBrowser].
|
||||
///The default value excludes the [WebView.onScrollChanged] and [WebView.onOverScrolled] events.
|
||||
static DebugSettings debugSettings = DebugSettings(excludeFilter: [
|
||||
RegExp(r"onScrollChanged"),
|
||||
RegExp(r"onOverScrolled")
|
||||
]);
|
||||
|
||||
///The window id of a [CreateWindowAction.windowId].
|
||||
final int? windowId;
|
||||
@ -567,10 +567,13 @@ abstract class WebView {
|
||||
///
|
||||
///[resources] represents the array of resources the web content wants to access.
|
||||
///
|
||||
///**NOTE**: available only on Android 23+.
|
||||
///**NOTE for Android**: available only on Android 23+.
|
||||
///
|
||||
///**NOTE for iOS**: available only on iOS 15.0+. The default [PermissionResponse.action] is [PermissionResponseAction.PROMPT].
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onPermissionRequest](https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)))
|
||||
///- iOS
|
||||
final Future<PermissionResponse?> Function(InAppWebViewController controller,
|
||||
PermissionRequest permissionRequest)? onPermissionRequest;
|
||||
|
||||
|
@ -14,3 +14,4 @@ export 'http_auth_credentials_database.dart';
|
||||
export 'context_menu.dart';
|
||||
export 'pull_to_refresh/main.dart';
|
||||
export 'web_message/main.dart';
|
||||
export 'debug_settings.dart';
|
||||
|
Loading…
x
Reference in New Issue
Block a user