Added support for Dart null-safety feature, Updated integration tests, Fixed missing properties initialization when using InAppWebViewController.fromInAppBrowser, Removed debuggingEnabled WebView option and added AndroidInAppWebViewController.setWebContentsDebuggingEnabled static method
This commit is contained in:
parent
eaad17eb4f
commit
26e63cedee
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,10 +1,13 @@
|
||||||
## 5.0.0
|
## 5.0.0-nullsafety.0
|
||||||
|
|
||||||
|
- Added support for Dart null-safety feature
|
||||||
|
- Updated integration tests
|
||||||
- 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))
|
- 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))
|
||||||
- Merge "Upgraded appcompat to 1.2.0-rc-02" [#465](https://github.com/pichillilorenzo/flutter_inappwebview/pull/465) (thanks to [andreidiaconu](https://github.com/andreidiaconu))
|
- Merge "Upgraded appcompat to 1.2.0-rc-02" [#465](https://github.com/pichillilorenzo/flutter_inappwebview/pull/465) (thanks to [andreidiaconu](https://github.com/andreidiaconu))
|
||||||
- Merge "Added missing field 'headers' which returned by WebResourceResponse.toMap()" [#490](https://github.com/pichillilorenzo/flutter_inappwebview/pull/490) (thanks to [Doflatango](https://github.com/Doflatango))
|
- Merge "Added missing field 'headers' which returned by WebResourceResponse.toMap()" [#490](https://github.com/pichillilorenzo/flutter_inappwebview/pull/490) (thanks to [Doflatango](https://github.com/Doflatango))
|
||||||
- Merge "Fix: added iOS fallback module import" [#466](https://github.com/pichillilorenzo/flutter_inappwebview/pull/466) (thanks to [Eddayy](https://github.com/Eddayy))
|
- Merge "Fix: added iOS fallback module import" [#466](https://github.com/pichillilorenzo/flutter_inappwebview/pull/466) (thanks to [Eddayy](https://github.com/Eddayy))
|
||||||
- Merge "Fix NullPointerException after taking a photo by a camera app on Android" [#492](https://github.com/pichillilorenzo/flutter_inappwebview/pull/492) (thanks to [AAkira](https://github.com/AAkira))
|
- Merge "Fix NullPointerException after taking a photo by a camera app on Android" [#492](https://github.com/pichillilorenzo/flutter_inappwebview/pull/492) (thanks to [AAkira](https://github.com/AAkira))
|
||||||
|
- 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 "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)
|
- Fixed "window.flutter_inappwebview.callHandler is not a function" [#218](https://github.com/pichillilorenzo/flutter_inappwebview/issues/218)
|
||||||
- Fixed "Android ContentBlocker - java.lang.NullPointerException ContentBlockerTrigger resource type" [#506](https://github.com/pichillilorenzo/flutter_inappwebview/issues/506)
|
- Fixed "Android ContentBlocker - java.lang.NullPointerException ContentBlockerTrigger resource type" [#506](https://github.com/pichillilorenzo/flutter_inappwebview/issues/506)
|
||||||
|
@ -12,6 +15,11 @@
|
||||||
- Fixed missing `clearHistory` webview method implementation on Android
|
- Fixed missing `clearHistory` webview method implementation on Android
|
||||||
- Fixed iOS crash when using CookieManager getCookies for an URL and the host URL is `null`
|
- Fixed iOS crash when using CookieManager getCookies for an URL and the host URL is `null`
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
- Minimum Flutter version required is `1.22.0` and Dart SDK `>=2.12.0-0 <3.0.0`
|
||||||
|
- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
|
||||||
|
|
||||||
## 4.0.0+4
|
## 4.0.0+4
|
||||||
|
|
||||||
- Reverted calling `handler.post` on Android when a WebView is created
|
- Reverted calling `handler.post` on Android when a WebView is created
|
||||||
|
|
167
README.md
167
README.md
|
@ -22,8 +22,8 @@ A Flutter plugin that allows you to add an inline webview, to use an headless we
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Dart sdk: ">=2.7.0 <3.0.0"
|
- Dart sdk: ">=2.12.0-0 <3.0.0"
|
||||||
- Flutter: ">=1.12.13+hotfix.5"
|
- Flutter: ">=1.22.0"
|
||||||
- Android: `minSdkVersion 17` and add support for `androidx` (see [AndroidX Migration](https://flutter.dev/docs/development/androidx-migration) to migrate an existing app)
|
- Android: `minSdkVersion 17` and add support for `androidx` (see [AndroidX Migration](https://flutter.dev/docs/development/androidx-migration) to migrate an existing app)
|
||||||
- iOS: `--ios-language swift`, Xcode version `>= 11`
|
- iOS: `--ios-language swift`, Xcode version `>= 11`
|
||||||
|
|
||||||
|
@ -75,6 +75,22 @@ or **Android API 19+** if you enable the `useHybridComposition` Android-specific
|
||||||
- Check the official [Network security configuration - "Opt out of cleartext traffic"](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted) section.
|
- Check the official [Network security configuration - "Opt out of cleartext traffic"](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted) section.
|
||||||
- Also, check this StackOverflow issue answer: [Cleartext HTTP traffic not permitted](https://stackoverflow.com/a/50834600/4637638).
|
- Also, check this StackOverflow issue answer: [Cleartext HTTP traffic not permitted](https://stackoverflow.com/a/50834600/4637638).
|
||||||
|
|
||||||
|
#### Debugging Android WebViews
|
||||||
|
On Android, in order to enable/disable debugging WebViews using `chrome://inspect` on Chrome, you should use the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method.
|
||||||
|
|
||||||
|
For example, you could call it inside the main function:
|
||||||
|
```dart
|
||||||
|
Future main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
runApp(new MyApp());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### IMPORTANT Note for iOS
|
### IMPORTANT Note for iOS
|
||||||
|
|
||||||
If you are starting a new fresh app, you need to create the Flutter App with `flutter create --androidx -i swift`
|
If you are starting a new fresh app, you need to create the Flutter App with `flutter create --androidx -i swift`
|
||||||
|
@ -168,6 +184,9 @@ Add the following codes inside the `<application>` tag of your `android/app/src/
|
||||||
</provider>
|
</provider>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Debugging iOS WebViews
|
||||||
|
On iOS, debugging WebViews on Safari through developer tools is always enabled. There isn't a way to enable or disable it.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
For help getting started with Flutter, view our online
|
For help getting started with Flutter, view our online
|
||||||
|
@ -241,11 +260,15 @@ Use `InAppWebViewController` to control the WebView instance.
|
||||||
Example:
|
Example:
|
||||||
```dart
|
```dart
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +279,7 @@ class MyApp extends StatefulWidget {
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
|
|
||||||
InAppWebViewController webView;
|
InAppWebViewController? webView;
|
||||||
String url = "";
|
String url = "";
|
||||||
double progress = 0;
|
double progress = 0;
|
||||||
|
|
||||||
|
@ -299,23 +322,23 @@ class _MyAppState extends State<MyApp> {
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
onWebViewCreated: (InAppWebViewController controller) {
|
||||||
webView = controller;
|
webView = controller;
|
||||||
},
|
},
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
onLoadStart: (controller, url) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
onLoadStop: (controller, url) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
onProgressChanged: (controller, progress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.progress = progress / 100;
|
this.progress = progress / 100;
|
||||||
});
|
});
|
||||||
|
@ -329,25 +352,19 @@ class _MyAppState extends State<MyApp> {
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_back),
|
child: Icon(Icons.arrow_back),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goBack();
|
||||||
webView.goBack();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_forward),
|
child: Icon(Icons.arrow_forward),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goForward();
|
||||||
webView.goForward();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.refresh),
|
child: Icon(Icons.refresh),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.reload();
|
||||||
webView.reload();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -445,7 +462,7 @@ Methods available:
|
||||||
|
|
||||||
##### `InAppWebViewController` Android-specific methods
|
##### `InAppWebViewController` Android-specific methods
|
||||||
|
|
||||||
Android-specific methods can be called using the `InAppWebViewController.android` attribute.
|
Android-specific methods can be called using the `InAppWebViewController.android` attribute. Static methods can be called using the `AndroidInAppWebViewController` class directly.
|
||||||
|
|
||||||
* `startSafeBrowsing`: Starts Safe Browsing initialization.
|
* `startSafeBrowsing`: Starts Safe Browsing initialization.
|
||||||
* `clearSslPreferences`: Clears the SSL preferences table stored in response to proceeding with SSL certificate errors.
|
* `clearSslPreferences`: Clears the SSL preferences table stored in response to proceeding with SSL certificate errors.
|
||||||
|
@ -462,10 +479,11 @@ Android-specific methods can be called using the `InAppWebViewController.android
|
||||||
* `static getSafeBrowsingPrivacyPolicyUrl`: Returns a URL pointing to the privacy policy for Safe Browsing reporting. This value will never be `null`.
|
* `static getSafeBrowsingPrivacyPolicyUrl`: Returns a URL pointing to the privacy policy for Safe Browsing reporting. This value will never be `null`.
|
||||||
* `static setSafeBrowsingWhitelist({@required List<String> hosts})`: Sets the list of hosts (domain names/IP addresses) that are exempt from SafeBrowsing checks. The list is global for all the WebViews.
|
* `static setSafeBrowsingWhitelist({@required List<String> hosts})`: Sets the list of hosts (domain names/IP addresses) that are exempt from SafeBrowsing checks. The list is global for all the WebViews.
|
||||||
* `static getCurrentWebViewPackage`: Gets the current Android WebView package info.
|
* `static getCurrentWebViewPackage`: Gets the current Android WebView package info.
|
||||||
|
* `static setWebContentsDebuggingEnabled(bool debuggingEnabled)`: Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application. Debugging is disabled by default.
|
||||||
|
|
||||||
##### `InAppWebViewController` iOS-specific methods
|
##### `InAppWebViewController` iOS-specific methods
|
||||||
|
|
||||||
iOS-specific methods can be called using the `InAppWebViewController.ios` attribute.
|
iOS-specific methods can be called using the `InAppWebViewController.ios` attribute. Static methods can be called using the `IOSInAppWebViewController` class directly.
|
||||||
|
|
||||||
* `hasOnlySecureContent`: A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections.
|
* `hasOnlySecureContent`: A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections.
|
||||||
* `reloadFromOrigin`: Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible.
|
* `reloadFromOrigin`: Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible.
|
||||||
|
@ -528,7 +546,6 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
||||||
* `userAgent`: Sets the user-agent for the WebView.
|
* `userAgent`: Sets the user-agent for the WebView.
|
||||||
* `applicationNameForUserAgent`: Append to the existing user-agent. Setting userAgent will override this.
|
* `applicationNameForUserAgent`: Append to the existing user-agent. Setting userAgent will override this.
|
||||||
* `javaScriptEnabled`: Set to `true` to enable JavaScript. The default value is `true`.
|
* `javaScriptEnabled`: Set to `true` to enable JavaScript. The default value is `true`.
|
||||||
* `debuggingEnabled`: Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
|
|
||||||
* `javaScriptCanOpenWindowsAutomatically`: Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`.
|
* `javaScriptCanOpenWindowsAutomatically`: Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`.
|
||||||
* `mediaPlaybackRequiresUserGesture`: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`.
|
* `mediaPlaybackRequiresUserGesture`: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`.
|
||||||
* `minimumFontSize`: Sets the minimum font size. The default value is `8` for Android, `0` for iOS.
|
* `minimumFontSize`: Sets the minimum font size. The default value is `8` for Android, `0` for iOS.
|
||||||
|
@ -699,6 +716,9 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,8 +729,8 @@ class MyApp extends StatefulWidget {
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
|
|
||||||
InAppWebViewController webView;
|
InAppWebViewController? webView;
|
||||||
ContextMenu contextMenu;
|
ContextMenu? contextMenu;
|
||||||
String url = "";
|
String url = "";
|
||||||
double progress = 0;
|
double progress = 0;
|
||||||
|
|
||||||
|
@ -727,7 +747,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
onCreateContextMenu: (hitTestResult) async {
|
onCreateContextMenu: (hitTestResult) async {
|
||||||
print("onCreateContextMenu");
|
print("onCreateContextMenu");
|
||||||
print(hitTestResult.extra);
|
print(hitTestResult.extra);
|
||||||
print(await webView.getSelectedText());
|
print(await webView?.getSelectedText());
|
||||||
},
|
},
|
||||||
onHideContextMenu: () {
|
onHideContextMenu: () {
|
||||||
print("onHideContextMenu");
|
print("onHideContextMenu");
|
||||||
|
@ -775,23 +795,23 @@ class _MyAppState extends State<MyApp> {
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
onWebViewCreated: (InAppWebViewController controller) {
|
||||||
webView = controller;
|
webView = controller;
|
||||||
},
|
},
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
onLoadStart: (controller, url) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
onLoadStop: (controller, url) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
onProgressChanged: (controller, progress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.progress = progress / 100;
|
this.progress = progress / 100;
|
||||||
});
|
});
|
||||||
|
@ -805,25 +825,19 @@ class _MyAppState extends State<MyApp> {
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_back),
|
child: Icon(Icons.arrow_back),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goBack();
|
||||||
webView.goBack();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_forward),
|
child: Icon(Icons.arrow_forward),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goForward();
|
||||||
webView.goForward();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.refresh),
|
child: Icon(Icons.refresh),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.reload();
|
||||||
webView.reload();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -856,12 +870,16 @@ As `InAppWebView`, it has the same options and events. Use `InAppWebViewControll
|
||||||
Example:
|
Example:
|
||||||
```dart
|
```dart
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,7 +890,7 @@ class MyApp extends StatefulWidget {
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
|
|
||||||
HeadlessInAppWebView headlessWebView;
|
HeadlessInAppWebView? headlessWebView;
|
||||||
String url = "";
|
String url = "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -883,7 +901,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
initialUrl: "https://flutter.dev/",
|
initialUrl: "https://flutter.dev/",
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onWebViewCreated: (controller) {
|
onWebViewCreated: (controller) {
|
||||||
|
@ -895,19 +913,19 @@ class _MyAppState extends State<MyApp> {
|
||||||
onLoadStart: (controller, url) async {
|
onLoadStart: (controller, url) async {
|
||||||
print("onLoadStart $url");
|
print("onLoadStart $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoadStop: (controller, url) async {
|
onLoadStop: (controller, url) async {
|
||||||
print("onLoadStop $url");
|
print("onLoadStop $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onUpdateVisitedHistory: (InAppWebViewController controller, String url, bool androidIsReload) {
|
onUpdateVisitedHistory: (controller, url, androidIsReload) {
|
||||||
print("onUpdateVisitedHistory $url");
|
print("onUpdateVisitedHistory $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -916,7 +934,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
headlessWebView.dispose();
|
headlessWebView?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -936,8 +954,8 @@ class _MyAppState extends State<MyApp> {
|
||||||
Center(
|
Center(
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await headlessWebView.dispose();
|
await headlessWebView?.dispose();
|
||||||
await headlessWebView.run();
|
await headlessWebView?.run();
|
||||||
},
|
},
|
||||||
child: Text("Run HeadlessInAppWebView")),
|
child: Text("Run HeadlessInAppWebView")),
|
||||||
),
|
),
|
||||||
|
@ -945,7 +963,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
try {
|
||||||
await headlessWebView.webViewController.evaluateJavascript(source: """console.log('Here is the message!');""");
|
await headlessWebView?.webViewController.evaluateJavascript(source: """console.log('Here is the message!');""");
|
||||||
} on MissingPluginException catch(e) {
|
} on MissingPluginException catch(e) {
|
||||||
print("HeadlessInAppWebView is not running. Click on \"Run HeadlessInAppWebView\"!");
|
print("HeadlessInAppWebView is not running. Click on \"Run HeadlessInAppWebView\"!");
|
||||||
}
|
}
|
||||||
|
@ -955,7 +973,7 @@ class _MyAppState extends State<MyApp> {
|
||||||
Center(
|
Center(
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
headlessWebView.dispose();
|
headlessWebView?.dispose();
|
||||||
},
|
},
|
||||||
child: Text("Dispose HeadlessInAppWebView")),
|
child: Text("Dispose HeadlessInAppWebView")),
|
||||||
)
|
)
|
||||||
|
@ -975,6 +993,8 @@ In-App Browser using native WebView.
|
||||||
Create a Class that extends the `InAppBrowser` Class in order to override the callbacks to manage the browser events.
|
Create a Class that extends the `InAppBrowser` Class in order to override the callbacks to manage the browser events.
|
||||||
Example:
|
Example:
|
||||||
```dart
|
```dart
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
|
@ -985,22 +1005,22 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStart(String url) async {
|
Future onLoadStart(url) async {
|
||||||
print("\n\nStarted $url\n\n");
|
print("\n\nStarted $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStop(String url) async {
|
Future onLoadStop(url) async {
|
||||||
print("\n\nStopped $url\n\n");
|
print("\n\nStopped $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLoadError(String url, int code, String message) {
|
void onLoadError(url, code, message) {
|
||||||
print("Can't load $url.. Error: $message");
|
print("Can't load $url.. Error: $message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onProgressChanged(int progress) {
|
void onProgressChanged(progress) {
|
||||||
print("Progress: $progress");
|
print("Progress: $progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,7 +1042,7 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
"ms ---> duration: " +
|
"ms ---> duration: " +
|
||||||
response.duration.toString() +
|
response.duration.toString() +
|
||||||
"ms " +
|
"ms " +
|
||||||
response.url);
|
(response.url ?? ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1030,13 +1050,16 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
print("""
|
print("""
|
||||||
console output:
|
console output:
|
||||||
message: ${consoleMessage.message}
|
message: ${consoleMessage.message}
|
||||||
messageLevel: ${consoleMessage.messageLevel.toValue()}
|
messageLevel: ${consoleMessage.messageLevel?.toValue()}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(
|
runApp(
|
||||||
new MyApp(),
|
new MyApp(),
|
||||||
);
|
);
|
||||||
|
@ -1147,23 +1170,25 @@ You can initialize the `ChromeSafariBrowser` instance with an `InAppBrowser` fal
|
||||||
|
|
||||||
Create a Class that extends the `ChromeSafariBrowser` Class in order to override the callbacks to manage the browser events. Example:
|
Create a Class that extends the `ChromeSafariBrowser` Class in order to override the callbacks to manage the browser events. Example:
|
||||||
```dart
|
```dart
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
class MyInAppBrowser extends InAppBrowser {
|
class MyInAppBrowser extends InAppBrowser {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStart(String url) async {
|
Future onLoadStart(url) async {
|
||||||
print("\n\nStarted $url\n\n");
|
print("\n\nStarted $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStop(String url) async {
|
Future onLoadStop(url) async {
|
||||||
print("\n\nStopped $url\n\n");
|
print("\n\nStopped $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLoadError(String url, int code, String message) {
|
void onLoadError(url, code, message) {
|
||||||
print("\n\nCan't load $url.. Error: $message\n\n");
|
print("\n\nCan't load $url.. Error: $message\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1194,11 +1219,12 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
runApp(
|
if (Platform.isAndroid) {
|
||||||
new MyApp(),
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
);
|
}
|
||||||
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
class MyApp extends StatefulWidget {
|
||||||
|
@ -1308,6 +1334,9 @@ InAppLocalhostServer localhostServer = new InAppLocalhostServer();
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await localhostServer.start();
|
await localhostServer.start();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1328,17 +1357,17 @@ Future main() async {
|
||||||
initialUrl: "http://localhost:8080/assets/index.html",
|
initialUrl: "http://localhost:8080/assets/index.html",
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
inAppWebViewOptions: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
onWebViewCreated: (controller) {
|
||||||
|
|
||||||
},
|
},
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
onLoadStart: (controller, url) {
|
||||||
|
|
||||||
},
|
},
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
onLoadStop: (controller, url) {
|
||||||
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -109,6 +109,7 @@ public class ContentBlockerHandler {
|
||||||
latch.await();
|
latch.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webViewUrl[0] != null) {
|
||||||
if (!trigger.loadType.isEmpty()) {
|
if (!trigger.loadType.isEmpty()) {
|
||||||
URI cUrl = new URI(webViewUrl[0]);
|
URI cUrl = new URI(webViewUrl[0]);
|
||||||
String cHost = cUrl.getHost();
|
String cHost = cUrl.getHost();
|
||||||
|
@ -135,6 +136,7 @@ public class ContentBlockerHandler {
|
||||||
if (webViewUrl[0].startsWith(topUrl))
|
if (webViewUrl[0].startsWith(topUrl))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
|
||||||
|
|
|
@ -67,28 +67,9 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
|
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// MutableContextWrapper mMutableContext = new MutableContextWrapper(Shared.activity);
|
webView = new InAppWebView(context, this, id, windowId, options, contextMenu, containerView);
|
||||||
// webView = new InAppWebView(mMutableContext, this, id, options, contextMenu, containerView);
|
|
||||||
// displayListenerProxy.onPostWebViewInitialization(displayManager);
|
|
||||||
// mMutableContext.setBaseContext(context);
|
|
||||||
|
|
||||||
webView = new InAppWebView(Shared.activity, this, id, windowId, options, contextMenu, containerView);
|
|
||||||
displayListenerProxy.onPostWebViewInitialization(displayManager);
|
displayListenerProxy.onPostWebViewInitialization(displayManager);
|
||||||
|
|
||||||
// fix https://github.com/pichillilorenzo/flutter_inappwebview/issues/182
|
|
||||||
try {
|
|
||||||
Class superClass = webView.getClass().getSuperclass();
|
|
||||||
while(!superClass.getName().equals("android.view.View")) {
|
|
||||||
superClass = superClass.getSuperclass();
|
|
||||||
}
|
|
||||||
Field mContext = superClass.getDeclaredField("mContext");
|
|
||||||
mContext.setAccessible(true);
|
|
||||||
mContext.set(webView, context);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Log.e(LOG_TAG, "Cannot find mContext for this WebView");
|
|
||||||
}
|
|
||||||
|
|
||||||
webView.prepare();
|
webView.prepare();
|
||||||
|
|
||||||
if (windowId != null) {
|
if (windowId != null) {
|
||||||
|
|
|
@ -677,9 +677,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
WebSettings settings = getSettings();
|
WebSettings settings = getSettings();
|
||||||
|
|
||||||
settings.setJavaScriptEnabled(options.javaScriptEnabled);
|
settings.setJavaScriptEnabled(options.javaScriptEnabled);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
|
||||||
setWebContentsDebuggingEnabled(options.debuggingEnabled);
|
|
||||||
}
|
|
||||||
settings.setJavaScriptCanOpenWindowsAutomatically(options.javaScriptCanOpenWindowsAutomatically);
|
settings.setJavaScriptCanOpenWindowsAutomatically(options.javaScriptCanOpenWindowsAutomatically);
|
||||||
settings.setBuiltInZoomControls(options.builtInZoomControls);
|
settings.setBuiltInZoomControls(options.builtInZoomControls);
|
||||||
settings.setDisplayZoomControls(options.displayZoomControls);
|
settings.setDisplayZoomControls(options.displayZoomControls);
|
||||||
|
@ -853,7 +850,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && !options.useHybridComposition) {
|
||||||
checkContextMenuShouldBeClosedTask = new Runnable() {
|
checkContextMenuShouldBeClosedTask = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -1133,9 +1130,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
if (newOptionsMap.get("javaScriptEnabled") != null && options.javaScriptEnabled != newOptions.javaScriptEnabled)
|
if (newOptionsMap.get("javaScriptEnabled") != null && options.javaScriptEnabled != newOptions.javaScriptEnabled)
|
||||||
settings.setJavaScriptEnabled(newOptions.javaScriptEnabled);
|
settings.setJavaScriptEnabled(newOptions.javaScriptEnabled);
|
||||||
|
|
||||||
if (newOptionsMap.get("debuggingEnabled") != null && options.debuggingEnabled != newOptions.debuggingEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
|
||||||
setWebContentsDebuggingEnabled(newOptions.debuggingEnabled);
|
|
||||||
|
|
||||||
if (newOptionsMap.get("useShouldInterceptAjaxRequest") != null && options.useShouldInterceptAjaxRequest != newOptions.useShouldInterceptAjaxRequest) {
|
if (newOptionsMap.get("useShouldInterceptAjaxRequest") != null && options.useShouldInterceptAjaxRequest != newOptions.useShouldInterceptAjaxRequest) {
|
||||||
String placeholderValue = newOptions.useShouldInterceptAjaxRequest ? "true" : "false";
|
String placeholderValue = newOptions.useShouldInterceptAjaxRequest ? "true" : "false";
|
||||||
String sourceJs = InAppWebView.enableVariableForShouldInterceptAjaxRequestJS.replace("$PLACEHOLDER_VALUE", placeholderValue);
|
String sourceJs = InAppWebView.enableVariableForShouldInterceptAjaxRequestJS.replace("$PLACEHOLDER_VALUE", placeholderValue);
|
||||||
|
@ -1505,14 +1499,11 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onScrollChanged (int l,
|
protected void onScrollChanged (int x,
|
||||||
int t,
|
int y,
|
||||||
int oldl,
|
int oldX,
|
||||||
int oldt) {
|
int oldY) {
|
||||||
super.onScrollChanged(l, t, oldl, oldt);
|
super.onScrollChanged(x, y, oldX, oldY);
|
||||||
|
|
||||||
int x = (int) (l/scale);
|
|
||||||
int y = (int) (t/scale);
|
|
||||||
|
|
||||||
if (floatingContextMenu != null) {
|
if (floatingContextMenu != null) {
|
||||||
floatingContextMenu.setAlpha(0f);
|
floatingContextMenu.setAlpha(0f);
|
||||||
|
@ -1662,12 +1653,18 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionMode startActionMode(ActionMode.Callback callback) {
|
public ActionMode startActionMode(ActionMode.Callback callback) {
|
||||||
|
if (options.useHybridComposition && !options.disableContextMenu && (contextMenu == null || contextMenu.keySet().size() == 0)) {
|
||||||
|
return super.startActionMode(callback);
|
||||||
|
}
|
||||||
return rebuildActionMode(super.startActionMode(callback), callback);
|
return rebuildActionMode(super.startActionMode(callback), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
@Override
|
@Override
|
||||||
public ActionMode startActionMode(ActionMode.Callback callback, int type) {
|
public ActionMode startActionMode(ActionMode.Callback callback, int type) {
|
||||||
|
if (options.useHybridComposition && !options.disableContextMenu && (contextMenu == null || contextMenu.keySet().size() == 0)) {
|
||||||
|
return super.startActionMode(callback, type);
|
||||||
|
}
|
||||||
return rebuildActionMode(super.startActionMode(callback, type), callback);
|
return rebuildActionMode(super.startActionMode(callback, type), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,6 +1708,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
final MenuItem menuItem = actionMenu.getItem(i);
|
final MenuItem menuItem = actionMenu.getItem(i);
|
||||||
final int itemId = menuItem.getItemId();
|
final int itemId = menuItem.getItemId();
|
||||||
final String itemTitle = menuItem.getTitle().toString();
|
final String itemTitle = menuItem.getTitle().toString();
|
||||||
|
|
||||||
TextView text = (TextView) LayoutInflater.from(this.getContext())
|
TextView text = (TextView) LayoutInflater.from(this.getContext())
|
||||||
.inflate(R.layout.floating_action_mode_item, this, false);
|
.inflate(R.layout.floating_action_mode_item, this, false);
|
||||||
text.setText(itemTitle);
|
text.setText(itemTitle);
|
||||||
|
@ -1855,7 +1853,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
" var clientRect = range.getClientRects();" +
|
" var clientRect = range.getClientRects();" +
|
||||||
" if (clientRect.length > 0) {" +
|
" if (clientRect.length > 0) {" +
|
||||||
" rangeY = clientRect[0].y;" +
|
" rangeY = clientRect[0].y;" +
|
||||||
" } else if (document.activeElement) {" +
|
" } else if (document.activeElement != null && document.activeElement.tagName.toLowerCase() !== 'iframe') {" +
|
||||||
" var boundingClientRect = document.activeElement.getBoundingClientRect();" +
|
" var boundingClientRect = document.activeElement.getBoundingClientRect();" +
|
||||||
" rangeY = boundingClientRect.y;" +
|
" rangeY = boundingClientRect.y;" +
|
||||||
" }" +
|
" }" +
|
||||||
|
@ -1865,7 +1863,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
@Override
|
@Override
|
||||||
public void onReceiveValue(String value) {
|
public void onReceiveValue(String value) {
|
||||||
if (floatingContextMenu != null) {
|
if (floatingContextMenu != null) {
|
||||||
if (value != null) {
|
if (value != null && !value.equals("null")) {
|
||||||
int x = contextMenuPoint.x;
|
int x = contextMenuPoint.x;
|
||||||
int y = (int) ((Float.parseFloat(value) * scale) + (floatingContextMenu.getHeight() / 3.5));
|
int y = (int) ((Float.parseFloat(value) * scale) + (floatingContextMenu.getHeight() / 3.5));
|
||||||
contextMenuPoint.y = y;
|
contextMenuPoint.y = y;
|
||||||
|
@ -1873,6 +1871,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
} else {
|
} else {
|
||||||
floatingContextMenu.setVisibility(View.VISIBLE);
|
floatingContextMenu.setVisibility(View.VISIBLE);
|
||||||
floatingContextMenu.animate().alpha(1f).setDuration(100).setListener(null);
|
floatingContextMenu.animate().alpha(1f).setDuration(100).setListener(null);
|
||||||
|
onFloatingActionGlobalLayout(contextMenuPoint.x, contextMenuPoint.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,9 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
if (webView.options.useOnLoadResource) {
|
if (webView.options.useOnLoadResource) {
|
||||||
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
|
||||||
}
|
}
|
||||||
|
if (!webView.options.useHybridComposition) {
|
||||||
js += InAppWebView.checkGlobalKeyDownEventToHideContextMenuJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.checkGlobalKeyDownEventToHideContextMenuJS.replaceAll("[\r\n]+", "");
|
||||||
|
}
|
||||||
js += InAppWebView.onWindowFocusEventJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.onWindowFocusEventJS.replaceAll("[\r\n]+", "");
|
||||||
js += InAppWebView.onWindowBlurEventJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.onWindowBlurEventJS.replaceAll("[\r\n]+", "");
|
||||||
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
|
||||||
|
|
|
@ -26,7 +26,6 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
public String userAgent = "";
|
public String userAgent = "";
|
||||||
public String applicationNameForUserAgent = "";
|
public String applicationNameForUserAgent = "";
|
||||||
public Boolean javaScriptEnabled = true;
|
public Boolean javaScriptEnabled = true;
|
||||||
public Boolean debuggingEnabled = false;
|
|
||||||
public Boolean javaScriptCanOpenWindowsAutomatically = false;
|
public Boolean javaScriptCanOpenWindowsAutomatically = false;
|
||||||
public Boolean mediaPlaybackRequiresUserGesture = true;
|
public Boolean mediaPlaybackRequiresUserGesture = true;
|
||||||
public Integer minimumFontSize = 8;
|
public Integer minimumFontSize = 8;
|
||||||
|
@ -97,6 +96,7 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
public Boolean useShouldInterceptRequest = false;
|
public Boolean useShouldInterceptRequest = false;
|
||||||
public Boolean useOnRenderProcessGone = false;
|
public Boolean useOnRenderProcessGone = false;
|
||||||
public Boolean disableDefaultErrorPage = false;
|
public Boolean disableDefaultErrorPage = false;
|
||||||
|
public Boolean useHybridComposition = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InAppWebViewOptions parse(Map<String, Object> options) {
|
public InAppWebViewOptions parse(Map<String, Object> options) {
|
||||||
|
@ -129,9 +129,6 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
case "javaScriptEnabled":
|
case "javaScriptEnabled":
|
||||||
javaScriptEnabled = (Boolean) value;
|
javaScriptEnabled = (Boolean) value;
|
||||||
break;
|
break;
|
||||||
case "debuggingEnabled":
|
|
||||||
debuggingEnabled = (Boolean) value;
|
|
||||||
break;
|
|
||||||
case "javaScriptCanOpenWindowsAutomatically":
|
case "javaScriptCanOpenWindowsAutomatically":
|
||||||
javaScriptCanOpenWindowsAutomatically = (Boolean) value;
|
javaScriptCanOpenWindowsAutomatically = (Boolean) value;
|
||||||
break;
|
break;
|
||||||
|
@ -339,6 +336,9 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
case "disableDefaultErrorPage":
|
case "disableDefaultErrorPage":
|
||||||
disableDefaultErrorPage = (Boolean) value;
|
disableDefaultErrorPage = (Boolean) value;
|
||||||
break;
|
break;
|
||||||
|
case "useHybridComposition":
|
||||||
|
useHybridComposition = (Boolean) value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +355,6 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
options.put("userAgent", userAgent);
|
options.put("userAgent", userAgent);
|
||||||
options.put("applicationNameForUserAgent", applicationNameForUserAgent);
|
options.put("applicationNameForUserAgent", applicationNameForUserAgent);
|
||||||
options.put("javaScriptEnabled", javaScriptEnabled);
|
options.put("javaScriptEnabled", javaScriptEnabled);
|
||||||
options.put("debuggingEnabled", debuggingEnabled);
|
|
||||||
options.put("javaScriptCanOpenWindowsAutomatically", javaScriptCanOpenWindowsAutomatically);
|
options.put("javaScriptCanOpenWindowsAutomatically", javaScriptCanOpenWindowsAutomatically);
|
||||||
options.put("mediaPlaybackRequiresUserGesture", mediaPlaybackRequiresUserGesture);
|
options.put("mediaPlaybackRequiresUserGesture", mediaPlaybackRequiresUserGesture);
|
||||||
options.put("minimumFontSize", minimumFontSize);
|
options.put("minimumFontSize", minimumFontSize);
|
||||||
|
@ -425,6 +424,7 @@ public class InAppWebViewOptions implements Options<InAppWebView> {
|
||||||
options.put("useShouldInterceptRequest", useShouldInterceptRequest);
|
options.put("useShouldInterceptRequest", useShouldInterceptRequest);
|
||||||
options.put("useOnRenderProcessGone", useOnRenderProcessGone);
|
options.put("useOnRenderProcessGone", useOnRenderProcessGone);
|
||||||
options.put("disableDefaultErrorPage", disableDefaultErrorPage);
|
options.put("disableDefaultErrorPage", disableDefaultErrorPage);
|
||||||
|
options.put("useHybridComposition", useHybridComposition);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ import android.widget.ListPopupWindow;
|
||||||
* A WebView subclass that mirrors the same implementation hacks that the system WebView does in
|
* A WebView subclass that mirrors the same implementation hacks that the system WebView does in
|
||||||
* order to correctly create an InputConnection.
|
* order to correctly create an InputConnection.
|
||||||
*
|
*
|
||||||
|
* These hacks are only needed in Android versions below N and exist to create an InputConnection
|
||||||
|
* on the WebView's dedicated input, or IME, thread. The majority of this proxying logic is in
|
||||||
* https://github.com/flutter/plugins/blob/master/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java
|
* https://github.com/flutter/plugins/blob/master/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java
|
||||||
*/
|
*/
|
||||||
public class InputAwareWebView extends WebView {
|
public class InputAwareWebView extends WebView {
|
||||||
|
@ -234,9 +236,9 @@ public class InputAwareWebView extends WebView {
|
||||||
|
|
||||||
private boolean isCalledFromListPopupWindowShow() {
|
private boolean isCalledFromListPopupWindowShow() {
|
||||||
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||||
for (int i = 0; i < stackTraceElements.length; i++) {
|
for (StackTraceElement stackTraceElement : stackTraceElements) {
|
||||||
if (stackTraceElements[i].getClassName().equals(ListPopupWindow.class.getCanonicalName())
|
if (stackTraceElement.getClassName().equals(ListPopupWindow.class.getCanonicalName())
|
||||||
&& stackTraceElements[i].getMethodName().equals("show")) {
|
&& stackTraceElement.getMethodName().equals("show")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,13 @@ public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
|
||||||
result.success(null);
|
result.success(null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "setWebContentsDebuggingEnabled":
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
boolean debuggingEnabled = (boolean) call.argument("debuggingEnabled");
|
||||||
|
WebView.setWebContentsDebuggingEnabled(debuggingEnabled);
|
||||||
|
}
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.10/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.11/","dependencies":[]}],"android":[{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.10/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.11/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+7/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[{"name":"url_launcher_web","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.2/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_inappwebview","dependencies":[]},{"name":"e2e","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]}],"date_created":"2020-09-07 18:06:16.830498","version":"1.20.3"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"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":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"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":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","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.0.1+2/","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.0.4+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":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"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-01-28 16:30:24.941683","version":"1.26.0-13.0.pre.194"}
|
|
@ -1,15 +1,16 @@
|
||||||
package com.pichillilorenzo.flutterwebviewexample;
|
package com.pichillilorenzo.flutterwebviewexample;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import dev.flutter.plugins.e2e.E2EPlugin;
|
import dev.flutter.plugins.integration_test.IntegrationTestPlugin;
|
||||||
import io.flutter.app.FlutterActivity;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||||
|
|
||||||
public class EmbedderV1Activity extends FlutterActivity {
|
@SuppressWarnings("deprecation")
|
||||||
|
public class EmbedderV1Activity extends io.flutter.app.FlutterActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin"));
|
IntegrationTestPlugin.registerWith(
|
||||||
|
registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin"));
|
||||||
InAppWebViewFlutterPlugin.registerWith(
|
InAppWebViewFlutterPlugin.registerWith(
|
||||||
registrarFor("com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin"));
|
registrarFor("com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin"));
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
final environment = {"NODE_SERVER_IP":"192.168.1.129"};
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
FLUTTER_BUILD_MODE=debug
|
FLUTTER_BUILD_MODE=debug
|
|
@ -1,18 +1,18 @@
|
||||||
#
|
#
|
||||||
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
#
|
#
|
||||||
|
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = 'Flutter'
|
s.name = 'Flutter'
|
||||||
s.version = '1.0.0'
|
s.version = '1.0.0'
|
||||||
s.summary = 'High-performance, high-fidelity mobile apps.'
|
s.summary = 'High-performance, high-fidelity mobile apps.'
|
||||||
s.description = <<-DESC
|
|
||||||
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
|
|
||||||
DESC
|
|
||||||
s.homepage = 'https://flutter.io'
|
s.homepage = 'https://flutter.io'
|
||||||
s.license = { :type => 'MIT' }
|
s.license = { :type => 'MIT' }
|
||||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||||
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||||
s.ios.deployment_target = '8.0'
|
s.ios.deployment_target = '8.0'
|
||||||
s.vendored_frameworks = 'Flutter.framework'
|
# Framework linking is handled by Flutter tooling, not CocoaPods.
|
||||||
|
# Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs.
|
||||||
|
s.vendored_frameworks = 'path/to/nothing'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|
|
@ -5,11 +5,10 @@ export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappweb
|
||||||
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
|
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
|
||||||
export "FLUTTER_BUILD_DIR=build"
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
||||||
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
|
|
||||||
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
|
||||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
export "FLUTTER_BUILD_NUMBER=1"
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue,FLUTTER_WEB_AUTO_DETECT%3Dtrue"
|
||||||
export "DART_OBFUSCATION=false"
|
export "DART_OBFUSCATION=false"
|
||||||
export "TRACK_WIDGET_CREATION=true"
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
export "TREE_SHAKE_ICONS=false"
|
export "TREE_SHAKE_ICONS=false"
|
||||||
export "PACKAGE_CONFIG=.packages"
|
export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json"
|
||||||
|
|
|
@ -254,19 +254,17 @@
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/e2e/e2e.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_downloader/flutter_downloader.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework",
|
||||||
|
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/e2e.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_downloader.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework",
|
||||||
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
||||||
);
|
);
|
||||||
|
@ -451,7 +449,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutter_inappwebviewExample;
|
PRODUCT_BUNDLE_IDENTIFIER = "flutter-inappwebviewExample";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
@ -2,54 +2,52 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSLocationAlwaysUsageDescription</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>Need location</string>
|
<string>en</string>
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string>Need location</string>
|
|
||||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
|
||||||
<string>Need location</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>flutter_inappwebview_example</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
|
||||||
<key>UIBackgroundModes</key>
|
|
||||||
<array>
|
|
||||||
<string>fetch</string>
|
|
||||||
<string>remote-notification</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>flutter_inappwebview_example</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UILaunchStoryboardName</key>
|
|
||||||
<string>LaunchScreen</string>
|
|
||||||
<key>UIMainStoryboardFile</key>
|
|
||||||
<string>Main</string>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>Need location</string>
|
||||||
|
<key>NSLocationAlwaysUsageDescription</key>
|
||||||
|
<string>Need location</string>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>Need location</string>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>fetch</string>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
</array>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
|
||||||
<false/>
|
|
||||||
<key>io.flutter.embedded_views_preview</key>
|
|
||||||
<true/>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>????</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
@ -57,7 +55,13 @@
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>NSBonjourServices</key>
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
<array>
|
||||||
|
<string></string>
|
||||||
|
</array>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSLocalNetworkUsageDescription</key>
|
||||||
|
<string>Allow Flutter tools on your computer to connect and debug your application.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -11,7 +11,7 @@ class HeadlessInAppWebViewExampleScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebViewExampleScreen> {
|
class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebViewExampleScreen> {
|
||||||
HeadlessInAppWebView headlessWebView;
|
HeadlessInAppWebView? headlessWebView;
|
||||||
String url = "";
|
String url = "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -22,7 +22,7 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
initialUrl: "https://flutter.dev/",
|
initialUrl: "https://flutter.dev/",
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onWebViewCreated: (controller) {
|
onWebViewCreated: (controller) {
|
||||||
|
@ -34,19 +34,19 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
onLoadStart: (controller, url) async {
|
onLoadStart: (controller, url) async {
|
||||||
print("onLoadStart $url");
|
print("onLoadStart $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoadStop: (controller, url) async {
|
onLoadStop: (controller, url) async {
|
||||||
print("onLoadStop $url");
|
print("onLoadStop $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onUpdateVisitedHistory: (InAppWebViewController controller, String url, bool androidIsReload) {
|
onUpdateVisitedHistory: (controller, url, androidIsReload) {
|
||||||
print("onUpdateVisitedHistory $url");
|
print("onUpdateVisitedHistory $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -55,7 +55,7 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
headlessWebView.dispose();
|
headlessWebView?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -76,8 +76,8 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
Center(
|
Center(
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await headlessWebView.dispose();
|
await headlessWebView?.dispose();
|
||||||
await headlessWebView.run();
|
await headlessWebView?.run();
|
||||||
},
|
},
|
||||||
child: Text("Run HeadlessInAppWebView")),
|
child: Text("Run HeadlessInAppWebView")),
|
||||||
),
|
),
|
||||||
|
@ -85,7 +85,7 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
try {
|
||||||
await headlessWebView.webViewController.evaluateJavascript(source: """console.log('Here is the message!');""");
|
await headlessWebView?.webViewController.evaluateJavascript(source: """console.log('Here is the message!');""");
|
||||||
} on MissingPluginException catch(e) {
|
} on MissingPluginException catch(e) {
|
||||||
print("HeadlessInAppWebView is not running. Click on \"Run HeadlessInAppWebView\"!");
|
print("HeadlessInAppWebView is not running. Click on \"Run HeadlessInAppWebView\"!");
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ class _HeadlessInAppWebViewExampleScreenState extends State<HeadlessInAppWebView
|
||||||
Center(
|
Center(
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
headlessWebView.dispose();
|
headlessWebView?.dispose();
|
||||||
},
|
},
|
||||||
child: Text("Dispose HeadlessInAppWebView")),
|
child: Text("Dispose HeadlessInAppWebView")),
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,22 +12,22 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStart(String url) async {
|
Future onLoadStart(url) async {
|
||||||
print("\n\nStarted $url\n\n");
|
print("\n\nStarted $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStop(String url) async {
|
Future onLoadStop(url) async {
|
||||||
print("\n\nStopped $url\n\n");
|
print("\n\nStopped $url\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLoadError(String url, int code, String message) {
|
void onLoadError(url, code, message) {
|
||||||
print("Can't load $url.. Error: $message");
|
print("Can't load $url.. Error: $message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onProgressChanged(int progress) {
|
void onProgressChanged(progress) {
|
||||||
print("Progress: $progress");
|
print("Progress: $progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,27 +38,27 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(
|
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(
|
||||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
shouldOverrideUrlLoadingRequest) async {
|
||||||
print("\n\nOverride ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
print("\n\nOverride ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
||||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
return ShouldOverrideUrlLoadingAction.ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLoadResource(LoadedResource response) {
|
void onLoadResource(response) {
|
||||||
print("Started at: " +
|
print("Started at: " +
|
||||||
response.startTime.toString() +
|
response.startTime.toString() +
|
||||||
"ms ---> duration: " +
|
"ms ---> duration: " +
|
||||||
response.duration.toString() +
|
response.duration.toString() +
|
||||||
"ms " +
|
"ms " +
|
||||||
response.url);
|
response.url!);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onConsoleMessage(ConsoleMessage consoleMessage) {
|
void onConsoleMessage(consoleMessage) {
|
||||||
print("""
|
print("""
|
||||||
console output:
|
console output:
|
||||||
message: ${consoleMessage.message}
|
message: ${consoleMessage.message}
|
||||||
messageLevel: ${consoleMessage.messageLevel.toValue()}
|
messageLevel: ${consoleMessage.messageLevel!.toValue()}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,6 @@ class _InAppBrowserExampleScreenState extends State<InAppBrowserExampleScreen> {
|
||||||
options: InAppBrowserClassOptions(
|
options: InAppBrowserClassOptions(
|
||||||
inAppWebViewGroupOptions: InAppWebViewGroupOptions(
|
inAppWebViewGroupOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
|
||||||
useShouldOverrideUrlLoading: true,
|
useShouldOverrideUrlLoading: true,
|
||||||
useOnLoadResource: true,
|
useOnLoadResource: true,
|
||||||
))));
|
))));
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -14,8 +13,8 @@ class InAppWebViewExampleScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
InAppWebViewController webView;
|
InAppWebViewController? webView;
|
||||||
ContextMenu contextMenu;
|
late ContextMenu contextMenu;
|
||||||
String url = "";
|
String url = "";
|
||||||
double progress = 0;
|
double progress = 0;
|
||||||
CookieManager _cookieManager = CookieManager.instance();
|
CookieManager _cookieManager = CookieManager.instance();
|
||||||
|
@ -28,8 +27,8 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
menuItems: [
|
menuItems: [
|
||||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||||
print("Menu item Special clicked!");
|
print("Menu item Special clicked!");
|
||||||
print(await webView.getSelectedText());
|
print(await webView?.getSelectedText());
|
||||||
await webView.clearFocus();
|
await webView?.clearFocus();
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
options: ContextMenuOptions(
|
options: ContextMenuOptions(
|
||||||
|
@ -38,7 +37,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
onCreateContextMenu: (hitTestResult) async {
|
onCreateContextMenu: (hitTestResult) async {
|
||||||
print("onCreateContextMenu");
|
print("onCreateContextMenu");
|
||||||
print(hitTestResult.extra);
|
print(hitTestResult.extra);
|
||||||
print(await webView.getSelectedText());
|
print(await webView?.getSelectedText());
|
||||||
},
|
},
|
||||||
onHideContextMenu: () {
|
onHideContextMenu: () {
|
||||||
print("onHideContextMenu");
|
print("onHideContextMenu");
|
||||||
|
@ -81,26 +80,25 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
||||||
child: InAppWebView(
|
child: InAppWebView(
|
||||||
// contextMenu: contextMenu,
|
// contextMenu: contextMenu,
|
||||||
initialUrl: "https://github.com/flutter",
|
initialUrl: "https://flutter.dev/",
|
||||||
// initialFile: "assets/index.html",
|
// initialFile: "assets/index.html",
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
debuggingEnabled: true,
|
useShouldOverrideUrlLoading: false
|
||||||
useShouldOverrideUrlLoading: true,
|
|
||||||
),
|
),
|
||||||
android: AndroidInAppWebViewOptions(
|
android: AndroidInAppWebViewOptions(
|
||||||
useHybridComposition: true
|
useHybridComposition: true
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
onWebViewCreated: (controller) {
|
||||||
webView = controller;
|
webView = controller;
|
||||||
print("onWebViewCreated");
|
print("onWebViewCreated");
|
||||||
},
|
},
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
onLoadStart: (controller, url) {
|
||||||
print("onLoadStart $url");
|
print("onLoadStart $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
|
shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
|
||||||
|
@ -122,21 +120,21 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
|
|
||||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
return ShouldOverrideUrlLoadingAction.ALLOW;
|
||||||
},
|
},
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
onLoadStop: (controller, url) async {
|
||||||
print("onLoadStop $url");
|
print("onLoadStop $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
onProgressChanged: (controller, progress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.progress = progress / 100;
|
this.progress = progress / 100;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onUpdateVisitedHistory: (InAppWebViewController controller, String url, bool androidIsReload) {
|
onUpdateVisitedHistory: (controller, url, androidIsReload) {
|
||||||
print("onUpdateVisitedHistory $url");
|
print("onUpdateVisitedHistory $url");
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url;
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onConsoleMessage: (controller, consoleMessage) {
|
onConsoleMessage: (controller, consoleMessage) {
|
||||||
|
@ -151,25 +149,19 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_back),
|
child: Icon(Icons.arrow_back),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goBack();
|
||||||
webView.goBack();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.arrow_forward),
|
child: Icon(Icons.arrow_forward),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.goForward();
|
||||||
webView.goForward();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Icon(Icons.refresh),
|
child: Icon(Icons.refresh),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (webView != null) {
|
webView?.reload();
|
||||||
webView.reload();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
import 'package:flutter_inappwebview_example/chrome_safari_browser_example.screen.dart';
|
import 'package:flutter_inappwebview_example/chrome_safari_browser_example.screen.dart';
|
||||||
import 'package:flutter_inappwebview_example/headless_in_app_webview.screen.dart';
|
import 'package:flutter_inappwebview_example/headless_in_app_webview.screen.dart';
|
||||||
|
@ -15,10 +17,13 @@ Future main() async {
|
||||||
// await Permission.camera.request();
|
// await Permission.camera.request();
|
||||||
// await Permission.storage.request();
|
// await Permission.storage.request();
|
||||||
// await localhostServer.start();
|
// await localhostServer.start();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
}
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawer myDrawer({@required BuildContext context}) {
|
Drawer myDrawer({required BuildContext context}) {
|
||||||
return Drawer(
|
return Drawer(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
|
|
|
@ -10,8 +10,8 @@ description: Demonstrates how to use the flutter_inappwebview plugin.
|
||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.0.0-dev.68.0 <3.0.0"
|
sdk: ">=2.12.0-0 <3.0.0"
|
||||||
flutter: ">=1.10.0 <2.0.0"
|
flutter: ">=1.22.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
@ -19,20 +19,26 @@ dependencies:
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^0.1.2
|
cupertino_icons: ^1.0.2
|
||||||
flutter_downloader: ^1.4.4
|
flutter_downloader: ^1.5.2
|
||||||
path_provider: ^1.6.9
|
path_provider: ^1.6.27
|
||||||
permission_handler: ^5.0.0+hotfix.6
|
permission_handler: ^5.0.1+1
|
||||||
url_launcher: ^5.4.11
|
url_launcher: ^6.0.0-nullsafety.4
|
||||||
# connectivity: ^0.4.5+6
|
# connectivity: ^0.4.5+6
|
||||||
flutter_inappwebview:
|
flutter_inappwebview:
|
||||||
path: ../
|
path: ../
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
e2e: "^0.2.0"
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
flutter_driver:
|
flutter_driver:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
test: any
|
# integration_test: ^1.0.2+1
|
||||||
|
integration_test:
|
||||||
|
git:
|
||||||
|
url: https://github.com/flutter/plugins.git
|
||||||
|
path: packages/integration_test
|
||||||
|
pedantic: ^1.8.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||||
|
@ -53,6 +59,8 @@ flutter:
|
||||||
- assets/css/
|
- assets/css/
|
||||||
- assets/images/
|
- assets/images/
|
||||||
- assets/favicon.ico
|
- assets/favicon.ico
|
||||||
|
- assets/sample_audio.ogg
|
||||||
|
- assets/sample_video.mp4
|
||||||
- test_assets/certificate.pfx
|
- test_assets/certificate.pfx
|
||||||
- test_assets/in_app_webview_initial_file_test.html
|
- test_assets/in_app_webview_initial_file_test.html
|
||||||
- test_assets/in_app_webview_on_load_resource_test.html
|
- test_assets/in_app_webview_on_load_resource_test.html
|
||||||
|
@ -64,6 +72,8 @@ flutter:
|
||||||
- test_assets/css/
|
- test_assets/css/
|
||||||
- test_assets/images/
|
- test_assets/images/
|
||||||
- test_assets/favicon.ico
|
- test_assets/favicon.ico
|
||||||
|
- test_assets/sample_audio.ogg
|
||||||
|
- test_assets/sample_video.mp4
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
# assets:
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
final environment = {"NODE_SERVER_IP":"192.168.1.122"};
|
|
|
@ -1,11 +0,0 @@
|
||||||
import 'package:flutter_driver/driver_extension.dart';
|
|
||||||
import 'main_test.dart' as app;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// This line enables the extension.
|
|
||||||
enableFlutterDriverExtension();
|
|
||||||
|
|
||||||
// Call the `main()` function of the app, or call `runApp` with
|
|
||||||
// any widget you are interested in testing.
|
|
||||||
app.main();
|
|
||||||
}
|
|
|
@ -1,532 +0,0 @@
|
||||||
// Imports the Flutter Driver API.
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
group('Flutter InAppWebView', () {
|
|
||||||
FlutterDriver driver;
|
|
||||||
|
|
||||||
// Connect to the Flutter driver before running any tests.
|
|
||||||
setUpAll(() async {
|
|
||||||
driver = await FlutterDriver.connect();
|
|
||||||
await driver.setTextEntryEmulation(enabled: true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Close the connection to the driver after the tests have completed.
|
|
||||||
tearDownAll(() async {
|
|
||||||
if (driver != null) {
|
|
||||||
driver.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
test('InAppWebViewInitialUrlTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewInitialFileTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewInitialUrlTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = await driver.getText(appBarTitle);
|
|
||||||
expect(url, "https://flutter.dev/");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewInitialFileTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewInitialDataTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewInitialFileTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewInitialDataTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnProgressChangedTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewInitialDataTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnProgressChangedTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnScrollChangedTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnProgressChangedTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnScrollChangedTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnLoadResourceTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnScrollChangedTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnLoadResourceTest', () async {
|
|
||||||
List<String> resourceList = [
|
|
||||||
"https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css",
|
|
||||||
"https://code.jquery.com/jquery-3.3.1.min.js",
|
|
||||||
"https://via.placeholder.com/100x50"
|
|
||||||
];
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewJavaScriptHandlerTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnLoadResourceTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
for (String resource in resourceList) {
|
|
||||||
expect(true, title.contains(resource));
|
|
||||||
}
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewJavaScriptHandlerTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewAjaxTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewJavaScriptHandlerTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(true, !title.contains("false"));
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewAjaxTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewFetchTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewAjaxTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "Lorenzo Pichilli Lorenzo Pichilli");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewFetchTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnLoadResourceCustomSchemeTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewFetchTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(true, title.contains("Lorenzo Pichilli") && title.contains("200"));
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnLoadResourceCustomSchemeTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewShouldOverrideUrlLoadingTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnLoadResourceCustomSchemeTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewShouldOverrideUrlLoadingTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnConsoleMessageTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewShouldOverrideUrlLoadingTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = await driver.getText(appBarTitle);
|
|
||||||
expect(url, "https://flutter.dev/");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnConsoleMessageTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnDownloadStartTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnConsoleMessageTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "message LOG");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnDownloadStartTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnCreateWindowTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnDownloadStartTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = await driver.getText(appBarTitle);
|
|
||||||
expect(url, "http://${environment["NODE_SERVER_IP"]}:8082/test-download-file");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnCreateWindowTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnJsDialogTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnCreateWindowTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = await driver.getText(appBarTitle);
|
|
||||||
expect(url, "https://flutter.dev/");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnJsDialogTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
final alertButtonOk = find.byValueKey('AlertButtonOk');
|
|
||||||
final confirmButtonCancel = find.byValueKey('ConfirmButtonCancel');
|
|
||||||
final confirmButtonOk = find.byValueKey('ConfirmButtonOk');
|
|
||||||
final promptTextField = find.byValueKey('PromptTextField');
|
|
||||||
final promptButtonCancel = find.byValueKey('PromptButtonCancel');
|
|
||||||
final promptButtonOk = find.byValueKey('PromptButtonOk');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnSafeBrowsingHitTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnJsDialogTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
await driver.tap(alertButtonOk);
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "alert");
|
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
|
|
||||||
await driver.tap(confirmButtonOk);
|
|
||||||
|
|
||||||
title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "confirm true");
|
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
|
|
||||||
await driver.tap(promptTextField);
|
|
||||||
await driver.enterText("new value");
|
|
||||||
await driver.waitFor(find.text("new value"));
|
|
||||||
|
|
||||||
await driver.tap(promptButtonOk);
|
|
||||||
|
|
||||||
title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "prompt new value");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnSafeBrowsingHitTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnReceivedHttpAuthRequestTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnSafeBrowsingHitTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = await driver.getText(appBarTitle);
|
|
||||||
if (Platform.isAndroid)
|
|
||||||
expect(url, "chrome://safe-browsing/match?type=malware");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnReceivedHttpAuthRequestTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewSslRequestTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnReceivedHttpAuthRequestTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "Authorized");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewSslRequestTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnFindResultReceivedTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewSslRequestTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "Authorized");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnFindResultReceivedTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnNavigationStateChangeTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnFindResultReceivedTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "2");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnNavigationStateChangeTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnLoadErrorTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnNavigationStateChangeTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(true, title.contains("first-push") && title.contains("second-push"));
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnLoadErrorTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewOnLoadHttpErrorTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnLoadErrorTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
if (Platform.isAndroid) {
|
|
||||||
expect(title, "-2");
|
|
||||||
} else if (Platform.isIOS) {
|
|
||||||
expect(title, "-1022");
|
|
||||||
}
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewOnLoadHttpErrorTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewCookieManagerTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewOnLoadHttpErrorTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "404");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewCookieManagerTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewHttpAuthCredentialDatabaseTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewCookieManagerTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "myValue true true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewHttpAuthCredentialDatabaseTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
final sideMenuButton = find.byValueKey('SideMenu');
|
|
||||||
final listTiles = find.byValueKey('ListTiles');
|
|
||||||
final nextTest = find.byValueKey('InAppWebViewContentBlockerTest');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewHttpAuthCredentialDatabaseTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "Authorized true true");
|
|
||||||
|
|
||||||
await driver.tap(sideMenuButton);
|
|
||||||
await driver.scrollUntilVisible(listTiles, nextTest, dyScroll: -300.0);
|
|
||||||
await driver.tap(nextTest);
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
test('InAppWebViewContentBlockerTest', () async {
|
|
||||||
final appBarTitle = find.byValueKey('AppBarTitle');
|
|
||||||
|
|
||||||
while((await driver.getText(appBarTitle)) == "InAppWebViewContentBlockerTest") {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
String title = await driver.getText(appBarTitle);
|
|
||||||
expect(title, "true");
|
|
||||||
}, timeout: new Timeout(new Duration(minutes: 5)));
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
class WidgetTest extends StatefulWidget {
|
|
||||||
final WidgetTestState state = WidgetTestState();
|
|
||||||
|
|
||||||
WidgetTest({Key key}): super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
WidgetTestState createState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WidgetTestState extends State<WidgetTest> {
|
|
||||||
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
|
||||||
InAppWebViewController webView;
|
|
||||||
String appBarTitle;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewAjaxTest extends WidgetTest {
|
|
||||||
final InAppWebViewAjaxTestState state = InAppWebViewAjaxTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewAjaxTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewAjaxTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewAjaxTest";
|
|
||||||
int totTests = 2;
|
|
||||||
int testsDone = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewAjaxTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewAjaxTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
|
||||||
xhttp.send("firstname=Foo&lastname=Bar");
|
|
||||||
|
|
||||||
var xhttp2 = new XMLHttpRequest();
|
|
||||||
xhttp2.open("GET", "http://${environment["NODE_SERVER_IP"]}:8082/test-download-file");
|
|
||||||
xhttp2.send();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
useShouldInterceptAjaxRequest: true,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
shouldInterceptAjaxRequest: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
|
||||||
if (ajaxRequest.url.endsWith("/test-ajax-post")) {
|
|
||||||
ajaxRequest.responseType = 'json';
|
|
||||||
ajaxRequest.data = "firstname=Lorenzo&lastname=Pichilli";
|
|
||||||
}
|
|
||||||
return ajaxRequest;
|
|
||||||
},
|
|
||||||
onAjaxReadyStateChange: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
|
||||||
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE && ajaxRequest.status == 200 && ajaxRequest.url.endsWith("/test-ajax-post")) {
|
|
||||||
Map<String, Object> res = ajaxRequest.response;
|
|
||||||
appBarTitle = (appBarTitle == "InAppWebViewAjaxTest") ? res['fullname'] : appBarTitle + " " + res['fullname'];
|
|
||||||
updateCountTest(context: context);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
onAjaxProgress: (InAppWebViewController controller, AjaxRequest ajaxRequest) async {
|
|
||||||
if (ajaxRequest.event.type == AjaxRequestEventType.LOAD && ajaxRequest.url.endsWith("/test-ajax-post")) {
|
|
||||||
Map<String, Object> res = ajaxRequest.response;
|
|
||||||
appBarTitle = (appBarTitle == "InAppWebViewAjaxTest") ? res['fullname'] : appBarTitle + " " + res['fullname'];
|
|
||||||
updateCountTest(context: context);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateCountTest({@required BuildContext context}) {
|
|
||||||
testsDone++;
|
|
||||||
if (testsDone == totTests) {
|
|
||||||
setState(() { });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewContentBlockerTest extends WidgetTest {
|
|
||||||
final InAppWebViewContentBlockerTestState state = InAppWebViewContentBlockerTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewContentBlockerTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewContentBlockerTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewContentBlockerTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
contentBlockers: [
|
|
||||||
ContentBlocker(
|
|
||||||
trigger: ContentBlockerTrigger(
|
|
||||||
urlFilter: ".*",
|
|
||||||
resourceType: [
|
|
||||||
ContentBlockerTriggerResourceType.IMAGE,
|
|
||||||
ContentBlockerTriggerResourceType.STYLE_SHEET
|
|
||||||
],
|
|
||||||
ifTopUrl: [
|
|
||||||
"https://flutter.dev/"
|
|
||||||
]),
|
|
||||||
action: ContentBlockerAction(
|
|
||||||
type: ContentBlockerActionType.BLOCK))
|
|
||||||
]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewCookieManagerTest extends WidgetTest {
|
|
||||||
final InAppWebViewCookieManagerTestState state = InAppWebViewCookieManagerTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewCookieManagerTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewCookieManagerTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewCookieManagerTest";
|
|
||||||
CookieManager cookieManager = CookieManager.instance();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
|
||||||
var title = "";
|
|
||||||
await cookieManager.getCookies(url: url);
|
|
||||||
await cookieManager.setCookie(url: url, name: "myCookie", value: "myValue");
|
|
||||||
Cookie cookie = await cookieManager.getCookie(url: url, name: "myCookie");
|
|
||||||
title = cookie.value.toString();
|
|
||||||
await cookieManager.deleteCookie(url: url, name: "myCookie");
|
|
||||||
cookie = await cookieManager.getCookie(url: url, name: "myCookie");
|
|
||||||
title += " " + ((cookie == null) ? "true" : "false");
|
|
||||||
await cookieManager.deleteCookies(url: url);
|
|
||||||
List<Cookie> cookies = await cookieManager.getCookies(url: url);
|
|
||||||
title += " " + ((cookies.length == 0) ? "true" : "false");
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = title;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewFetchTest extends WidgetTest {
|
|
||||||
final InAppWebViewFetchTestState state = InAppWebViewFetchTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewFetchTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewFetchTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewFetchTest";
|
|
||||||
int totTests = 2;
|
|
||||||
int testsDone = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewFetchTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewFetchTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
fetch(new Request("http://${environment["NODE_SERVER_IP"]}:8082/test-download-file")).then(function(response) {
|
|
||||||
window.flutter_inappwebview.callHandler('fetchGet', response.status);
|
|
||||||
}).catch(function(error) {
|
|
||||||
window.flutter_inappwebview.callHandler('fetchGet', "ERROR: " + error);
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch("http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post", {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
firstname: 'Foo',
|
|
||||||
lastname: 'Bar'
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}).then(function(response) {
|
|
||||||
response.json().then(function(value) {
|
|
||||||
window.flutter_inappwebview.callHandler('fetchPost', value);
|
|
||||||
}).catch(function(error) {
|
|
||||||
window.flutter_inappwebview.callHandler('fetchPost', "ERROR: " + error);
|
|
||||||
});
|
|
||||||
}).catch(function(error) {
|
|
||||||
window.flutter_inappwebview.callHandler('fetchPost', "ERROR: " + error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
useShouldInterceptFetchRequest: true,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
|
|
||||||
webView.addJavaScriptHandler(handlerName: "fetchGet", callback: (args) {
|
|
||||||
appBarTitle = (appBarTitle == "InAppWebViewFetchTest") ? args[0].toString() : appBarTitle + " " + args[0].toString();
|
|
||||||
updateCountTest(context: context);
|
|
||||||
});
|
|
||||||
|
|
||||||
webView.addJavaScriptHandler(handlerName: "fetchPost", callback: (args) {
|
|
||||||
appBarTitle = (appBarTitle == "InAppWebViewFetchTest") ? args[0]["fullname"] : appBarTitle + " " + args[0]["fullname"];
|
|
||||||
updateCountTest(context: context);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
shouldInterceptFetchRequest: (InAppWebViewController controller, FetchRequest fetchRequest) async {
|
|
||||||
if (fetchRequest.url.endsWith("/test-ajax-post")) {
|
|
||||||
fetchRequest.body = utf8.encode("""{
|
|
||||||
"firstname": "Lorenzo",
|
|
||||||
"lastname": "Pichilli"
|
|
||||||
}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
return fetchRequest;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateCountTest({@required BuildContext context}) {
|
|
||||||
testsDone++;
|
|
||||||
if (testsDone == totTests) {
|
|
||||||
setState(() { });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewHttpAuthCredentialDatabaseTest extends WidgetTest {
|
|
||||||
final InAppWebViewHttpAuthCredentialDatabaseTestState state = InAppWebViewHttpAuthCredentialDatabaseTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewHttpAuthCredentialDatabaseTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewHttpAuthCredentialDatabaseTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewHttpAuthCredentialDatabaseTest";
|
|
||||||
HttpAuthCredentialDatabase httpAuthCredentialDatabase = HttpAuthCredentialDatabase.instance();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
|
|
||||||
httpAuthCredentialDatabase.setHttpAuthCredential(
|
|
||||||
protectionSpace: ProtectionSpace(host: environment["NODE_SERVER_IP"], protocol: "http", realm: "Node", port: 8081),
|
|
||||||
credential: HttpAuthCredential(username: "USERNAME", password: "PASSWORD")
|
|
||||||
);
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "http://${environment["NODE_SERVER_IP"]}:8081/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
|
||||||
var title = "";
|
|
||||||
String h1Content = await controller.evaluateJavascript(source: "document.body.querySelector('h1').textContent");
|
|
||||||
title = h1Content;
|
|
||||||
var credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials(protectionSpace:
|
|
||||||
ProtectionSpace(host: environment["NODE_SERVER_IP"], protocol: "http", realm: "Node", port: 8081)
|
|
||||||
);
|
|
||||||
title += " " + ((credentials.length == 1) ? "true" : "false");
|
|
||||||
await httpAuthCredentialDatabase.clearAllAuthCredentials();
|
|
||||||
credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials(protectionSpace:
|
|
||||||
ProtectionSpace(host: environment["NODE_SERVER_IP"], protocol: "http", realm: "Node", port: 8081)
|
|
||||||
);
|
|
||||||
title += " " + ((credentials.length == 0) ? "true" : "false");
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = title;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onReceivedHttpAuthRequest: (InAppWebViewController controller, HttpAuthChallenge challenge) async {
|
|
||||||
return new HttpAuthResponse(action: HttpAuthResponseAction.USE_SAVED_HTTP_AUTH_CREDENTIALS);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewInitialDataTest extends WidgetTest {
|
|
||||||
final InAppWebViewInitialDataTestState state = InAppWebViewInitialDataTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewInitialDataTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewInitialDataTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewInitialDataTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewInitialDataTest</title>
|
|
||||||
<link rel="stylesheet" href="https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="css/style.css">
|
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
|
||||||
<link rel="shortcut icon" href="favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body class="text-center">
|
|
||||||
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
|
|
||||||
<header class="masthead mb-auto">
|
|
||||||
<div class="inner">
|
|
||||||
<h3 class="masthead-brand">InAppWebViewInitialDataTest</h3>
|
|
||||||
<nav class="nav nav-masthead justify-content-center">
|
|
||||||
<a class="nav-link active" href="index.html">Home</a>
|
|
||||||
<a class="nav-link" href="page-1.html">Page 1</a>
|
|
||||||
<a class="nav-link" href="page-2.html">Page 2</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main role="main" class="inner cover">
|
|
||||||
<h1 class="cover-heading">InAppWebViewInitialFileTest</h1>
|
|
||||||
<img src="images/flutter-logo.svg" alt="flutter logo">
|
|
||||||
<p>
|
|
||||||
<img src="https://via.placeholder.com/100x50" alt="placeholder 100x50">
|
|
||||||
</p>
|
|
||||||
<a id="link" href="https://github.com/pichillilorenzo/flutter_inappwebview">flutter_inappwebview</a>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewInitialFileTest extends WidgetTest {
|
|
||||||
final InAppWebViewInitialFileTestState state = InAppWebViewInitialFileTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewInitialFileTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewInitialFileTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewInitialFileTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_initial_file_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewInitialUrlTest extends WidgetTest {
|
|
||||||
final InAppWebViewInitialUrlTestState state = InAppWebViewInitialUrlTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewInitialUrlTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewInitialUrlTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewInitialUrlTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = url;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
String bar;
|
|
||||||
String baz;
|
|
||||||
|
|
||||||
Foo({this.bar, this.baz});
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'bar': this.bar,
|
|
||||||
'baz': this.baz
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewJavaScriptHandlerTest extends WidgetTest {
|
|
||||||
final InAppWebViewJavaScriptHandlerTestState state = InAppWebViewJavaScriptHandlerTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewJavaScriptHandlerTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewJavaScriptHandlerTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewJavaScriptHandlerTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_javascript_handler_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
|
|
||||||
controller.addJavaScriptHandler(handlerName:'handlerFoo', callback: (args) {
|
|
||||||
appBarTitle = (args.length == 0).toString();
|
|
||||||
return Foo(bar: 'bar_value', baz: 'baz_value');
|
|
||||||
});
|
|
||||||
|
|
||||||
controller.addJavaScriptHandler(handlerName: 'handlerFooWithArgs', callback: (args) {
|
|
||||||
appBarTitle += " " + (args[0] is int).toString();
|
|
||||||
appBarTitle += " " + (args[1] is bool).toString();
|
|
||||||
appBarTitle += " " + (args[2] is List).toString();
|
|
||||||
appBarTitle += " " + (args[2] is List).toString();
|
|
||||||
appBarTitle += " " + (args[3] is Map).toString();
|
|
||||||
appBarTitle += " " + (args[4] is Map).toString();
|
|
||||||
setState(() { });
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnConsoleMessageTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnConsoleMessageTestState state = InAppWebViewOnConsoleMessageTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnConsoleMessageTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnConsoleMessageTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnConsoleMessageTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_on_console_message_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = consoleMessage.message + " " + consoleMessage.messageLevel.toString();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnCreateWindowTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnCreateWindowTestState state = InAppWebViewOnCreateWindowTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnCreateWindowTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnCreateWindowTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnCreateWindowTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_on_create_window_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
if (url == "https://flutter.dev/") {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = url;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCreateWindow: (InAppWebViewController controller, CreateWindowRequest createWindowRequest) async {
|
|
||||||
controller.loadUrl(url: createWindowRequest.url);
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnDownloadStartTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnDownloadStartTestState state = InAppWebViewOnDownloadStartTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnDownloadStartTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnDownloadStartTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnDownloadStartTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewOnDownloadStartTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewOnDownloadStartTest</h1>
|
|
||||||
<a id="download-file" href="http://${environment["NODE_SERVER_IP"]}:8082/test-download-file">download file</a>
|
|
||||||
<script>
|
|
||||||
window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
|
|
||||||
document.querySelector("#download-file").click();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
useOnDownloadStart: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onDownloadStart: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = url;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnFindResultReceivedTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnFindResultReceivedTestState state = InAppWebViewOnFindResultReceivedTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnFindResultReceivedTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnFindResultReceivedTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnFindResultReceivedTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_initial_file_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
controller.findAllAsync(find: "InAppWebViewInitialFileTest");
|
|
||||||
},
|
|
||||||
onFindResultReceived: (InAppWebViewController controller, int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting) async {
|
|
||||||
if (isDoneCounting) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = numberOfMatches.toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnJsDialogTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnJsDialogTestState state = InAppWebViewOnJsDialogTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnJsDialogTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnJsDialogTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnJsDialogTest";
|
|
||||||
|
|
||||||
TextEditingController _textFieldController = TextEditingController();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
_textFieldController.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_on_js_dialog_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
|
|
||||||
controller.addJavaScriptHandler(handlerName: 'confirm', callback: (args) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "confirm " + ((args[0] is bool && args[0]) ? "true" : "false");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
controller.addJavaScriptHandler(handlerName: 'prompt', callback: (args) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "prompt " + args[0];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "loaded";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onJsAlert:
|
|
||||||
(InAppWebViewController controller, JsAlertRequest jsAlertRequest) async {
|
|
||||||
JsAlertResponseAction action =
|
|
||||||
await createAlertDialog(context, jsAlertRequest.message);
|
|
||||||
return JsAlertResponse(
|
|
||||||
handledByClient: true, action: action);
|
|
||||||
},
|
|
||||||
onJsConfirm:
|
|
||||||
(InAppWebViewController controller, JsConfirmRequest jsConfirmRequest) async {
|
|
||||||
JsConfirmResponseAction action =
|
|
||||||
await createConfirmDialog(context, jsConfirmRequest.message);
|
|
||||||
return JsConfirmResponse(
|
|
||||||
handledByClient: true, action: action);
|
|
||||||
},
|
|
||||||
onJsPrompt: (InAppWebViewController controller, JsPromptRequest jsPromptRequest) async {
|
|
||||||
_textFieldController.text = jsPromptRequest.defaultValue;
|
|
||||||
JsPromptResponseAction action =
|
|
||||||
await createPromptDialog(context, jsPromptRequest.message);
|
|
||||||
return JsPromptResponse(
|
|
||||||
handledByClient: true,
|
|
||||||
action: action,
|
|
||||||
value: _textFieldController.text);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<JsAlertResponseAction> createAlertDialog(
|
|
||||||
BuildContext context, String message) async {
|
|
||||||
JsAlertResponseAction action;
|
|
||||||
|
|
||||||
await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
content: Text(message),
|
|
||||||
actions: <Widget>[
|
|
||||||
FlatButton(
|
|
||||||
child: Text("Ok"),
|
|
||||||
key: Key("AlertButtonOk"),
|
|
||||||
onPressed: () {
|
|
||||||
action = JsAlertResponseAction.CONFIRM;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "alert";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<JsConfirmResponseAction> createConfirmDialog(
|
|
||||||
BuildContext context, String message) async {
|
|
||||||
JsConfirmResponseAction action;
|
|
||||||
|
|
||||||
await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
content: Text(message),
|
|
||||||
actions: <Widget>[
|
|
||||||
FlatButton(
|
|
||||||
child: Text("Cancel"),
|
|
||||||
key: Key("ConfirmButtonCancel"),
|
|
||||||
onPressed: () {
|
|
||||||
action = JsConfirmResponseAction.CANCEL;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FlatButton(
|
|
||||||
child: Text("Ok"),
|
|
||||||
key: Key("ConfirmButtonOk"),
|
|
||||||
onPressed: () {
|
|
||||||
action = JsConfirmResponseAction.CONFIRM;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<JsPromptResponseAction> createPromptDialog(
|
|
||||||
BuildContext context, String message) async {
|
|
||||||
JsPromptResponseAction action;
|
|
||||||
|
|
||||||
await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: Text(message),
|
|
||||||
content: TextField(
|
|
||||||
key: Key("PromptTextField"),
|
|
||||||
controller: _textFieldController,
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
FlatButton(
|
|
||||||
child: Text("Cancel"),
|
|
||||||
key: Key("PromptButtonCancel"),
|
|
||||||
onPressed: () {
|
|
||||||
action = JsPromptResponseAction.CANCEL;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FlatButton(
|
|
||||||
child: Text("Ok"),
|
|
||||||
key: Key("PromptButtonOk"),
|
|
||||||
onPressed: () {
|
|
||||||
action = JsPromptResponseAction.CONFIRM;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadErrorTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnLoadErrorTestState state = InAppWebViewOnLoadErrorTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnLoadErrorTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadErrorTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnLoadErrorTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://not-existing-domain.org/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadError: (InAppWebViewController controller, String url, int code, String message) async {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = code.toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadHttpErrorTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnLoadHttpErrorTestState state = InAppWebViewOnLoadHttpErrorTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnLoadHttpErrorTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadHttpErrorTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnLoadHttpErrorTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://google.com/404",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadHttpError: (InAppWebViewController controller, String url, int statusCode, String description) async {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = statusCode.toString();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadResourceCustomSchemeTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnLoadResourceCustomSchemeTestState state = InAppWebViewOnLoadResourceCustomSchemeTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnLoadResourceCustomSchemeTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadResourceCustomSchemeTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnLoadResourceCustomSchemeTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_on_load_resource_custom_scheme_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
resourceCustomSchemes: ["my-special-custom-scheme"]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
|
|
||||||
webView.addJavaScriptHandler(handlerName: "imageLoaded", callback: (args) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadResourceCustomScheme: (InAppWebViewController controller, String scheme, String url) async {
|
|
||||||
if (scheme == "my-special-custom-scheme") {
|
|
||||||
var bytes = await rootBundle.load("test_assets/" + url.replaceFirst("my-special-custom-scheme://", "", 0));
|
|
||||||
var response = CustomSchemeResponse(data: bytes.buffer.asUint8List(), contentType: "image/svg+xml", contentEnconding: "utf-8");
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadResourceTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnLoadResourceTestState state = InAppWebViewOnLoadResourceTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnLoadResourceTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnLoadResourceTestState extends WidgetTestState {
|
|
||||||
List<String> resourceList = [
|
|
||||||
"https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css",
|
|
||||||
"https://code.jquery.com/jquery-3.3.1.min.js",
|
|
||||||
"https://via.placeholder.com/100x50"
|
|
||||||
];
|
|
||||||
int countResources = 0;
|
|
||||||
String appBarTitle = "InAppWebViewOnLoadResourceTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_on_load_resource_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
useOnLoadResource: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadResource: (InAppWebViewController controller, LoadedResource response) {
|
|
||||||
appBarTitle = (appBarTitle == "InAppWebViewOnLoadResourceTest") ? response.url : appBarTitle + " " + response.url;
|
|
||||||
countResources++;
|
|
||||||
if (countResources == resourceList.length) {
|
|
||||||
setState(() { });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'main_test.dart';
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnNavigationStateChangeTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnNavigationStateChangeTestState state = InAppWebViewOnNavigationStateChangeTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnNavigationStateChangeTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnNavigationStateChangeTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewOnNavigationStateChangeTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
controller.evaluateJavascript(source: """
|
|
||||||
var state = {}
|
|
||||||
var title = ''
|
|
||||||
var url = 'first-push';
|
|
||||||
history.pushState(state, title, url);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
var url = 'second-push';
|
|
||||||
history.pushState(state, title, url);
|
|
||||||
}, 100);
|
|
||||||
""");
|
|
||||||
},
|
|
||||||
onUpdateVisitedHistory: (InAppWebViewController controller, String url, bool androidIsReload) async {
|
|
||||||
if (url.endsWith("second-push")) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle += " " + url;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
appBarTitle = url;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnProgressChangedTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnProgressChangedTestState state = InAppWebViewOnProgressChangedTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnProgressChangedTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnProgressChangedTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnProgressChangedTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
|
||||||
if (progress == 100) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnReceivedHttpAuthRequestTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnReceivedHttpAuthRequestTestState state = InAppWebViewOnReceivedHttpAuthRequestTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnReceivedHttpAuthRequestTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnReceivedHttpAuthRequestTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnReceivedHttpAuthRequestTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "http://${environment["NODE_SERVER_IP"]}:8081/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
|
||||||
String h1Content = await controller.evaluateJavascript(source: "document.body.querySelector('h1').textContent");
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = h1Content;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onReceivedHttpAuthRequest: (InAppWebViewController controller, HttpAuthChallenge challenge) async {
|
|
||||||
return new HttpAuthResponse(
|
|
||||||
username: "USERNAME",
|
|
||||||
password: "PASSWORD",
|
|
||||||
action: HttpAuthResponseAction.PROCEED,
|
|
||||||
permanentPersistence: true);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnSafeBrowsingHitTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnSafeBrowsingHitTestState state = InAppWebViewOnSafeBrowsingHitTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnSafeBrowsingHitTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnSafeBrowsingHitTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnSafeBrowsingHitTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: (Platform.isAndroid) ? "chrome://safe-browsing/match?type=malware" : "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
// if I set javaScriptEnabled to true, it will crash!
|
|
||||||
javaScriptEnabled: false,
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
),
|
|
||||||
android: AndroidInAppWebViewOptions(
|
|
||||||
safeBrowsingEnabled: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
if(Platform.isAndroid)
|
|
||||||
controller.android.startSafeBrowsing();
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = url;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
androidOnSafeBrowsingHit: (InAppWebViewController controller, String url, SafeBrowsingThreat threatType) async {
|
|
||||||
return SafeBrowsingResponse(report: true, action: SafeBrowsingResponseAction.PROCEED);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewOnScrollChangedTest extends WidgetTest {
|
|
||||||
final InAppWebViewOnScrollChangedTestState state = InAppWebViewOnScrollChangedTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewOnScrollChangedTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewOnScrollChangedTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewOnScrollChangedTest";
|
|
||||||
bool scrolled = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://flutter.dev/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
controller.scrollTo(x: 0, y: 500);
|
|
||||||
},
|
|
||||||
onScrollChanged: (InAppWebViewController controller, int x, int y) {
|
|
||||||
if (!scrolled) {
|
|
||||||
scrolled = true;
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = "true";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:io' show Platform;
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
|
|
||||||
class InAppWebViewShouldOverrideUrlLoadingTest extends WidgetTest {
|
|
||||||
final InAppWebViewShouldOverrideUrlLoadingTestState state = InAppWebViewShouldOverrideUrlLoadingTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewShouldOverrideUrlLoadingTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewShouldOverrideUrlLoadingTestState extends WidgetTestState {
|
|
||||||
String appBarTitle = "InAppWebViewShouldOverrideUrlLoadingTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialFile: "test_assets/in_app_webview_initial_file_test.html",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true,
|
|
||||||
useShouldOverrideUrlLoading: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) {
|
|
||||||
if (url == "https://flutter.dev/") {
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = url;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
controller.evaluateJavascript(source: "document.querySelector('#link').click();");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
shouldOverrideUrlLoading: (InAppWebViewController controller, ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
|
||||||
if (Platform.isAndroid || shouldOverrideUrlLoadingRequest.iosWKNavigationType == IOSWKNavigationType.LINK_ACTIVATED) {
|
|
||||||
await controller.loadUrl(url: "https://flutter.dev/");
|
|
||||||
return ShouldOverrideUrlLoadingAction.CANCEL;
|
|
||||||
}
|
|
||||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'main_test.dart';
|
|
||||||
import '.env.dart';
|
|
||||||
|
|
||||||
class InAppWebViewSslRequestTest extends WidgetTest {
|
|
||||||
final InAppWebViewSslRequestTestState state = InAppWebViewSslRequestTestState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
InAppWebViewSslRequestTestState createState() => state;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InAppWebViewSslRequestTestState extends WidgetTestState {
|
|
||||||
|
|
||||||
String appBarTitle = "InAppWebViewSslRequestTest";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
key: this.scaffoldKey,
|
|
||||||
appBar: myAppBar(state: this, title: appBarTitle),
|
|
||||||
drawer: myDrawer(context: context),
|
|
||||||
body: Container(
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: InAppWebView(
|
|
||||||
initialUrl: "https://${environment["NODE_SERVER_IP"]}:4433/",
|
|
||||||
initialHeaders: {},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
debuggingEnabled: true
|
|
||||||
)
|
|
||||||
),
|
|
||||||
onWebViewCreated: (InAppWebViewController controller) {
|
|
||||||
webView = controller;
|
|
||||||
},
|
|
||||||
onLoadStart: (InAppWebViewController controller, String url) {
|
|
||||||
|
|
||||||
},
|
|
||||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
|
||||||
String h1Content = await controller.evaluateJavascript(source: "document.body.querySelector('h1').textContent");
|
|
||||||
setState(() {
|
|
||||||
appBarTitle = h1Content;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onReceivedServerTrustAuthRequest: (InAppWebViewController controller, ServerTrustChallenge challenge) async {
|
|
||||||
return new ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED);
|
|
||||||
},
|
|
||||||
onReceivedClientCertRequest: (InAppWebViewController controller, ClientCertChallenge challenge) async {
|
|
||||||
return new ClientCertResponse(
|
|
||||||
certificatePath: "test_assets/certificate.pfx",
|
|
||||||
certificatePassword: "",
|
|
||||||
androidKeyStoreType: "PKCS12",
|
|
||||||
action: ClientCertResponseAction.PROCEED);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// @dart = 2.9
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
final FlutterDriver driver = await FlutterDriver.connect();
|
||||||
|
final String data =
|
||||||
|
await driver.requestData(null, timeout: const Duration(minutes: 1));
|
||||||
|
await driver.close();
|
||||||
|
final Map<String, dynamic> result = jsonDecode(data);
|
||||||
|
exit(result['result'] == 'true' ? 0 : 1);
|
||||||
|
}
|
|
@ -1,153 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'custom_widget_test.dart';
|
|
||||||
import 'in_app_webview_ajax_test.dart';
|
|
||||||
import 'in_app_webview_content_blocker_test.dart';
|
|
||||||
import 'in_app_webview_cookie_manager_test.dart';
|
|
||||||
import 'in_app_webview_fetch_test.dart';
|
|
||||||
import 'in_app_webview_http_auth_credential_database_test.dart';
|
|
||||||
import 'in_app_webview_initial_data_test.dart';
|
|
||||||
import 'in_app_webview_initial_file_test.dart';
|
|
||||||
import 'in_app_webview_initial_url_test.dart';
|
|
||||||
import 'in_app_webview_javascript_handler_test.dart';
|
|
||||||
import 'in_app_webview_on_console_message_test.dart';
|
|
||||||
import 'in_app_webview_on_download_start_test.dart';
|
|
||||||
import 'in_app_webview_on_find_result_received_test.dart';
|
|
||||||
import 'in_app_webview_on_js_dialog_test.dart';
|
|
||||||
import 'in_app_webview_on_load_error_test.dart';
|
|
||||||
import 'in_app_webview_on_load_http_error_test.dart';
|
|
||||||
import 'in_app_webview_on_load_resource_custom_scheme_test.dart';
|
|
||||||
import 'in_app_webview_on_load_resource_test.dart';
|
|
||||||
import 'in_app_webview_on_navigation_state_change_test.dart';
|
|
||||||
import 'in_app_webview_on_progress_changed_test.dart';
|
|
||||||
import 'in_app_webview_on_received_http_auth_request_test.dart';
|
|
||||||
import 'in_app_webview_on_safe_browsing_hit_test.dart';
|
|
||||||
import 'in_app_webview_on_scroll_changed_test.dart';
|
|
||||||
import 'in_app_webview_on_create_window_test.dart';
|
|
||||||
import 'in_app_webview_should_override_url_loading_test.dart';
|
|
||||||
import 'in_app_webview_ssl_request_test.dart';
|
|
||||||
|
|
||||||
Map<String, WidgetBuilder> getTestRoutes({@required BuildContext context}) {
|
|
||||||
var routes = {
|
|
||||||
'/': (context) => InAppWebViewInitialUrlTest(),
|
|
||||||
'/InAppWebViewInitialFileTest': (context) => InAppWebViewInitialFileTest(),
|
|
||||||
'/InAppWebViewInitialDataTest': (context) => InAppWebViewInitialDataTest(),
|
|
||||||
'/InAppWebViewOnProgressChangedTest': (context) => InAppWebViewOnProgressChangedTest(),
|
|
||||||
'/InAppWebViewOnScrollChangedTest': (context) => InAppWebViewOnScrollChangedTest(),
|
|
||||||
'/InAppWebViewOnLoadResourceTest': (context) => InAppWebViewOnLoadResourceTest(),
|
|
||||||
'/InAppWebViewJavaScriptHandlerTest': (context) => InAppWebViewJavaScriptHandlerTest(),
|
|
||||||
'/InAppWebViewAjaxTest': (context) => InAppWebViewAjaxTest(),
|
|
||||||
'/InAppWebViewFetchTest': (context) => InAppWebViewFetchTest(),
|
|
||||||
'/InAppWebViewOnLoadResourceCustomSchemeTest': (context) => InAppWebViewOnLoadResourceCustomSchemeTest(),
|
|
||||||
'/InAppWebViewShouldOverrideUrlLoadingTest': (context) => InAppWebViewShouldOverrideUrlLoadingTest(),
|
|
||||||
'/InAppWebViewOnConsoleMessageTest': (context) => InAppWebViewOnConsoleMessageTest(),
|
|
||||||
'/InAppWebViewOnDownloadStartTest': (context) => InAppWebViewOnDownloadStartTest(),
|
|
||||||
'/InAppWebViewOnCreateWindowTest': (context) => InAppWebViewOnCreateWindowTest(),
|
|
||||||
'/InAppWebViewOnJsDialogTest': (context) => InAppWebViewOnJsDialogTest(),
|
|
||||||
'/InAppWebViewOnSafeBrowsingHitTest': (context) => InAppWebViewOnSafeBrowsingHitTest(),
|
|
||||||
'/InAppWebViewOnReceivedHttpAuthRequestTest': (context) => InAppWebViewOnReceivedHttpAuthRequestTest(),
|
|
||||||
'/InAppWebViewSslRequestTest': (context) => InAppWebViewSslRequestTest(),
|
|
||||||
'/InAppWebViewOnFindResultReceivedTest': (context) => InAppWebViewOnFindResultReceivedTest(),
|
|
||||||
'/InAppWebViewOnNavigationStateChangeTest': (context) => InAppWebViewOnNavigationStateChangeTest(),
|
|
||||||
'/InAppWebViewOnLoadErrorTest': (context) => InAppWebViewOnLoadErrorTest(),
|
|
||||||
'/InAppWebViewOnLoadHttpErrorTest': (context) => InAppWebViewOnLoadHttpErrorTest(),
|
|
||||||
'/InAppWebViewCookieManagerTest': (context) => InAppWebViewCookieManagerTest(),
|
|
||||||
'/InAppWebViewHttpAuthCredentialDatabaseTest': (context) => InAppWebViewHttpAuthCredentialDatabaseTest(),
|
|
||||||
'/InAppWebViewContentBlockerTest': (context) => InAppWebViewContentBlockerTest(),
|
|
||||||
};
|
|
||||||
return routes;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppBar myAppBar({@required WidgetTestState state, @required String title}) {
|
|
||||||
|
|
||||||
return AppBar(
|
|
||||||
title: Text(
|
|
||||||
title,
|
|
||||||
key: Key("AppBarTitle")
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.menu),
|
|
||||||
key: Key("SideMenu"),
|
|
||||||
onPressed: () {
|
|
||||||
state.scaffoldKey.currentState.openDrawer();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.refresh),
|
|
||||||
onPressed: () {
|
|
||||||
if (state.webView != null)
|
|
||||||
state.webView.reload();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawer myDrawer({@required context}) {
|
|
||||||
var routes = getTestRoutes(context: context);
|
|
||||||
List<Widget> listTiles = [
|
|
||||||
DrawerHeader(
|
|
||||||
child: Text('Tests'),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.blue,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
];
|
|
||||||
for (String k in routes.keys) {
|
|
||||||
var title = "";
|
|
||||||
if (k == "/") {
|
|
||||||
title = "InAppWebViewInitialUrlTest";
|
|
||||||
} else {
|
|
||||||
title = k.substring(1);
|
|
||||||
}
|
|
||||||
listTiles.add(ListTile(
|
|
||||||
title: Text(title),
|
|
||||||
key: Key(title),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pushReplacementNamed(context, k);
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return Drawer(
|
|
||||||
child: ListView(
|
|
||||||
key: Key("ListTiles"),
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
children: listTiles,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future main() async {
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
|
||||||
runApp(new MyApp());
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_MyAppState createState() => new _MyAppState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MaterialApp(
|
|
||||||
title: 'flutter_inappbrowser tests',
|
|
||||||
initialRoute: '/',
|
|
||||||
routes: getTestRoutes(context: context)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,6 +14,12 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/build" />
|
||||||
|
@ -27,6 +33,33 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/example/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/integration_test_macos/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/integration_test_macos/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/integration_test/integration_test_macos/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/path_provider/example/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/permission_handler/example/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/url_launcher/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
|
||||||
|
|
|
@ -1153,7 +1153,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
scrollView.maximumZoomScale = CGFloat(options.maximumZoomScale)
|
scrollView.maximumZoomScale = CGFloat(options.maximumZoomScale)
|
||||||
scrollView.minimumZoomScale = CGFloat(options.minimumZoomScale)
|
scrollView.minimumZoomScale = CGFloat(options.minimumZoomScale)
|
||||||
|
|
||||||
// options.debuggingEnabled is always enabled for iOS,
|
// debugging is always enabled for iOS,
|
||||||
// there isn't any option to set about it such as on Android.
|
// there isn't any option to set about it such as on Android.
|
||||||
|
|
||||||
if options.clearCache {
|
if options.clearCache {
|
||||||
|
@ -2498,6 +2498,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
if !handledByClient, InAppWebView.windowWebViews[windowId] != nil {
|
if !handledByClient, InAppWebView.windowWebViews[windowId] != nil {
|
||||||
InAppWebView.windowWebViews.removeValue(forKey: windowId)
|
InAppWebView.windowWebViews.removeValue(forKey: windowId)
|
||||||
|
if let url = navigationAction.request.url {
|
||||||
|
self.loadUrl(url: url, headers: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,6 @@ public class InAppWebViewOptions: Options<InAppWebView> {
|
||||||
var userAgent = ""
|
var userAgent = ""
|
||||||
var applicationNameForUserAgent = ""
|
var applicationNameForUserAgent = ""
|
||||||
var javaScriptEnabled = true
|
var javaScriptEnabled = true
|
||||||
var debuggingEnabled = true
|
|
||||||
var javaScriptCanOpenWindowsAutomatically = false
|
var javaScriptCanOpenWindowsAutomatically = false
|
||||||
var mediaPlaybackRequiresUserGesture = true
|
var mediaPlaybackRequiresUserGesture = true
|
||||||
var verticalScrollBarEnabled = true
|
var verticalScrollBarEnabled = true
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'asn1_identifier.dart';
|
import 'asn1_identifier.dart';
|
||||||
import 'asn1_object.dart';
|
import 'asn1_object.dart';
|
||||||
|
|
||||||
class ASN1DERDecoder {
|
class ASN1DERDecoder {
|
||||||
static List<ASN1Object> decode({@required List<int> data}) {
|
static List<ASN1Object> decode({required List<int> data}) {
|
||||||
var iterator = data.iterator;
|
var iterator = data.iterator;
|
||||||
return parse(iterator: iterator);
|
return parse(iterator: iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<ASN1Object> parse({@required Iterator<int> iterator}) {
|
static List<ASN1Object> parse({required Iterator<int> iterator}) {
|
||||||
var result = <ASN1Object>[];
|
var result = <ASN1Object>[];
|
||||||
|
|
||||||
while (iterator.moveNext()) {
|
while (iterator.moveNext()) {
|
||||||
|
@ -20,7 +19,7 @@ class ASN1DERDecoder {
|
||||||
var asn1obj = ASN1Object();
|
var asn1obj = ASN1Object();
|
||||||
asn1obj.identifier = ASN1Identifier(nextValue);
|
asn1obj.identifier = ASN1Identifier(nextValue);
|
||||||
|
|
||||||
if (asn1obj.identifier.isConstructed()) {
|
if (asn1obj.identifier!.isConstructed()) {
|
||||||
var contentData = loadSubContent(iterator: iterator);
|
var contentData = loadSubContent(iterator: iterator);
|
||||||
|
|
||||||
if (contentData.isEmpty) {
|
if (contentData.isEmpty) {
|
||||||
|
@ -34,18 +33,20 @@ class ASN1DERDecoder {
|
||||||
|
|
||||||
asn1obj.encoded = Uint8List.fromList(contentData);
|
asn1obj.encoded = Uint8List.fromList(contentData);
|
||||||
|
|
||||||
for (var item in asn1obj.sub) {
|
if (asn1obj.sub != null) {
|
||||||
|
for (var item in asn1obj.sub!) {
|
||||||
item.parent = asn1obj;
|
item.parent = asn1obj;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (asn1obj.identifier.typeClass() == ASN1IdentifierClass.UNIVERSAL) {
|
if (asn1obj.identifier!.typeClass() == ASN1IdentifierClass.UNIVERSAL) {
|
||||||
var contentData = loadSubContent(iterator: iterator);
|
var contentData = loadSubContent(iterator: iterator);
|
||||||
|
|
||||||
asn1obj.encoded = Uint8List.fromList(contentData);
|
asn1obj.encoded = Uint8List.fromList(contentData);
|
||||||
|
|
||||||
// decode the content data with come more convenient format
|
// decode the content data with come more convenient format
|
||||||
|
|
||||||
var tagNumber = asn1obj.identifier.tagNumber();
|
var tagNumber = asn1obj.identifier!.tagNumber();
|
||||||
|
|
||||||
if (tagNumber == ASN1IdentifierTagNumber.END_OF_CONTENT) {
|
if (tagNumber == ASN1IdentifierTagNumber.END_OF_CONTENT) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -130,9 +131,12 @@ class ASN1DERDecoder {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BigInt getContentLength({@required Iterator<int> iterator}) {
|
static BigInt getContentLength({required Iterator<int> iterator}) {
|
||||||
if (iterator.moveNext()) {
|
if (iterator.moveNext()) {
|
||||||
var first = iterator.current;
|
int? first;
|
||||||
|
try {
|
||||||
|
first = iterator.current;
|
||||||
|
} catch (e) {}
|
||||||
if (first != null) {
|
if (first != null) {
|
||||||
if ((first & 0x80) != 0) {
|
if ((first & 0x80) != 0) {
|
||||||
// long
|
// long
|
||||||
|
@ -141,7 +145,10 @@ class ASN1DERDecoder {
|
||||||
var data = <int>[];
|
var data = <int>[];
|
||||||
for (var i = 0; i < octetsToRead; i++) {
|
for (var i = 0; i < octetsToRead; i++) {
|
||||||
if (iterator.moveNext()) {
|
if (iterator.moveNext()) {
|
||||||
var n = iterator.current;
|
int? n;
|
||||||
|
try {
|
||||||
|
n = iterator.current;
|
||||||
|
} catch (e) {}
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
data.add(n);
|
data.add(n);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +165,7 @@ class ASN1DERDecoder {
|
||||||
return BigInt.from(0);
|
return BigInt.from(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<int> loadSubContent({@required Iterator<int> iterator}) {
|
static List<int> loadSubContent({required Iterator<int> iterator}) {
|
||||||
var len = getContentLength(iterator: iterator);
|
var len = getContentLength(iterator: iterator);
|
||||||
int int64MaxValue = double.maxFinite.toInt();
|
int int64MaxValue = double.maxFinite.toInt();
|
||||||
|
|
||||||
|
@ -170,7 +177,10 @@ class ASN1DERDecoder {
|
||||||
|
|
||||||
for (var i = 0; i < len.toInt(); i++) {
|
for (var i = 0; i < len.toInt(); i++) {
|
||||||
if (iterator.moveNext()) {
|
if (iterator.moveNext()) {
|
||||||
var n = iterator.current;
|
int? n;
|
||||||
|
try {
|
||||||
|
n = iterator.current;
|
||||||
|
} catch (e) {}
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
byteArray.add(n);
|
byteArray.add(n);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +193,7 @@ class ASN1DERDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode DER OID bytes to String with dot notation
|
/// Decode DER OID bytes to String with dot notation
|
||||||
static String decodeOid({@required List<int> contentData}) {
|
static String decodeOid({required List<int> contentData}) {
|
||||||
if (contentData.isEmpty) {
|
if (contentData.isEmpty) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -211,7 +221,7 @@ class ASN1DERDecoder {
|
||||||
///dates past 2049. Parsing that structure hasn't been implemented yet.
|
///dates past 2049. Parsing that structure hasn't been implemented yet.
|
||||||
///
|
///
|
||||||
///[contentData] the UTCTime value to convert.
|
///[contentData] the UTCTime value to convert.
|
||||||
static DateTime utcTimeToDate({@required List<int> contentData}) {
|
static DateTime? utcTimeToDate({required List<int> contentData}) {
|
||||||
/* The following formats can be used:
|
/* The following formats can be used:
|
||||||
YYMMDDhhmmZ
|
YYMMDDhhmmZ
|
||||||
YYMMDDhhmm+hh'mm'
|
YYMMDDhhmm+hh'mm'
|
||||||
|
@ -231,7 +241,7 @@ class ASN1DERDecoder {
|
||||||
hh' is the absolute value of the offset from GMT in hours
|
hh' is the absolute value of the offset from GMT in hours
|
||||||
mm' is the absolute value of the offset from GMT in minutes */
|
mm' is the absolute value of the offset from GMT in minutes */
|
||||||
|
|
||||||
String utc;
|
String? utc;
|
||||||
try {
|
try {
|
||||||
utc = utf8.decode(contentData);
|
utc = utf8.decode(contentData);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
@ -250,8 +260,8 @@ class ASN1DERDecoder {
|
||||||
var mm = int.parse(utc.substring(8, 10), radix: 10);
|
var mm = int.parse(utc.substring(8, 10), radix: 10);
|
||||||
var ss = 0;
|
var ss = 0;
|
||||||
|
|
||||||
int end;
|
int? end;
|
||||||
String c;
|
String? c;
|
||||||
// not just YYMMDDhhmmZ
|
// not just YYMMDDhhmmZ
|
||||||
if (utc.length > 11) {
|
if (utc.length > 11) {
|
||||||
// get character after minutes
|
// get character after minutes
|
||||||
|
@ -298,7 +308,7 @@ class ASN1DERDecoder {
|
||||||
///Converts a GeneralizedTime value to a date.
|
///Converts a GeneralizedTime value to a date.
|
||||||
///
|
///
|
||||||
///[contentData] the GeneralizedTime value to convert.
|
///[contentData] the GeneralizedTime value to convert.
|
||||||
static DateTime generalizedTimeToDate({@required List<int> contentData}) {
|
static DateTime? generalizedTimeToDate({required List<int> contentData}) {
|
||||||
/* The following formats can be used:
|
/* The following formats can be used:
|
||||||
YYYYMMDDHHMMSS
|
YYYYMMDDHHMMSS
|
||||||
YYYYMMDDHHMMSS.fff
|
YYYYMMDDHHMMSS.fff
|
||||||
|
@ -321,7 +331,7 @@ class ASN1DERDecoder {
|
||||||
hh' is the absolute value of the offset from GMT in hours
|
hh' is the absolute value of the offset from GMT in hours
|
||||||
mm' is the absolute value of the offset from GMT in minutes */
|
mm' is the absolute value of the offset from GMT in minutes */
|
||||||
|
|
||||||
String gentime;
|
String? gentime;
|
||||||
try {
|
try {
|
||||||
gentime = utf8.decode(contentData);
|
gentime = utf8.decode(contentData);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
@ -385,7 +395,7 @@ class ASN1DERDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInt toIntValue(List<int> data) {
|
BigInt? toIntValue(List<int> data) {
|
||||||
if (data.length > 8) {
|
if (data.length > 8) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,15 @@ class ASN1DistinguishedNames {
|
||||||
ASN1DistinguishedNames.EMAIL,
|
ASN1DistinguishedNames.EMAIL,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static ASN1DistinguishedNames fromValue(String oid) {
|
static ASN1DistinguishedNames? fromValue(String? oid) {
|
||||||
if (oid != null)
|
if (oid != null) {
|
||||||
|
try {
|
||||||
return ASN1DistinguishedNames.values
|
return ASN1DistinguishedNames.values
|
||||||
.firstWhere((element) => element.oid() == oid, orElse: () => null);
|
.firstWhere((element) => element.oid() == oid);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,15 @@ class ASN1IdentifierClass {
|
||||||
ASN1IdentifierClass.PRIVATE,
|
ASN1IdentifierClass.PRIVATE,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static ASN1IdentifierClass fromValue(int value) {
|
static ASN1IdentifierClass? fromValue(int? value) {
|
||||||
if (value != null)
|
if (value != null) {
|
||||||
|
try {
|
||||||
return ASN1IdentifierClass.values.firstWhere(
|
return ASN1IdentifierClass.values.firstWhere(
|
||||||
(element) => element.toValue() == value,
|
(element) => element.toValue() == value);
|
||||||
orElse: () => null);
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +87,15 @@ class ASN1IdentifierTagNumber {
|
||||||
ASN1IdentifierTagNumber.BMP_STRING,
|
ASN1IdentifierTagNumber.BMP_STRING,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static ASN1IdentifierTagNumber fromValue(int value) {
|
static ASN1IdentifierTagNumber? fromValue(int? value) {
|
||||||
if (value != null)
|
if (value != null) {
|
||||||
|
try {
|
||||||
return ASN1IdentifierTagNumber.values.firstWhere(
|
return ASN1IdentifierTagNumber.values.firstWhere(
|
||||||
(element) => element.toValue() == value,
|
(element) => element.toValue() == value);
|
||||||
orElse: () => null);
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,34 +7,34 @@ import 'oid.dart';
|
||||||
|
|
||||||
class ASN1Object {
|
class ASN1Object {
|
||||||
/// This property contains the DER encoded object
|
/// This property contains the DER encoded object
|
||||||
Uint8List encoded;
|
Uint8List? encoded;
|
||||||
|
|
||||||
/// This property contains the decoded Swift object whenever is possible
|
/// This property contains the decoded Swift object whenever is possible
|
||||||
dynamic value;
|
dynamic value;
|
||||||
|
|
||||||
ASN1Identifier identifier;
|
ASN1Identifier? identifier;
|
||||||
|
|
||||||
List<ASN1Object> sub;
|
List<ASN1Object>? sub;
|
||||||
|
|
||||||
ASN1Object parent;
|
ASN1Object? parent;
|
||||||
|
|
||||||
ASN1Object subAtIndex(int index) {
|
ASN1Object? subAtIndex(int index) {
|
||||||
if (sub != null && index >= 0 && index < sub.length) {
|
if (sub != null && index >= 0 && index < sub!.length) {
|
||||||
return sub[index];
|
return sub![index];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1Object firstSub() {
|
ASN1Object? firstSub() {
|
||||||
if (subCount() > 0) {
|
if (subCount() > 0) {
|
||||||
return sub.first;
|
return sub!.first;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1Object lastSub() {
|
ASN1Object? lastSub() {
|
||||||
if (subCount() > 0) {
|
if (subCount() > 0) {
|
||||||
return sub.last;
|
return sub!.last;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class ASN1Object {
|
||||||
return sub?.length ?? 0;
|
return sub?.length ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1Object findOid({OID oid, String oidValue}) {
|
ASN1Object? findOid({OID? oid, String? oidValue}) {
|
||||||
oidValue = oid != null ? oid.toValue() : oidValue;
|
oidValue = oid != null ? oid.toValue() : oidValue;
|
||||||
for (var child in (sub ?? <ASN1Object>[])) {
|
for (var child in (sub ?? <ASN1Object>[])) {
|
||||||
if (child.identifier?.tagNumber() ==
|
if (child.identifier?.tagNumber() ==
|
||||||
|
@ -67,7 +67,7 @@ class ASN1Object {
|
||||||
|
|
||||||
String printAsn1({insets = ""}) {
|
String printAsn1({insets = ""}) {
|
||||||
var output = insets;
|
var output = insets;
|
||||||
output += identifier?.description?.toUpperCase() ?? "";
|
output += identifier?.description.toUpperCase() ?? "";
|
||||||
output += (value != null ? ": $value" : "");
|
output += (value != null ? ": $value" : "");
|
||||||
if (identifier?.typeClass() == ASN1IdentifierClass.UNIVERSAL &&
|
if (identifier?.typeClass() == ASN1IdentifierClass.UNIVERSAL &&
|
||||||
identifier?.tagNumber() == ASN1IdentifierTagNumber.OBJECT_IDENTIFIER) {
|
identifier?.tagNumber() == ASN1IdentifierTagNumber.OBJECT_IDENTIFIER) {
|
||||||
|
@ -76,12 +76,12 @@ class ASN1Object {
|
||||||
output += " ($descr)";
|
output += " ($descr)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output += sub != null && sub.length > 0 ? " {" : "";
|
output += sub != null && sub!.length > 0 ? " {" : "";
|
||||||
output += "\n";
|
output += "\n";
|
||||||
for (var item in (sub ?? <ASN1Object>[])) {
|
for (var item in (sub ?? <ASN1Object>[])) {
|
||||||
output += item.printAsn1(insets: insets + " ");
|
output += item.printAsn1(insets: insets + " ");
|
||||||
}
|
}
|
||||||
output += sub != null && sub.length > 0 ? "}\n" : "";
|
output += sub != null && sub!.length > 0 ? "}\n" : "";
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ class ASN1Object {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1Object atIndex(X509BlockPosition x509blockPosition) {
|
ASN1Object? atIndex(X509BlockPosition x509blockPosition) {
|
||||||
if (sub != null && x509blockPosition.index < sub.length) {
|
if (sub != null && x509blockPosition.index < sub!.length) {
|
||||||
return sub[x509blockPosition.index];
|
return sub![x509blockPosition.index];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,20 @@ class KeyUsage {
|
||||||
KeyUsage.decipherOnly,
|
KeyUsage.decipherOnly,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static KeyUsage fromIndex(int value) {
|
static KeyUsage? fromIndex(int? value) {
|
||||||
return KeyUsage.values.firstWhere((element) => element.toValue() == value,
|
if (value != null) {
|
||||||
orElse: () => null);
|
try {
|
||||||
|
return KeyUsage.values.firstWhere((element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int toValue() => _value;
|
int toValue() => _value;
|
||||||
|
|
||||||
String name() => _KeyUsageMapName[this._value];
|
String name() => _KeyUsageMapName.containsKey(this._value) ? _KeyUsageMapName[this._value]! : "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => "($_value, ${name()})";
|
String toString() => "($_value, ${name()})";
|
||||||
|
|
|
@ -102,14 +102,20 @@ class OID {
|
||||||
OID.timeStamping,
|
OID.timeStamping,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static OID fromValue(String value) {
|
static OID? fromValue(String? value) {
|
||||||
return OID.values.firstWhere((element) => element.toValue() == value,
|
if (value != null) {
|
||||||
orElse: () => null);
|
try {
|
||||||
|
return OID.values.firstWhere((element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toValue() => _value;
|
String toValue() => _value;
|
||||||
|
|
||||||
String name() => _oidMapName[this._value];
|
String name() => _oidMapName.containsKey(this._value) ? _oidMapName[this._value]! : "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => "($_value, ${name()})";
|
String toString() => "($_value, ${name()})";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'asn1_decoder.dart';
|
import 'asn1_decoder.dart';
|
||||||
import 'asn1_object.dart';
|
import 'asn1_object.dart';
|
||||||
import 'oid.dart';
|
import 'oid.dart';
|
||||||
|
@ -13,19 +12,19 @@ import 'asn1_distinguished_names.dart';
|
||||||
///Class that represents a X.509 certificate.
|
///Class that represents a X.509 certificate.
|
||||||
///This provides a standard way to access all the attributes of an X.509 certificate.
|
///This provides a standard way to access all the attributes of an X.509 certificate.
|
||||||
class X509Certificate {
|
class X509Certificate {
|
||||||
List<ASN1Object> asn1;
|
List<ASN1Object>? asn1;
|
||||||
ASN1Object block1;
|
ASN1Object? block1;
|
||||||
|
|
||||||
///Returns the encoded form of this certificate. It is
|
///Returns the encoded form of this certificate. It is
|
||||||
///assumed that each certificate type would have only a single
|
///assumed that each certificate type would have only a single
|
||||||
///form of encoding; for example, X.509 certificates would
|
///form of encoding; for example, X.509 certificates would
|
||||||
///be encoded as ASN.1 DER.
|
///be encoded as ASN.1 DER.
|
||||||
Uint8List encoded;
|
Uint8List? encoded;
|
||||||
|
|
||||||
static const beginPemBlock = "-----BEGIN CERTIFICATE-----";
|
static const beginPemBlock = "-----BEGIN CERTIFICATE-----";
|
||||||
static const endPemBlock = "-----END CERTIFICATE-----";
|
static const endPemBlock = "-----END CERTIFICATE-----";
|
||||||
|
|
||||||
X509Certificate({ASN1Object asn1}) {
|
X509Certificate({ASN1Object? asn1}) {
|
||||||
if (asn1 != null) {
|
if (asn1 != null) {
|
||||||
var block1 = asn1.subAtIndex(0);
|
var block1 = asn1.subAtIndex(0);
|
||||||
if (block1 == null) {
|
if (block1 == null) {
|
||||||
|
@ -34,7 +33,7 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static X509Certificate fromData({@required Uint8List data}) {
|
static X509Certificate fromData({required Uint8List data}) {
|
||||||
var decoded = utf8.decode(data, allowMalformed: true);
|
var decoded = utf8.decode(data, allowMalformed: true);
|
||||||
if (decoded.contains(X509Certificate.beginPemBlock)) {
|
if (decoded.contains(X509Certificate.beginPemBlock)) {
|
||||||
return X509Certificate.fromPemData(pem: data);
|
return X509Certificate.fromPemData(pem: data);
|
||||||
|
@ -43,10 +42,10 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static X509Certificate fromDerData({@required Uint8List der}) {
|
static X509Certificate fromDerData({required Uint8List der}) {
|
||||||
var asn1 = ASN1DERDecoder.decode(data: der.toList(growable: true));
|
var asn1 = ASN1DERDecoder.decode(data: der.toList(growable: true));
|
||||||
if (asn1.length > 0) {
|
if (asn1.length > 0) {
|
||||||
var block1 = asn1.first?.subAtIndex(0);
|
var block1 = asn1.first.subAtIndex(0);
|
||||||
if (block1 != null) {
|
if (block1 != null) {
|
||||||
var certificate = X509Certificate();
|
var certificate = X509Certificate();
|
||||||
certificate.asn1 = asn1;
|
certificate.asn1 = asn1;
|
||||||
|
@ -58,7 +57,7 @@ class X509Certificate {
|
||||||
throw ASN1ParseError();
|
throw ASN1ParseError();
|
||||||
}
|
}
|
||||||
|
|
||||||
static X509Certificate fromPemData({@required Uint8List pem}) {
|
static X509Certificate fromPemData({required Uint8List pem}) {
|
||||||
var derData = X509Certificate.decodeToDER(pemData: pem);
|
var derData = X509Certificate.decodeToDER(pemData: pem);
|
||||||
if (derData == null) {
|
if (derData == null) {
|
||||||
throw ASN1ParseError();
|
throw ASN1ParseError();
|
||||||
|
@ -67,9 +66,9 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Read possible PEM encoding
|
///Read possible PEM encoding
|
||||||
static Uint8List decodeToDER({@required pemData}) {
|
static Uint8List? decodeToDER({required pemData}) {
|
||||||
var pem = String.fromCharCodes(pemData);
|
var pem = String.fromCharCodes(pemData);
|
||||||
if (pem != null && pem.contains(X509Certificate.beginPemBlock)) {
|
if (pem.contains(X509Certificate.beginPemBlock)) {
|
||||||
var lines = pem.split("\n");
|
var lines = pem.split("\n");
|
||||||
var base64buffer = "";
|
var base64buffer = "";
|
||||||
var certLine = false;
|
var certLine = false;
|
||||||
|
@ -85,7 +84,7 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8List derDataDecoded;
|
Uint8List? derDataDecoded;
|
||||||
try {
|
try {
|
||||||
derDataDecoded = Uint8List.fromList(utf8.encode(base64buffer));
|
derDataDecoded = Uint8List.fromList(utf8.encode(base64buffer));
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
@ -97,38 +96,40 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
String get description =>
|
String get description =>
|
||||||
asn1.fold("", (value, element) => value + element.description + "\n");
|
asn1?.fold("", (value, element) => (value ?? '') + element.description + '\n') ?? '';
|
||||||
|
|
||||||
///Checks that the given date is within the certificate's validity period.
|
///Checks that the given date is within the certificate's validity period.
|
||||||
bool checkValidity({DateTime date}) {
|
bool checkValidity({DateTime? date}) {
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
date = DateTime.now();
|
date = DateTime.now();
|
||||||
}
|
}
|
||||||
if (notBefore != null && notAfter != null) {
|
if (notBefore != null && notAfter != null) {
|
||||||
return date.isAfter(notBefore) && date.isBefore(notAfter);
|
return date.isAfter(notBefore!) && date.isBefore(notAfter!);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the version (version number) value from the certificate.
|
///Gets the version (version number) value from the certificate.
|
||||||
int get version {
|
int? get version {
|
||||||
var v = firstLeafValue(block: block1) as List<int>;
|
if (block1 != null) {
|
||||||
|
var v = firstLeafValue(block: block1!) as List<int>?;
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
var index = toIntValue(v);
|
var index = toIntValue(v);
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
return index.toInt() + 1;
|
return index.toInt() + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the serialNumber value from the certificate.
|
///Gets the serialNumber value from the certificate.
|
||||||
List<int> get serialNumber =>
|
List<int> get serialNumber =>
|
||||||
block1.atIndex(X509BlockPosition.serialNumber)?.value as List<int>;
|
block1?.atIndex(X509BlockPosition.serialNumber)?.value as List<int>;
|
||||||
|
|
||||||
///Returns the issuer (issuer distinguished name) value from the certificate as a String.
|
///Returns the issuer (issuer distinguished name) value from the certificate as a String.
|
||||||
String get issuerDistinguishedName {
|
String? get issuerDistinguishedName {
|
||||||
var issuerBlock = block1.atIndex(X509BlockPosition.issuer);
|
var issuerBlock = block1?.atIndex(X509BlockPosition.issuer);
|
||||||
if (issuerBlock != null) {
|
if (issuerBlock != null) {
|
||||||
return blockDistinguishedName(block: issuerBlock);
|
return blockDistinguishedName(block: issuerBlock);
|
||||||
}
|
}
|
||||||
|
@ -137,10 +138,10 @@ class X509Certificate {
|
||||||
|
|
||||||
List<String> get issuerOIDs {
|
List<String> get issuerOIDs {
|
||||||
var result = <String>[];
|
var result = <String>[];
|
||||||
var issuerBlock = block1.atIndex(X509BlockPosition.issuer);
|
var issuerBlock = block1?.atIndex(X509BlockPosition.issuer);
|
||||||
if (issuerBlock != null) {
|
if (issuerBlock != null) {
|
||||||
for (var sub in (issuerBlock.sub ?? <ASN1Object>[])) {
|
for (var sub in (issuerBlock.sub ?? <ASN1Object>[])) {
|
||||||
var value = firstLeafValue(block: sub) as String;
|
var value = firstLeafValue(block: sub) as String?;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
|
@ -149,12 +150,12 @@ class X509Certificate {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String issuer({String oid, ASN1DistinguishedNames dn}) {
|
String? issuer({String? oid, ASN1DistinguishedNames? dn}) {
|
||||||
if (oid == null && dn != null) {
|
if (oid == null && dn != null) {
|
||||||
oid = dn.oid();
|
oid = dn.oid();
|
||||||
}
|
}
|
||||||
if (oid != null) {
|
if (oid != null) {
|
||||||
var issuerBlock = block1.atIndex(X509BlockPosition.issuer);
|
var issuerBlock = block1?.atIndex(X509BlockPosition.issuer);
|
||||||
if (issuerBlock != null) {
|
if (issuerBlock != null) {
|
||||||
var oidBlock = issuerBlock.findOid(oidValue: oid);
|
var oidBlock = issuerBlock.findOid(oidValue: oid);
|
||||||
if (oidBlock != null) {
|
if (oidBlock != null) {
|
||||||
|
@ -171,8 +172,8 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Returns the subject (subject distinguished name) value from the certificate as a String.
|
///Returns the subject (subject distinguished name) value from the certificate as a String.
|
||||||
String get subjectDistinguishedName {
|
String? get subjectDistinguishedName {
|
||||||
var subjectBlock = block1.atIndex(X509BlockPosition.subject);
|
var subjectBlock = block1?.atIndex(X509BlockPosition.subject);
|
||||||
if (subjectBlock != null) {
|
if (subjectBlock != null) {
|
||||||
return blockDistinguishedName(block: subjectBlock);
|
return blockDistinguishedName(block: subjectBlock);
|
||||||
}
|
}
|
||||||
|
@ -181,10 +182,10 @@ class X509Certificate {
|
||||||
|
|
||||||
List<String> get subjectOIDs {
|
List<String> get subjectOIDs {
|
||||||
var result = <String>[];
|
var result = <String>[];
|
||||||
var subjectBlock = block1.atIndex(X509BlockPosition.subject);
|
var subjectBlock = block1?.atIndex(X509BlockPosition.subject);
|
||||||
if (subjectBlock != null) {
|
if (subjectBlock != null) {
|
||||||
for (var sub in (subjectBlock.sub ?? <ASN1Object>[])) {
|
for (var sub in (subjectBlock.sub ?? <ASN1Object>[])) {
|
||||||
var value = firstLeafValue(block: sub) as String;
|
var value = firstLeafValue(block: sub) as String?;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result.add(value);
|
result.add(value);
|
||||||
}
|
}
|
||||||
|
@ -193,12 +194,12 @@ class X509Certificate {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String subject({String oid, ASN1DistinguishedNames dn}) {
|
String? subject({String? oid, ASN1DistinguishedNames? dn}) {
|
||||||
if (oid == null && dn != null) {
|
if (oid == null && dn != null) {
|
||||||
oid = dn.oid();
|
oid = dn.oid();
|
||||||
}
|
}
|
||||||
if (oid != null) {
|
if (oid != null) {
|
||||||
var subjectBlock = block1.atIndex(X509BlockPosition.subject);
|
var subjectBlock = block1?.atIndex(X509BlockPosition.subject);
|
||||||
if (subjectBlock != null) {
|
if (subjectBlock != null) {
|
||||||
var oidBlock = subjectBlock.findOid(oidValue: oid);
|
var oidBlock = subjectBlock.findOid(oidValue: oid);
|
||||||
if (oidBlock != null) {
|
if (oidBlock != null) {
|
||||||
|
@ -215,30 +216,29 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the notBefore date from the validity period of the certificate.
|
///Gets the notBefore date from the validity period of the certificate.
|
||||||
DateTime get notBefore =>
|
DateTime? get notBefore =>
|
||||||
block1.atIndex(X509BlockPosition.dateValidity)?.subAtIndex(0)?.value
|
block1?.atIndex(X509BlockPosition.dateValidity)?.subAtIndex(0)?.value
|
||||||
as DateTime;
|
as DateTime?;
|
||||||
|
|
||||||
///Gets the notAfter date from the validity period of the certificate.
|
///Gets the notAfter date from the validity period of the certificate.
|
||||||
DateTime get notAfter {
|
DateTime? get notAfter {
|
||||||
var value = block1
|
var value = block1?.atIndex(X509BlockPosition.dateValidity)
|
||||||
.atIndex(X509BlockPosition.dateValidity)
|
|
||||||
?.subAtIndex(1)
|
?.subAtIndex(1)
|
||||||
?.value as DateTime;
|
?.value as DateTime?;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the signature value (the raw signature bits) from the certificate.
|
///Gets the signature value (the raw signature bits) from the certificate.
|
||||||
List<int> get signature => asn1[0].subAtIndex(2)?.value as List<int>;
|
List<int>? get signature => asn1?[0].subAtIndex(2)?.value as List<int>;
|
||||||
|
|
||||||
///Gets the signature algorithm name for the certificate signature algorithm.
|
///Gets the signature algorithm name for the certificate signature algorithm.
|
||||||
String get sigAlgName => OID.fromValue(sigAlgOID ?? "")?.name();
|
String? get sigAlgName => OID.fromValue(sigAlgOID ?? '')?.name();
|
||||||
|
|
||||||
///Gets the signature algorithm OID string from the certificate.
|
///Gets the signature algorithm OID string from the certificate.
|
||||||
String get sigAlgOID => block1.subAtIndex(2)?.subAtIndex(0)?.value as String;
|
String? get sigAlgOID => block1?.subAtIndex(2)?.subAtIndex(0)?.value as String?;
|
||||||
|
|
||||||
///Gets the DER-encoded signature algorithm parameters from this certificate's signature algorithm.
|
///Gets the DER-encoded signature algorithm parameters from this certificate's signature algorithm.
|
||||||
List<int> get sigAlgParams => null;
|
List<int>? get sigAlgParams => null;
|
||||||
|
|
||||||
///Gets a boolean array representing bits of the KeyUsage extension, (OID = 2.5.29.15).
|
///Gets a boolean array representing bits of the KeyUsage extension, (OID = 2.5.29.15).
|
||||||
///```
|
///```
|
||||||
|
@ -256,12 +256,12 @@ class X509Certificate {
|
||||||
///```
|
///```
|
||||||
List<bool> get keyUsage {
|
List<bool> get keyUsage {
|
||||||
var result = <bool>[];
|
var result = <bool>[];
|
||||||
var oidBlock = block1.findOid(oid: OID.keyUsage);
|
var oidBlock = block1?.findOid(oid: OID.keyUsage);
|
||||||
if (oidBlock != null) {
|
if (oidBlock != null) {
|
||||||
var sub = oidBlock.parent?.sub;
|
var sub = oidBlock.parent?.sub;
|
||||||
if (sub != null && sub.length > 0) {
|
if (sub != null && sub.length > 0) {
|
||||||
var data = sub.last.subAtIndex(0)?.value as List<int>;
|
var data = sub.last.subAtIndex(0)?.value as List<int>?;
|
||||||
int bits = (data != null && data.length > 0) ? data.first ?? 0 : 0;
|
int bits = (data != null && data.length > 0) ? data.first : 0;
|
||||||
for (var index = 0; index < 8; index++) {
|
for (var index = 0; index < 8; index++) {
|
||||||
var value = bits & (1 << index).toUnsigned(8) != 0;
|
var value = bits & (1 << index).toUnsigned(8) != 0;
|
||||||
result.insert(0, value);
|
result.insert(0, value);
|
||||||
|
@ -285,8 +285,8 @@ class X509Certificate {
|
||||||
extensionObject(oid: OID.issuerAltName)?.valueAsStrings ?? <String>[];
|
extensionObject(oid: OID.issuerAltName)?.valueAsStrings ?? <String>[];
|
||||||
|
|
||||||
///Gets the informations of the public key from this certificate.
|
///Gets the informations of the public key from this certificate.
|
||||||
X509PublicKey get publicKey {
|
X509PublicKey? get publicKey {
|
||||||
var pkBlock = block1.atIndex(X509BlockPosition.publicKey);
|
var pkBlock = block1?.atIndex(X509BlockPosition.publicKey);
|
||||||
if (pkBlock != null) {
|
if (pkBlock != null) {
|
||||||
return X509PublicKey(pkBlock: pkBlock);
|
return X509PublicKey(pkBlock: pkBlock);
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,7 @@ class X509Certificate {
|
||||||
return extensionBlocks
|
return extensionBlocks
|
||||||
.map((block) => X509Extension(block: block))
|
.map((block) => X509Extension(block: block))
|
||||||
.where((extension) => extension.isCritical)
|
.where((extension) => extension.isCritical)
|
||||||
.map((extension) => extension.oid)
|
.map((extension) => extension.oid ?? '')
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ class X509Certificate {
|
||||||
return extensionBlocks
|
return extensionBlocks
|
||||||
.map((block) => X509Extension(block: block))
|
.map((block) => X509Extension(block: block))
|
||||||
.where((extension) => !extension.isCritical)
|
.where((extension) => !extension.isCritical)
|
||||||
.map((extension) => extension.oid)
|
.map((extension) => extension.oid ?? '')
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ class X509Certificate {
|
||||||
?.firstSub()
|
?.firstSub()
|
||||||
?.sub
|
?.sub
|
||||||
?.map((e) => e.firstSub()?.value as String)
|
?.map((e) => e.firstSub()?.value as String)
|
||||||
?.toList() ??
|
.toList() ??
|
||||||
<String>[];
|
<String>[];
|
||||||
|
|
||||||
///Gets the list of CRL distribution points from the CRLDistributionPoints extension, (OID = 2.5.29.31).
|
///Gets the list of CRL distribution points from the CRLDistributionPoints extension, (OID = 2.5.29.31).
|
||||||
|
@ -373,7 +373,7 @@ class X509Certificate {
|
||||||
?.firstSub()
|
?.firstSub()
|
||||||
?.sub
|
?.sub
|
||||||
?.map((e) => e.firstSub()?.firstSub()?.firstSub()?.value as String)
|
?.map((e) => e.firstSub()?.firstSub()?.firstSub()?.value as String)
|
||||||
?.toList() ??
|
.toList() ??
|
||||||
<String>[];
|
<String>[];
|
||||||
|
|
||||||
///Gets the map of the format (as a key) and location (as a value) of additional information
|
///Gets the map of the format (as a key) and location (as a value) of additional information
|
||||||
|
@ -390,24 +390,23 @@ class X509Certificate {
|
||||||
sub.forEach((element) {
|
sub.forEach((element) {
|
||||||
if (element.subCount() > 1) {
|
if (element.subCount() > 1) {
|
||||||
result.putIfAbsent(
|
result.putIfAbsent(
|
||||||
element.subAtIndex(0).value, () => element.subAtIndex(1).value);
|
element.subAtIndex(0)!.value, () => element.subAtIndex(1)!.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ASN1Object> get extensionBlocks =>
|
List<ASN1Object>? get extensionBlocks =>
|
||||||
block1.atIndex(X509BlockPosition.extensions)?.subAtIndex(0)?.sub;
|
block1?.atIndex(X509BlockPosition.extensions)?.subAtIndex(0)?.sub;
|
||||||
|
|
||||||
///Gets the extension information of the given OID code or enum string value.
|
///Gets the extension information of the given OID code or enum string value.
|
||||||
X509Extension extensionObject({String oidValue, OID oid}) {
|
X509Extension? extensionObject({String? oidValue, OID? oid}) {
|
||||||
if (oidValue == null && oid != null) {
|
if (oidValue == null && oid != null) {
|
||||||
oidValue = oid.toValue();
|
oidValue = oid.toValue();
|
||||||
}
|
}
|
||||||
if (oidValue != null) {
|
if (oidValue != null) {
|
||||||
var block = block1
|
var block = block1?.atIndex(X509BlockPosition.extensions)
|
||||||
.atIndex(X509BlockPosition.extensions)
|
|
||||||
?.findOid(oidValue: oidValue)
|
?.findOid(oidValue: oidValue)
|
||||||
?.parent;
|
?.parent;
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
|
@ -418,7 +417,7 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Format subject/issuer information in RFC1779
|
///Format subject/issuer information in RFC1779
|
||||||
String blockDistinguishedName({@required ASN1Object block}) {
|
String blockDistinguishedName({required ASN1Object block}) {
|
||||||
var result = "";
|
var result = "";
|
||||||
for (var oidName in ASN1DistinguishedNames.values) {
|
for (var oidName in ASN1DistinguishedNames.values) {
|
||||||
var oidBlock = block.findOid(oidValue: oidName.oid());
|
var oidBlock = block.findOid(oidValue: oidName.oid());
|
||||||
|
@ -431,7 +430,7 @@ class X509Certificate {
|
||||||
|
|
||||||
var sub = oidBlock.parent?.sub;
|
var sub = oidBlock.parent?.sub;
|
||||||
if (sub != null && sub.length > 0) {
|
if (sub != null && sub.length > 0) {
|
||||||
var value = sub.last.value as String;
|
var value = sub.last.value as String?;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
var specialChar = ",+=\n<>#;\\";
|
var specialChar = ",+=\n<>#;\\";
|
||||||
var quote = "";
|
var quote = "";
|
||||||
|
@ -490,10 +489,13 @@ class X509Certificate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic firstLeafValue({@required ASN1Object block}) {
|
dynamic firstLeafValue({required ASN1Object block}) {
|
||||||
var sub = block.sub;
|
var sub = block.sub;
|
||||||
if (sub != null && sub.length > 0) {
|
if (sub != null && sub.length > 0) {
|
||||||
var subFirst = sub.first;
|
ASN1Object? subFirst;
|
||||||
|
try {
|
||||||
|
subFirst = sub.first;
|
||||||
|
} catch (e) {}
|
||||||
if (subFirst != null) {
|
if (subFirst != null) {
|
||||||
return firstLeafValue(block: subFirst);
|
return firstLeafValue(block: subFirst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,28 @@ import 'asn1_object.dart';
|
||||||
import 'oid.dart';
|
import 'oid.dart';
|
||||||
|
|
||||||
class X509Extension {
|
class X509Extension {
|
||||||
ASN1Object block;
|
ASN1Object? block;
|
||||||
|
|
||||||
X509Extension({this.block});
|
X509Extension({required this.block});
|
||||||
|
|
||||||
String get oid => block.subAtIndex(0)?.value;
|
String? get oid => block?.subAtIndex(0)?.value;
|
||||||
|
|
||||||
String get name => OID.fromValue(oid ?? "")?.name();
|
String? get name => OID.fromValue(oid)?.name();
|
||||||
|
|
||||||
bool get isCritical {
|
bool get isCritical {
|
||||||
if ((block.sub?.length ?? 0) > 2) {
|
if ((block?.sub?.length ?? 0) > 2) {
|
||||||
return block.subAtIndex(1)?.value ?? false;
|
return block?.subAtIndex(1)?.value ?? false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic get value {
|
dynamic get value {
|
||||||
var sub = block.sub;
|
var sub = block?.sub;
|
||||||
if (sub != null && sub.length > 0) {
|
if (sub != null && sub.length > 0) {
|
||||||
var valueBlock = sub.last;
|
ASN1Object? valueBlock;
|
||||||
|
try {
|
||||||
|
valueBlock = sub.last;
|
||||||
|
} catch (e) {}
|
||||||
if (valueBlock != null) {
|
if (valueBlock != null) {
|
||||||
return firstLeafValue(block: valueBlock);
|
return firstLeafValue(block: valueBlock);
|
||||||
}
|
}
|
||||||
|
@ -29,19 +32,23 @@ class X509Extension {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1Object get valueAsBlock {
|
ASN1Object? get valueAsBlock {
|
||||||
var sub = block.sub;
|
var sub = block?.sub;
|
||||||
if (sub != null && sub.length > 0) {
|
if (sub != null && sub.length > 0) {
|
||||||
return sub.last;
|
ASN1Object? valueBlock;
|
||||||
|
try {
|
||||||
|
valueBlock = sub.last;
|
||||||
|
} catch (e) {}
|
||||||
|
return valueBlock;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> get valueAsStrings {
|
List<String> get valueAsStrings {
|
||||||
var result = <String>[];
|
var result = <String>[];
|
||||||
var sub;
|
var sub = <ASN1Object>[];
|
||||||
try {
|
try {
|
||||||
sub = block.sub?.last?.sub?.last?.sub ?? <ASN1Object>[];
|
sub = block?.sub?.last.sub?.last.sub ?? <ASN1Object>[];
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
for (var item in sub) {
|
for (var item in sub) {
|
||||||
|
|
|
@ -5,17 +5,17 @@ import 'asn1_object.dart';
|
||||||
import 'oid.dart';
|
import 'oid.dart';
|
||||||
|
|
||||||
class X509PublicKey {
|
class X509PublicKey {
|
||||||
ASN1Object pkBlock;
|
ASN1Object? pkBlock;
|
||||||
|
|
||||||
X509PublicKey({this.pkBlock});
|
X509PublicKey({this.pkBlock});
|
||||||
|
|
||||||
String get algOid => pkBlock?.subAtIndex(0)?.subAtIndex(0)?.value;
|
String? get algOid => pkBlock?.subAtIndex(0)?.subAtIndex(0)?.value;
|
||||||
|
|
||||||
String get algName => OID.fromValue(algOid ?? "")?.name();
|
String? get algName => OID.fromValue(algOid)?.name();
|
||||||
|
|
||||||
String get algParams => pkBlock?.subAtIndex(0)?.subAtIndex(1)?.value;
|
String? get algParams => pkBlock?.subAtIndex(0)?.subAtIndex(1)?.value;
|
||||||
|
|
||||||
Uint8List get encoded {
|
Uint8List? get encoded {
|
||||||
var oid = OID.fromValue(algOid);
|
var oid = OID.fromValue(algOid);
|
||||||
var keyData = pkBlock?.subAtIndex(1)?.value ?? null;
|
var keyData = pkBlock?.subAtIndex(1)?.value ?? null;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class X509PublicKey {
|
||||||
if (oid == OID.ecPublicKey) {
|
if (oid == OID.ecPublicKey) {
|
||||||
return Uint8List.fromList(keyData);
|
return Uint8List.fromList(keyData);
|
||||||
} else if (oid == OID.rsaEncryption) {
|
} else if (oid == OID.rsaEncryption) {
|
||||||
List<ASN1Object> publicKeyAsn1Objects;
|
List<ASN1Object>? publicKeyAsn1Objects;
|
||||||
try {
|
try {
|
||||||
publicKeyAsn1Objects =
|
publicKeyAsn1Objects =
|
||||||
ASN1DERDecoder.decode(data: keyData.toList(growable: true));
|
ASN1DERDecoder.decode(data: keyData.toList(growable: true));
|
||||||
|
@ -31,7 +31,7 @@ class X509PublicKey {
|
||||||
|
|
||||||
if (publicKeyAsn1Objects != null && publicKeyAsn1Objects.length > 0) {
|
if (publicKeyAsn1Objects != null && publicKeyAsn1Objects.length > 0) {
|
||||||
var publicKeyModulus =
|
var publicKeyModulus =
|
||||||
publicKeyAsn1Objects.first?.subAtIndex(0)?.value;
|
publicKeyAsn1Objects.first.subAtIndex(0)?.value;
|
||||||
if (publicKeyModulus != null) {
|
if (publicKeyModulus != null) {
|
||||||
return Uint8List.fromList(publicKeyModulus);
|
return Uint8List.fromList(publicKeyModulus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
|
@ -12,11 +11,11 @@ import 'in_app_browser.dart';
|
||||||
///
|
///
|
||||||
///[browserFallback] represents the [InAppBrowser] instance fallback in case `Chrome Custom Tabs`/`SFSafariViewController` is not available.
|
///[browserFallback] represents the [InAppBrowser] instance fallback in case `Chrome Custom Tabs`/`SFSafariViewController` is not available.
|
||||||
class ChromeSafariBrowser {
|
class ChromeSafariBrowser {
|
||||||
String uuid;
|
late String uuid;
|
||||||
InAppBrowser browserFallback;
|
InAppBrowser? browserFallback;
|
||||||
Map<int, ChromeSafariBrowserMenuItem> _menuItems = new HashMap();
|
Map<int, ChromeSafariBrowserMenuItem> _menuItems = new HashMap();
|
||||||
bool _isOpened = false;
|
bool _isOpened = false;
|
||||||
MethodChannel _channel;
|
late MethodChannel _channel;
|
||||||
static const MethodChannel _sharedChannel =
|
static const MethodChannel _sharedChannel =
|
||||||
const MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser');
|
const MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser');
|
||||||
|
|
||||||
|
@ -46,7 +45,9 @@ class ChromeSafariBrowser {
|
||||||
String url = call.arguments["url"];
|
String url = call.arguments["url"];
|
||||||
String title = call.arguments["title"];
|
String title = call.arguments["title"];
|
||||||
int id = call.arguments["id"].toInt();
|
int id = call.arguments["id"].toInt();
|
||||||
this._menuItems[id].action(url, title);
|
if (this._menuItems[id] != null) {
|
||||||
|
this._menuItems[id]!.action(url, title);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw UnimplementedError("Unimplemented ${call.method} method");
|
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||||
|
@ -65,14 +66,14 @@ class ChromeSafariBrowser {
|
||||||
///
|
///
|
||||||
///[contextMenuFallback]: Context Menu used by the [InAppBrowser] instance fallback.
|
///[contextMenuFallback]: Context Menu used by the [InAppBrowser] instance fallback.
|
||||||
Future<void> open(
|
Future<void> open(
|
||||||
{@required String url,
|
{required String url,
|
||||||
ChromeSafariBrowserClassOptions options,
|
ChromeSafariBrowserClassOptions? options,
|
||||||
Map<String, String> headersFallback = const {},
|
Map<String, String>? headersFallback = const {},
|
||||||
InAppBrowserClassOptions optionsFallback}) async {
|
InAppBrowserClassOptions? optionsFallback}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
|
|
||||||
List<Map<String, dynamic>> menuItemList = new List();
|
List<Map<String, dynamic>> menuItemList = [];
|
||||||
_menuItems.forEach((key, value) {
|
_menuItems.forEach((key, value) {
|
||||||
menuItemList.add({"id": value.id, "label": value.label});
|
menuItemList.add({"id": value.id, "label": value.label});
|
||||||
});
|
});
|
||||||
|
@ -160,7 +161,7 @@ class ChromeSafariBrowserMenuItem {
|
||||||
final void Function(String url, String title) action;
|
final void Function(String url, String title) action;
|
||||||
|
|
||||||
ChromeSafariBrowserMenuItem(
|
ChromeSafariBrowserMenuItem(
|
||||||
{@required this.id, @required this.label, @required this.action});
|
{required this.id, required this.label, required this.action});
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {"id": id, "label": label};
|
return {"id": id, "label": label};
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ContentBlocker {
|
||||||
///Action associated to the trigger. The action tells to the WebView what to do when the trigger is matched.
|
///Action associated to the trigger. The action tells to the WebView what to do when the trigger is matched.
|
||||||
ContentBlockerAction action;
|
ContentBlockerAction action;
|
||||||
|
|
||||||
ContentBlocker({@required this.trigger, @required this.action});
|
ContentBlocker({required this.trigger, required this.action});
|
||||||
|
|
||||||
Map<String, Map<String, dynamic>> toMap() {
|
Map<String, Map<String, dynamic>> toMap() {
|
||||||
return {"trigger": trigger.toMap(), "action": action.toMap()};
|
return {"trigger": trigger.toMap(), "action": action.toMap()};
|
||||||
|
@ -24,9 +24,9 @@ class ContentBlocker {
|
||||||
static ContentBlocker fromMap(Map<dynamic, Map<dynamic, dynamic>> map) {
|
static ContentBlocker fromMap(Map<dynamic, Map<dynamic, dynamic>> map) {
|
||||||
return ContentBlocker(
|
return ContentBlocker(
|
||||||
trigger: ContentBlockerTrigger.fromMap(
|
trigger: ContentBlockerTrigger.fromMap(
|
||||||
Map<String, dynamic>.from(map["trigger"])),
|
Map<String, dynamic>.from(map["trigger"]!)),
|
||||||
action: ContentBlockerAction.fromMap(
|
action: ContentBlockerAction.fromMap(
|
||||||
Map<String, dynamic>.from(map["action"])));
|
Map<String, dynamic>.from(map["action"]!)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,36 +36,36 @@ class ContentBlocker {
|
||||||
///For example, you can limit the trigger to specific domains or have it not apply when a match is found on a specific domain.
|
///For example, you can limit the trigger to specific domains or have it not apply when a match is found on a specific domain.
|
||||||
class ContentBlockerTrigger {
|
class ContentBlockerTrigger {
|
||||||
///A regular expression pattern to match the URL against.
|
///A regular expression pattern to match the URL against.
|
||||||
String urlFilter;
|
late String urlFilter;
|
||||||
|
|
||||||
///Used only by iOS. A Boolean value. The default value is false.
|
///Used only by iOS. A Boolean value. The default value is false.
|
||||||
bool urlFilterIsCaseSensitive;
|
late bool urlFilterIsCaseSensitive;
|
||||||
|
|
||||||
///A list of [ContentBlockerTriggerResourceType] representing the resource types (how the browser intends to use the resource) that the rule should match.
|
///A list of [ContentBlockerTriggerResourceType] representing the resource types (how the browser intends to use the resource) that the rule should match.
|
||||||
///If not specified, the rule matches all resource types.
|
///If not specified, the rule matches all resource types.
|
||||||
List<ContentBlockerTriggerResourceType> resourceType;
|
late List<ContentBlockerTriggerResourceType> resourceType;
|
||||||
|
|
||||||
///A list of strings matched to a URL's domain; limits action to a list of specific domains.
|
///A list of strings matched to a URL's domain; limits action to a list of specific domains.
|
||||||
///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.unlessDomain].
|
///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.unlessDomain].
|
||||||
List<String> ifDomain;
|
late List<String> ifDomain;
|
||||||
|
|
||||||
///A list of strings matched to a URL's domain; acts on any site except domains in a provided list.
|
///A list of strings matched to a URL's domain; acts on any site except domains in a provided list.
|
||||||
///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.ifDomain].
|
///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.ifDomain].
|
||||||
List<String> unlessDomain;
|
late List<String> unlessDomain;
|
||||||
|
|
||||||
///A list of [ContentBlockerTriggerLoadType] that can include one of two mutually exclusive values. If not specified, the rule matches all load types.
|
///A list of [ContentBlockerTriggerLoadType] that can include one of two mutually exclusive values. If not specified, the rule matches all load types.
|
||||||
List<ContentBlockerTriggerLoadType> loadType;
|
late List<ContentBlockerTriggerLoadType> loadType;
|
||||||
|
|
||||||
///A list of strings matched to the entire main document URL; limits the action to a specific list of URL patterns.
|
///A list of strings matched to the entire main document URL; limits the action to a specific list of URL patterns.
|
||||||
///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.unlessTopUrl].
|
///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.unlessTopUrl].
|
||||||
List<String> ifTopUrl;
|
late List<String> ifTopUrl;
|
||||||
|
|
||||||
///An array of strings matched to the entire main document URL; acts on any site except URL patterns in provided list.
|
///An array of strings matched to the entire main document URL; acts on any site except URL patterns in provided list.
|
||||||
///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.ifTopUrl].
|
///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.ifTopUrl].
|
||||||
List<String> unlessTopUrl;
|
late List<String> unlessTopUrl;
|
||||||
|
|
||||||
ContentBlockerTrigger(
|
ContentBlockerTrigger(
|
||||||
{@required String urlFilter,
|
{required String urlFilter,
|
||||||
bool urlFilterIsCaseSensitive = false,
|
bool urlFilterIsCaseSensitive = false,
|
||||||
List<ContentBlockerTriggerResourceType> resourceType = const [],
|
List<ContentBlockerTriggerResourceType> resourceType = const [],
|
||||||
List<String> ifDomain = const [],
|
List<String> ifDomain = const [],
|
||||||
|
@ -74,7 +74,6 @@ class ContentBlockerTrigger {
|
||||||
List<String> ifTopUrl = const [],
|
List<String> ifTopUrl = const [],
|
||||||
List<String> unlessTopUrl = const []}) {
|
List<String> unlessTopUrl = const []}) {
|
||||||
this.urlFilter = urlFilter;
|
this.urlFilter = urlFilter;
|
||||||
assert(this.urlFilter != null);
|
|
||||||
this.resourceType = resourceType;
|
this.resourceType = resourceType;
|
||||||
this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive;
|
this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive;
|
||||||
this.ifDomain = ifDomain;
|
this.ifDomain = ifDomain;
|
||||||
|
@ -124,13 +123,19 @@ class ContentBlockerTrigger {
|
||||||
|
|
||||||
List<String> resourceTypeStringList =
|
List<String> resourceTypeStringList =
|
||||||
List<String>.from(map["resource-type"] ?? []);
|
List<String>.from(map["resource-type"] ?? []);
|
||||||
resourceTypeStringList.forEach((type) {
|
resourceTypeStringList.forEach((typeValue) {
|
||||||
resourceType.add(ContentBlockerTriggerResourceType.fromValue(type));
|
var type = ContentBlockerTriggerResourceType.fromValue(typeValue);
|
||||||
|
if (type != null) {
|
||||||
|
resourceType.add(type);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
List<String> loadTypeStringList = List<String>.from(map["load-type"] ?? []);
|
List<String> loadTypeStringList = List<String>.from(map["load-type"] ?? []);
|
||||||
loadTypeStringList.forEach((type) {
|
loadTypeStringList.forEach((typeValue) {
|
||||||
loadType.add(ContentBlockerTriggerLoadType.fromValue(type));
|
var type = ContentBlockerTriggerLoadType.fromValue(typeValue);
|
||||||
|
if (type != null) {
|
||||||
|
loadType.add(type);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ContentBlockerTrigger(
|
return ContentBlockerTrigger(
|
||||||
|
@ -152,16 +157,15 @@ class ContentBlockerTrigger {
|
||||||
///Group the rules with similar actions together to improve performance.
|
///Group the rules with similar actions together to improve performance.
|
||||||
class ContentBlockerAction {
|
class ContentBlockerAction {
|
||||||
///Type of the action.
|
///Type of the action.
|
||||||
ContentBlockerActionType type;
|
late ContentBlockerActionType type;
|
||||||
|
|
||||||
///If the action type is [ContentBlockerActionType.CSS_DISPLAY_NONE], then also the [selector] property is required, otherwise it is ignored.
|
///If the action type is [ContentBlockerActionType.CSS_DISPLAY_NONE], then also the [selector] property is required, otherwise it is ignored.
|
||||||
///It specify a string that defines a selector list. Use CSS identifiers as the individual selector values, separated by commas.
|
///It specify a string that defines a selector list. Use CSS identifiers as the individual selector values, separated by commas.
|
||||||
String selector;
|
String? selector;
|
||||||
|
|
||||||
ContentBlockerAction(
|
ContentBlockerAction(
|
||||||
{@required ContentBlockerActionType type, String selector}) {
|
{required ContentBlockerActionType type, String? selector}) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
assert(this.type != null);
|
|
||||||
if (this.type == ContentBlockerActionType.CSS_DISPLAY_NONE) {
|
if (this.type == ContentBlockerActionType.CSS_DISPLAY_NONE) {
|
||||||
assert(selector != null);
|
assert(selector != null);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +187,7 @@ class ContentBlockerAction {
|
||||||
|
|
||||||
static ContentBlockerAction fromMap(Map<String, dynamic> map) {
|
static ContentBlockerAction fromMap(Map<String, dynamic> map) {
|
||||||
return ContentBlockerAction(
|
return ContentBlockerAction(
|
||||||
type: ContentBlockerActionType.fromValue(map["type"]),
|
type: ContentBlockerActionType.fromValue(map["type"])!,
|
||||||
selector: map["selector"]);
|
selector: map["selector"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,20 @@ class ContextMenu {
|
||||||
///Event fired when the context menu for this WebView is being built.
|
///Event fired when the context menu for this WebView is being built.
|
||||||
///
|
///
|
||||||
///[hitTestResult] represents the hit result for hitting an HTML elements.
|
///[hitTestResult] represents the hit result for hitting an HTML elements.
|
||||||
final void Function(InAppWebViewHitTestResult hitTestResult)
|
final void Function(InAppWebViewHitTestResult hitTestResult)?
|
||||||
onCreateContextMenu;
|
onCreateContextMenu;
|
||||||
|
|
||||||
///Event fired when the context menu for this WebView is being hidden.
|
///Event fired when the context menu for this WebView is being hidden.
|
||||||
final void Function() onHideContextMenu;
|
final void Function()? onHideContextMenu;
|
||||||
|
|
||||||
///Event fired when a context menu item has been clicked.
|
///Event fired when a context menu item has been clicked.
|
||||||
///
|
///
|
||||||
///[contextMenuItemClicked] represents the [ContextMenuItem] clicked.
|
///[contextMenuItemClicked] represents the [ContextMenuItem] clicked.
|
||||||
final void Function(ContextMenuItem contextMenuItemClicked)
|
final void Function(ContextMenuItem contextMenuItemClicked)?
|
||||||
onContextMenuActionItemClicked;
|
onContextMenuActionItemClicked;
|
||||||
|
|
||||||
///Context menu options.
|
///Context menu options.
|
||||||
final ContextMenuOptions options;
|
final ContextMenuOptions? options;
|
||||||
|
|
||||||
///List of the custom [ContextMenuItem].
|
///List of the custom [ContextMenuItem].
|
||||||
final List<ContextMenuItem> menuItems;
|
final List<ContextMenuItem> menuItems;
|
||||||
|
@ -33,12 +33,11 @@ class ContextMenu {
|
||||||
this.onCreateContextMenu,
|
this.onCreateContextMenu,
|
||||||
this.onHideContextMenu,
|
this.onHideContextMenu,
|
||||||
this.options,
|
this.options,
|
||||||
this.onContextMenuActionItemClicked})
|
this.onContextMenuActionItemClicked});
|
||||||
: assert(menuItems != null);
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {
|
return {
|
||||||
"menuItems": menuItems.map((menuItem) => menuItem?.toMap()).toList(),
|
"menuItems": menuItems.map((menuItem) => menuItem.toMap()).toList(),
|
||||||
"options": options?.toMap()
|
"options": options?.toMap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -56,21 +55,21 @@ class ContextMenu {
|
||||||
///Class that represent an item of the [ContextMenu].
|
///Class that represent an item of the [ContextMenu].
|
||||||
class ContextMenuItem {
|
class ContextMenuItem {
|
||||||
///Android menu item ID.
|
///Android menu item ID.
|
||||||
int androidId;
|
int? androidId;
|
||||||
|
|
||||||
///iOS menu item ID.
|
///iOS menu item ID.
|
||||||
String iosId;
|
String? iosId;
|
||||||
|
|
||||||
///Menu item title.
|
///Menu item title.
|
||||||
String title;
|
String title;
|
||||||
|
|
||||||
///Menu item action that will be called when an user clicks on it.
|
///Menu item action that will be called when an user clicks on it.
|
||||||
Function() action;
|
Function()? action;
|
||||||
|
|
||||||
ContextMenuItem(
|
ContextMenuItem(
|
||||||
{@required this.androidId,
|
{this.androidId,
|
||||||
@required this.iosId,
|
this.iosId,
|
||||||
@required this.title,
|
required this.title,
|
||||||
this.action});
|
this.action});
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
|
@ -11,19 +10,19 @@ import 'types.dart';
|
||||||
///
|
///
|
||||||
///**NOTE for iOS**: available from iOS 11.0+.
|
///**NOTE for iOS**: available from iOS 11.0+.
|
||||||
class CookieManager {
|
class CookieManager {
|
||||||
static CookieManager _instance;
|
static CookieManager? _instance;
|
||||||
static const MethodChannel _channel = const MethodChannel(
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_cookiemanager');
|
'com.pichillilorenzo/flutter_inappwebview_cookiemanager');
|
||||||
|
|
||||||
///Gets the cookie manager shared instance.
|
///Gets the cookie manager shared instance.
|
||||||
static CookieManager instance() {
|
static CookieManager instance() {
|
||||||
return (_instance != null) ? _instance : _init();
|
return (_instance != null) ? _instance! : _init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static CookieManager _init() {
|
static CookieManager _init() {
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
_instance = CookieManager();
|
_instance = CookieManager();
|
||||||
return _instance;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
||||||
|
@ -33,23 +32,23 @@ class CookieManager {
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null`, its default value will be the domain name of [url].
|
///If [domain] is `null`, its default value will be the domain name of [url].
|
||||||
Future<void> setCookie(
|
Future<void> setCookie(
|
||||||
{@required String url,
|
{required String url,
|
||||||
@required String name,
|
required String name,
|
||||||
@required String value,
|
required String value,
|
||||||
String domain,
|
String? domain,
|
||||||
String path = "/",
|
String path = "/",
|
||||||
int expiresDate,
|
int? expiresDate,
|
||||||
int maxAge,
|
int? maxAge,
|
||||||
bool isSecure,
|
bool? isSecure,
|
||||||
bool isHttpOnly,
|
bool? isHttpOnly,
|
||||||
HTTPCookieSameSitePolicy sameSite}) async {
|
HTTPCookieSameSitePolicy? sameSite}) async {
|
||||||
if (domain == null) domain = _getDomainName(url);
|
if (domain == null) domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name.isNotEmpty);
|
||||||
assert(value != null && value.isNotEmpty);
|
assert(value.isNotEmpty);
|
||||||
assert(domain != null && domain.isNotEmpty);
|
assert(domain.isNotEmpty);
|
||||||
assert(path != null && path.isNotEmpty);
|
assert(path.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
|
@ -67,8 +66,8 @@ class CookieManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets all the cookies for the given [url].
|
///Gets all the cookies for the given [url].
|
||||||
Future<List<Cookie>> getCookies({@required String url}) async {
|
Future<List<Cookie>> getCookies({required String url}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
|
@ -94,10 +93,10 @@ class CookieManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets a cookie by its [name] for the given [url].
|
///Gets a cookie by its [name] for the given [url].
|
||||||
Future<Cookie> getCookie(
|
Future<Cookie?> getCookie(
|
||||||
{@required String url, @required String name}) async {
|
{required String url, required String name}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
|
@ -126,16 +125,16 @@ class CookieManager {
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
||||||
Future<void> deleteCookie(
|
Future<void> deleteCookie(
|
||||||
{@required String url,
|
{required String url,
|
||||||
@required String name,
|
required String name,
|
||||||
String domain = "",
|
String domain = "",
|
||||||
String path = "/"}) async {
|
String path = "/"}) async {
|
||||||
if (domain == null || domain.isEmpty) domain = _getDomainName(url);
|
if (domain.isEmpty) domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name.isNotEmpty);
|
||||||
assert(domain != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(path != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
|
@ -150,12 +149,12 @@ class CookieManager {
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
||||||
Future<void> deleteCookies(
|
Future<void> deleteCookies(
|
||||||
{@required String url, String domain = "", String path = "/"}) async {
|
{required String url, String domain = "", String path = "/"}) async {
|
||||||
if (domain == null || domain.isEmpty) domain = _getDomainName(url);
|
if (domain.isEmpty) domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(domain != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
assert(path != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
|
@ -173,6 +172,7 @@ class CookieManager {
|
||||||
String _getDomainName(String url) {
|
String _getDomainName(String url) {
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(url);
|
||||||
String domain = uri.host;
|
String domain = uri.host;
|
||||||
|
// ignore: unnecessary_null_comparison
|
||||||
if (domain == null) return "";
|
if (domain == null) return "";
|
||||||
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,16 @@ import 'in_app_webview_controller.dart';
|
||||||
///
|
///
|
||||||
///Remember to dispose it when you don't need it anymore.
|
///Remember to dispose it when you don't need it anymore.
|
||||||
class HeadlessInAppWebView implements WebView {
|
class HeadlessInAppWebView implements WebView {
|
||||||
String uuid;
|
late String uuid;
|
||||||
bool _isDisposed = true;
|
bool _isDisposed = true;
|
||||||
static const MethodChannel _sharedChannel =
|
static const MethodChannel _sharedChannel =
|
||||||
const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
||||||
|
|
||||||
///WebView Controller that can be used to access the [InAppWebViewController] API.
|
///WebView Controller that can be used to access the [InAppWebViewController] API.
|
||||||
InAppWebViewController webViewController;
|
late InAppWebViewController webViewController;
|
||||||
|
|
||||||
///The window id of a [CreateWindowRequest.windowId].
|
///The window id of a [CreateWindowRequest.windowId].
|
||||||
final int windowId;
|
final int? windowId;
|
||||||
|
|
||||||
HeadlessInAppWebView(
|
HeadlessInAppWebView(
|
||||||
{this.windowId,
|
{this.windowId,
|
||||||
|
@ -89,7 +89,9 @@ class HeadlessInAppWebView implements WebView {
|
||||||
Future<dynamic> handleMethod(MethodCall call) async {
|
Future<dynamic> handleMethod(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "onHeadlessWebViewCreated":
|
case "onHeadlessWebViewCreated":
|
||||||
onWebViewCreated(webViewController);
|
if (onWebViewCreated != null) {
|
||||||
|
onWebViewCreated!(webViewController);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return webViewController.handleMethod(call);
|
return webViewController.handleMethod(call);
|
||||||
|
@ -107,12 +109,13 @@ class HeadlessInAppWebView implements WebView {
|
||||||
args.putIfAbsent(
|
args.putIfAbsent(
|
||||||
'params',
|
'params',
|
||||||
() => <String, dynamic>{
|
() => <String, dynamic>{
|
||||||
'initialUrl': '${Uri.parse(this.initialUrl)}',
|
'initialUrl': this.initialUrl != null ? '${Uri.parse(this.initialUrl!)}' : '',
|
||||||
'initialFile': this.initialFile,
|
'initialFile': this.initialFile,
|
||||||
'initialData': this.initialData?.toMap(),
|
'initialData': this.initialData?.toMap(),
|
||||||
'initialHeaders': this.initialHeaders,
|
'initialHeaders': this.initialHeaders,
|
||||||
'initialOptions': this.initialOptions?.toMap() ?? {},
|
'initialOptions': this.initialOptions?.toMap() ?? {},
|
||||||
'contextMenu': this.contextMenu?.toMap() ?? {}
|
'contextMenu': this.contextMenu?.toMap() ?? {},
|
||||||
|
'windowId': this.windowId
|
||||||
});
|
});
|
||||||
await _sharedChannel.invokeMethod('createHeadlessWebView', args);
|
await _sharedChannel.invokeMethod('createHeadlessWebView', args);
|
||||||
}
|
}
|
||||||
|
@ -129,242 +132,242 @@ class HeadlessInAppWebView implements WebView {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
androidOnGeolocationPermissionsHidePrompt;
|
androidOnGeolocationPermissionsHidePrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<GeolocationPermissionShowPromptResponse> Function(
|
final Future<GeolocationPermissionShowPromptResponse?> Function(
|
||||||
InAppWebViewController controller, String origin)
|
InAppWebViewController controller, String origin)?
|
||||||
androidOnGeolocationPermissionsShowPrompt;
|
androidOnGeolocationPermissionsShowPrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<PermissionRequestResponse> Function(
|
final Future<PermissionRequestResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
String origin,
|
String origin,
|
||||||
List<String> resources) androidOnPermissionRequest;
|
List<String> resources)? androidOnPermissionRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<SafeBrowsingResponse> Function(InAppWebViewController controller,
|
final Future<SafeBrowsingResponse?> Function(InAppWebViewController controller,
|
||||||
String url, SafeBrowsingThreat threatType) androidOnSafeBrowsingHit;
|
String url, SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final InAppWebViewInitialData initialData;
|
final InAppWebViewInitialData? initialData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String initialFile;
|
final String? initialFile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Map<String, String> initialHeaders;
|
final Map<String, String>? initialHeaders;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final InAppWebViewGroupOptions initialOptions;
|
final InAppWebViewGroupOptions? initialOptions;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final ContextMenu contextMenu;
|
final ContextMenu? contextMenu;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String initialUrl;
|
final String? initialUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onPageCommitVisible;
|
onPageCommitVisible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String title)
|
final void Function(InAppWebViewController controller, String? title)?
|
||||||
onTitleChanged;
|
onTitleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnWebContentProcessDidTerminate;
|
iosOnWebContentProcessDidTerminate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxProgress;
|
onAjaxProgress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxReadyStateChange;
|
onAjaxReadyStateChange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, ConsoleMessage consoleMessage)
|
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
||||||
onConsoleMessage;
|
onConsoleMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<bool> Function(InAppWebViewController controller,
|
final Future<bool?> Function(InAppWebViewController controller,
|
||||||
CreateWindowRequest createWindowRequest) onCreateWindow;
|
CreateWindowRequest createWindowRequest)? onCreateWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onCloseWindow;
|
final void Function(InAppWebViewController controller)? onCloseWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWindowFocus;
|
final void Function(InAppWebViewController controller)? onWindowFocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWindowBlur;
|
final void Function(InAppWebViewController controller)? onWindowBlur;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) androidOnRequestFocus;
|
final void Function(InAppWebViewController controller)? androidOnRequestFocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String url)?
|
||||||
onDownloadStart;
|
onDownloadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||||
int numberOfMatches, bool isDoneCounting) onFindResultReceived;
|
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsAlertResponse> Function(
|
final Future<JsAlertResponse?> Function(
|
||||||
InAppWebViewController controller, JsAlertRequest jsAlertRequest)
|
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
||||||
onJsAlert;
|
onJsAlert;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsConfirmResponse> Function(
|
final Future<JsConfirmResponse?> Function(
|
||||||
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)
|
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
||||||
onJsConfirm;
|
onJsConfirm;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsPromptResponse> Function(
|
final Future<JsPromptResponse?> Function(
|
||||||
InAppWebViewController controller, JsPromptRequest jsPromptRequest)
|
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
||||||
onJsPrompt;
|
onJsPrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url, int code,
|
final void Function(InAppWebViewController controller, String? url, int code,
|
||||||
String message) onLoadError;
|
String message)? onLoadError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url,
|
final void Function(InAppWebViewController controller, String? url,
|
||||||
int statusCode, String description) onLoadHttpError;
|
int statusCode, String description)? onLoadHttpError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoadedResource resource)
|
InAppWebViewController controller, LoadedResource resource)?
|
||||||
onLoadResource;
|
onLoadResource;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<CustomSchemeResponse> Function(
|
final Future<CustomSchemeResponse?> Function(
|
||||||
InAppWebViewController controller, String scheme, String url)
|
InAppWebViewController controller, String scheme, String url)?
|
||||||
onLoadResourceCustomScheme;
|
onLoadResourceCustomScheme;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onLoadStart;
|
onLoadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url) onLoadStop;
|
final void Function(InAppWebViewController controller, String? url)? onLoadStop;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller,
|
final void Function(InAppWebViewController controller,
|
||||||
InAppWebViewHitTestResult hitTestResult) onLongPressHitTestResult;
|
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url) onPrint;
|
final void Function(InAppWebViewController controller, String? url)? onPrint;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int progress)
|
final void Function(InAppWebViewController controller, int progress)?
|
||||||
onProgressChanged;
|
onProgressChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ClientCertResponse> Function(
|
final Future<ClientCertResponse?> Function(
|
||||||
InAppWebViewController controller, ClientCertChallenge challenge)
|
InAppWebViewController controller, ClientCertChallenge challenge)?
|
||||||
onReceivedClientCertRequest;
|
onReceivedClientCertRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<HttpAuthResponse> Function(
|
final Future<HttpAuthResponse?> Function(
|
||||||
InAppWebViewController controller, HttpAuthChallenge challenge)
|
InAppWebViewController controller, HttpAuthChallenge challenge)?
|
||||||
onReceivedHttpAuthRequest;
|
onReceivedHttpAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ServerTrustAuthResponse> Function(
|
final Future<ServerTrustAuthResponse?> Function(
|
||||||
InAppWebViewController controller, ServerTrustChallenge challenge)
|
InAppWebViewController controller, ServerTrustChallenge challenge)?
|
||||||
onReceivedServerTrustAuthRequest;
|
onReceivedServerTrustAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int x, int y)
|
final void Function(InAppWebViewController controller, int x, int y)?
|
||||||
onScrollChanged;
|
onScrollChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool androidIsReload)
|
InAppWebViewController controller, String? url, bool? androidIsReload)?
|
||||||
onUpdateVisitedHistory;
|
onUpdateVisitedHistory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWebViewCreated;
|
final void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequest> Function(
|
final Future<AjaxRequest?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
shouldInterceptAjaxRequest;
|
shouldInterceptAjaxRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FetchRequest> Function(
|
final Future<FetchRequest?> Function(
|
||||||
InAppWebViewController controller, FetchRequest fetchRequest)
|
InAppWebViewController controller, FetchRequest fetchRequest)?
|
||||||
shouldInterceptFetchRequest;
|
shouldInterceptFetchRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ShouldOverrideUrlLoadingAction> Function(
|
final Future<ShouldOverrideUrlLoadingAction?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)
|
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)?
|
||||||
shouldOverrideUrlLoading;
|
shouldOverrideUrlLoading;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onEnterFullscreen;
|
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onExitFullscreen;
|
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebResourceResponse> Function(
|
final Future<WebResourceResponse?> Function(
|
||||||
InAppWebViewController controller, WebResourceRequest request)
|
InAppWebViewController controller, WebResourceRequest request)?
|
||||||
androidShouldInterceptRequest;
|
androidShouldInterceptRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessUnresponsive;
|
androidOnRenderProcessUnresponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessResponsive;
|
androidOnRenderProcessResponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, RenderProcessGoneDetail detail)
|
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
||||||
androidOnRenderProcessGone;
|
androidOnRenderProcessGone;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FormResubmissionAction> Function(
|
final Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, String url) androidOnFormResubmission;
|
InAppWebViewController controller, String? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
androidOnScaleChanged;
|
androidOnScaleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uint8List icon)
|
final void Function(InAppWebViewController controller, Uint8List icon)?
|
||||||
androidOnReceivedIcon;
|
androidOnReceivedIcon;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool precomposed)
|
InAppWebViewController controller, String url, bool precomposed)?
|
||||||
androidOnReceivedTouchIconUrl;
|
androidOnReceivedTouchIconUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsBeforeUnloadResponse> Function(
|
final Future<JsBeforeUnloadResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
JsBeforeUnloadRequest jsBeforeUnloadRequest) androidOnJsBeforeUnload;
|
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoginRequest loginRequest)
|
InAppWebViewController controller, LoginRequest loginRequest)?
|
||||||
androidOnReceivedLoginRequest;
|
androidOnReceivedLoginRequest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
@ -11,19 +9,19 @@ import 'package:flutter/services.dart';
|
||||||
///[WebViewDatabase](https://developer.android.com/reference/android/webkit/WebViewDatabase)
|
///[WebViewDatabase](https://developer.android.com/reference/android/webkit/WebViewDatabase)
|
||||||
///doesn't offer the same functionalities as iOS `URLCredentialStorage`.
|
///doesn't offer the same functionalities as iOS `URLCredentialStorage`.
|
||||||
class HttpAuthCredentialDatabase {
|
class HttpAuthCredentialDatabase {
|
||||||
static HttpAuthCredentialDatabase _instance;
|
static HttpAuthCredentialDatabase? _instance;
|
||||||
static const MethodChannel _channel = const MethodChannel(
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_credential_database');
|
'com.pichillilorenzo/flutter_inappwebview_credential_database');
|
||||||
|
|
||||||
///Gets the database shared instance.
|
///Gets the database shared instance.
|
||||||
static HttpAuthCredentialDatabase instance() {
|
static HttpAuthCredentialDatabase instance() {
|
||||||
return (_instance != null) ? _instance : _init();
|
return (_instance != null) ? _instance! : _init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static HttpAuthCredentialDatabase _init() {
|
static HttpAuthCredentialDatabase _init() {
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
_instance = HttpAuthCredentialDatabase();
|
_instance = HttpAuthCredentialDatabase();
|
||||||
return _instance;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
||||||
|
@ -59,7 +57,7 @@ class HttpAuthCredentialDatabase {
|
||||||
|
|
||||||
///Gets all the HTTP auth credentials saved for that [protectionSpace].
|
///Gets all the HTTP auth credentials saved for that [protectionSpace].
|
||||||
Future<List<HttpAuthCredential>> getHttpAuthCredentials(
|
Future<List<HttpAuthCredential>> getHttpAuthCredentials(
|
||||||
{@required ProtectionSpace protectionSpace}) async {
|
{required ProtectionSpace protectionSpace}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("host", () => protectionSpace.host);
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
@ -77,8 +75,8 @@ class HttpAuthCredentialDatabase {
|
||||||
|
|
||||||
///Saves an HTTP auth [credential] for that [protectionSpace].
|
///Saves an HTTP auth [credential] for that [protectionSpace].
|
||||||
Future<void> setHttpAuthCredential(
|
Future<void> setHttpAuthCredential(
|
||||||
{@required ProtectionSpace protectionSpace,
|
{required ProtectionSpace protectionSpace,
|
||||||
@required HttpAuthCredential credential}) async {
|
required HttpAuthCredential credential}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("host", () => protectionSpace.host);
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
@ -91,8 +89,8 @@ class HttpAuthCredentialDatabase {
|
||||||
|
|
||||||
///Removes an HTTP auth [credential] for that [protectionSpace].
|
///Removes an HTTP auth [credential] for that [protectionSpace].
|
||||||
Future<void> removeHttpAuthCredential(
|
Future<void> removeHttpAuthCredential(
|
||||||
{@required ProtectionSpace protectionSpace,
|
{required ProtectionSpace protectionSpace,
|
||||||
@required HttpAuthCredential credential}) async {
|
required HttpAuthCredential credential}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("host", () => protectionSpace.host);
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
@ -105,7 +103,7 @@ class HttpAuthCredentialDatabase {
|
||||||
|
|
||||||
///Removes all the HTTP auth credentials saved for that [protectionSpace].
|
///Removes all the HTTP auth credentials saved for that [protectionSpace].
|
||||||
Future<void> removeHttpAuthCredentials(
|
Future<void> removeHttpAuthCredentials(
|
||||||
{@required ProtectionSpace protectionSpace}) async {
|
{required ProtectionSpace protectionSpace}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("host", () => protectionSpace.host);
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
import 'context_menu.dart';
|
import 'context_menu.dart';
|
||||||
|
@ -15,23 +14,23 @@ import 'types.dart';
|
||||||
///The [webViewController] field can be used to access the [InAppWebViewController] API.
|
///The [webViewController] field can be used to access the [InAppWebViewController] API.
|
||||||
class InAppBrowser {
|
class InAppBrowser {
|
||||||
///Browser's UUID.
|
///Browser's UUID.
|
||||||
String uuid;
|
late String uuid;
|
||||||
|
|
||||||
///Context menu used by the browser. It should be set before opening the browser.
|
///Context menu used by the browser. It should be set before opening the browser.
|
||||||
ContextMenu contextMenu;
|
ContextMenu? contextMenu;
|
||||||
|
|
||||||
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
|
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
|
||||||
HashMap<String, JavaScriptHandlerCallback>();
|
HashMap<String, JavaScriptHandlerCallback>();
|
||||||
bool _isOpened = false;
|
bool _isOpened = false;
|
||||||
MethodChannel _channel;
|
late MethodChannel _channel;
|
||||||
static const MethodChannel _sharedChannel =
|
static const MethodChannel _sharedChannel =
|
||||||
const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
||||||
|
|
||||||
/// WebView Controller that can be used to access the [InAppWebViewController] API.
|
/// WebView Controller that can be used to access the [InAppWebViewController] API.
|
||||||
InAppWebViewController webViewController;
|
late InAppWebViewController webViewController;
|
||||||
|
|
||||||
///The window id of a [CreateWindowRequest.windowId].
|
///The window id of a [CreateWindowRequest.windowId].
|
||||||
final int windowId;
|
final int? windowId;
|
||||||
|
|
||||||
///
|
///
|
||||||
InAppBrowser({this.windowId}) {
|
InAppBrowser({this.windowId}) {
|
||||||
|
@ -67,10 +66,10 @@ class InAppBrowser {
|
||||||
///
|
///
|
||||||
///[options]: Options for the [InAppBrowser].
|
///[options]: Options for the [InAppBrowser].
|
||||||
Future<void> openUrl(
|
Future<void> openUrl(
|
||||||
{@required String url,
|
{required String url,
|
||||||
Map<String, String> headers = const {},
|
Map<String, String> headers = const {},
|
||||||
InAppBrowserClassOptions options}) async {
|
InAppBrowserClassOptions? options}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -117,10 +116,10 @@ class InAppBrowser {
|
||||||
///
|
///
|
||||||
///[options]: Options for the [InAppBrowser].
|
///[options]: Options for the [InAppBrowser].
|
||||||
Future<void> openFile(
|
Future<void> openFile(
|
||||||
{@required String assetFilePath,
|
{required String assetFilePath,
|
||||||
Map<String, String> headers = const {},
|
Map<String, String> headers = const {},
|
||||||
InAppBrowserClassOptions options}) async {
|
InAppBrowserClassOptions? options}) async {
|
||||||
assert(assetFilePath != null && assetFilePath.isNotEmpty);
|
assert(assetFilePath.isNotEmpty);
|
||||||
this.throwIsAlreadyOpened(message: 'Cannot open $assetFilePath!');
|
this.throwIsAlreadyOpened(message: 'Cannot open $assetFilePath!');
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -143,14 +142,12 @@ class InAppBrowser {
|
||||||
///
|
///
|
||||||
///The [options] parameter specifies the options for the [InAppBrowser].
|
///The [options] parameter specifies the options for the [InAppBrowser].
|
||||||
Future<void> openData(
|
Future<void> openData(
|
||||||
{@required String data,
|
{required String data,
|
||||||
String mimeType = "text/html",
|
String mimeType = "text/html",
|
||||||
String encoding = "utf8",
|
String encoding = "utf8",
|
||||||
String baseUrl = "about:blank",
|
String baseUrl = "about:blank",
|
||||||
String androidHistoryUrl = "about:blank",
|
String androidHistoryUrl = "about:blank",
|
||||||
InAppBrowserClassOptions options}) async {
|
InAppBrowserClassOptions? options}) async {
|
||||||
assert(data != null);
|
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
||||||
|
@ -165,8 +162,8 @@ class InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
///This is a static method that opens an [url] in the system browser. You wont be able to use the [InAppBrowser] methods here!
|
///This is a static method that opens an [url] in the system browser. You wont be able to use the [InAppBrowser] methods here!
|
||||||
static Future<void> openWithSystemBrowser({@required String url}) async {
|
static Future<void> openWithSystemBrowser({required String url}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url.isNotEmpty);
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
return await _sharedChannel.invokeMethod('openWithSystemBrowser', args);
|
return await _sharedChannel.invokeMethod('openWithSystemBrowser', args);
|
||||||
|
@ -202,24 +199,24 @@ class InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Sets the [InAppBrowser] options with the new [options] and evaluates them.
|
///Sets the [InAppBrowser] options with the new [options] and evaluates them.
|
||||||
Future<void> setOptions({@required InAppBrowserClassOptions options}) async {
|
Future<void> setOptions({required InAppBrowserClassOptions options}) async {
|
||||||
this.throwIsNotOpened();
|
this.throwIsNotOpened();
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
args.putIfAbsent('options', () => options.toMap());
|
||||||
await _channel.invokeMethod('setOptions', args);
|
await _channel.invokeMethod('setOptions', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the current [InAppBrowser] options. Returns `null` if it wasn't able to get them.
|
///Gets the current [InAppBrowser] options. Returns `null` if it wasn't able to get them.
|
||||||
Future<InAppBrowserClassOptions> getOptions() async {
|
Future<InAppBrowserClassOptions?> getOptions() async {
|
||||||
this.throwIsNotOpened();
|
this.throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
|
||||||
Map<dynamic, dynamic> options =
|
Map<dynamic, dynamic>? options =
|
||||||
await _channel.invokeMethod('getOptions', args);
|
await _channel.invokeMethod('getOptions', args);
|
||||||
if (options != null) {
|
if (options != null) {
|
||||||
options = options.cast<String, dynamic>();
|
options = options.cast<String, dynamic>();
|
||||||
return InAppBrowserClassOptions.fromMap(options);
|
return InAppBrowserClassOptions.fromMap(options as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -241,21 +238,21 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview
|
||||||
void onLoadStart(String url) {}
|
void onLoadStart(String? url) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] finishes loading an [url].
|
///Event fired when the [InAppBrowser] finishes loading an [url].
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
|
||||||
void onLoadStop(String url) {}
|
void onLoadStop(String? url) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] encounters an error loading an [url].
|
///Event fired when the [InAppBrowser] encounters an error loading an [url].
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20int,%20java.lang.String,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20int,%20java.lang.String,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview
|
||||||
void onLoadError(String url, int code, String message) {}
|
void onLoadError(String? url, int code, String message) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] main page receives an HTTP error.
|
///Event fired when the [InAppBrowser] main page receives an HTTP error.
|
||||||
///
|
///
|
||||||
|
@ -270,7 +267,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
||||||
void onLoadHttpError(String url, int statusCode, String description) {}
|
void onLoadHttpError(String? url, int statusCode, String description) {}
|
||||||
|
|
||||||
///Event fired when the current [progress] (range 0-100) of loading a page is changed.
|
///Event fired when the current [progress] (range 0-100) of loading a page is changed.
|
||||||
///
|
///
|
||||||
|
@ -297,8 +294,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview
|
||||||
// ignore: missing_return
|
Future<ShouldOverrideUrlLoadingAction?>? shouldOverrideUrlLoading(
|
||||||
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(
|
|
||||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) {}
|
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] webview loads a resource.
|
///Event fired when the [InAppBrowser] webview loads a resource.
|
||||||
|
@ -335,8 +331,7 @@ class InAppBrowser {
|
||||||
///[url] represents the url of the request.
|
///[url] represents the url of the request.
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkurlschemehandler
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkurlschemehandler
|
||||||
// ignore: missing_return
|
Future<CustomSchemeResponse?>? onLoadResourceCustomScheme(
|
||||||
Future<CustomSchemeResponse> onLoadResourceCustomScheme(
|
|
||||||
String scheme, String url) {}
|
String scheme, String url) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] webview requests the host application to create a new window,
|
///Event fired when the [InAppBrowser] webview requests the host application to create a new window,
|
||||||
|
@ -369,8 +364,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview
|
||||||
// ignore: missing_return
|
Future<bool?>? onCreateWindow(CreateWindowRequest createWindowRequest) {}
|
||||||
Future<bool> onCreateWindow(CreateWindowRequest createWindowRequest) {}
|
|
||||||
|
|
||||||
///Event fired when the host application should close the given WebView and remove it from the view system if necessary.
|
///Event fired when the host application should close the given WebView and remove it from the view system if necessary.
|
||||||
///At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.
|
///At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.
|
||||||
|
@ -396,8 +390,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsAlert(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsAlert(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview
|
||||||
// ignore: missing_return
|
Future<JsAlertResponse?>? onJsAlert(JsAlertRequest jsAlertRequest) {}
|
||||||
Future<JsAlertResponse> onJsAlert(JsAlertRequest jsAlertRequest) {}
|
|
||||||
|
|
||||||
///Event fired when javascript calls the `confirm()` method to display a confirm dialog.
|
///Event fired when javascript calls the `confirm()` method to display a confirm dialog.
|
||||||
///If [JsConfirmResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
///If [JsConfirmResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
||||||
|
@ -407,8 +400,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsConfirm(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsConfirm(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview
|
||||||
// ignore: missing_return
|
Future<JsConfirmResponse?>? onJsConfirm(JsConfirmRequest jsConfirmRequest) {}
|
||||||
Future<JsConfirmResponse> onJsConfirm(JsConfirmRequest jsConfirmRequest) {}
|
|
||||||
|
|
||||||
///Event fired when javascript calls the `prompt()` method to display a prompt dialog.
|
///Event fired when javascript calls the `prompt()` method to display a prompt dialog.
|
||||||
///If [JsPromptResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
///If [JsPromptResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
||||||
|
@ -418,8 +410,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview
|
||||||
// ignore: missing_return
|
Future<JsPromptResponse?>? onJsPrompt(JsPromptRequest jsPromptRequest) {}
|
||||||
Future<JsPromptResponse> onJsPrompt(JsPromptRequest jsPromptRequest) {}
|
|
||||||
|
|
||||||
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
||||||
///
|
///
|
||||||
|
@ -428,8 +419,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
// ignore: missing_return
|
Future<HttpAuthResponse?>? onReceivedHttpAuthRequest(
|
||||||
Future<HttpAuthResponse> onReceivedHttpAuthRequest(
|
|
||||||
HttpAuthChallenge challenge) {}
|
HttpAuthChallenge challenge) {}
|
||||||
|
|
||||||
///Event fired when the WebView need to perform server trust authentication (certificate validation).
|
///Event fired when the WebView need to perform server trust authentication (certificate validation).
|
||||||
|
@ -440,8 +430,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
// ignore: missing_return
|
Future<ServerTrustAuthResponse?>? onReceivedServerTrustAuthRequest(
|
||||||
Future<ServerTrustAuthResponse> onReceivedServerTrustAuthRequest(
|
|
||||||
ServerTrustChallenge challenge) {}
|
ServerTrustChallenge challenge) {}
|
||||||
|
|
||||||
///Notify the host application to handle an SSL client certificate request.
|
///Notify the host application to handle an SSL client certificate request.
|
||||||
|
@ -454,8 +443,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
// ignore: missing_return
|
Future<ClientCertResponse?>? onReceivedClientCertRequest(
|
||||||
Future<ClientCertResponse> onReceivedClientCertRequest(
|
|
||||||
ClientCertChallenge challenge) {}
|
ClientCertChallenge challenge) {}
|
||||||
|
|
||||||
///Event fired as find-on-page operations progress.
|
///Event fired as find-on-page operations progress.
|
||||||
|
@ -477,8 +465,7 @@ class InAppBrowser {
|
||||||
///[ajaxRequest] represents the `XMLHttpRequest`.
|
///[ajaxRequest] represents the `XMLHttpRequest`.
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
||||||
// ignore: missing_return
|
Future<AjaxRequest?>? shouldInterceptAjaxRequest(AjaxRequest ajaxRequest) {}
|
||||||
Future<AjaxRequest> shouldInterceptAjaxRequest(AjaxRequest ajaxRequest) {}
|
|
||||||
|
|
||||||
///Event fired whenever the `readyState` attribute of an `XMLHttpRequest` changes.
|
///Event fired whenever the `readyState` attribute of an `XMLHttpRequest` changes.
|
||||||
///It gives the host application a chance to abort the request.
|
///It gives the host application a chance to abort the request.
|
||||||
|
@ -486,8 +473,7 @@ class InAppBrowser {
|
||||||
///[ajaxRequest] represents the [XMLHttpRequest].
|
///[ajaxRequest] represents the [XMLHttpRequest].
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
||||||
// ignore: missing_return
|
Future<AjaxRequestAction?>? onAjaxReadyStateChange(AjaxRequest ajaxRequest) {}
|
||||||
Future<AjaxRequestAction> onAjaxReadyStateChange(AjaxRequest ajaxRequest) {}
|
|
||||||
|
|
||||||
///Event fired as an `XMLHttpRequest` progress.
|
///Event fired as an `XMLHttpRequest` progress.
|
||||||
///It gives the host application a chance to abort the request.
|
///It gives the host application a chance to abort the request.
|
||||||
|
@ -495,8 +481,7 @@ class InAppBrowser {
|
||||||
///[ajaxRequest] represents the [XMLHttpRequest].
|
///[ajaxRequest] represents the [XMLHttpRequest].
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptAjaxRequest] option to `true`.
|
||||||
// ignore: missing_return
|
Future<AjaxRequestAction?>? onAjaxProgress(AjaxRequest ajaxRequest) {}
|
||||||
Future<AjaxRequestAction> onAjaxProgress(AjaxRequest ajaxRequest) {}
|
|
||||||
|
|
||||||
///Event fired when a request is sent to a server through [Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API).
|
///Event fired when a request is sent to a server through [Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API).
|
||||||
///It gives the host application a chance to take control over the request before sending it.
|
///It gives the host application a chance to take control over the request before sending it.
|
||||||
|
@ -504,8 +489,7 @@ class InAppBrowser {
|
||||||
///[fetchRequest] represents a resource request.
|
///[fetchRequest] represents a resource request.
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptFetchRequest] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldInterceptFetchRequest] option to `true`.
|
||||||
// ignore: missing_return
|
Future<FetchRequest?>? shouldInterceptFetchRequest(FetchRequest fetchRequest) {}
|
||||||
Future<FetchRequest> shouldInterceptFetchRequest(FetchRequest fetchRequest) {}
|
|
||||||
|
|
||||||
///Event fired when the host application updates its visited links database.
|
///Event fired when the host application updates its visited links database.
|
||||||
///This event is also fired when the navigation state of the [InAppWebView] changes through the usage of
|
///This event is also fired when the navigation state of the [InAppWebView] changes through the usage of
|
||||||
|
@ -517,14 +501,14 @@ class InAppBrowser {
|
||||||
///[androidIsReload] indicates if this url is being reloaded. Available only on Android.
|
///[androidIsReload] indicates if this url is being reloaded. Available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)
|
||||||
void onUpdateVisitedHistory(String url, bool androidIsReload) {}
|
void onUpdateVisitedHistory(String? url, bool? androidIsReload) {}
|
||||||
|
|
||||||
///Event fired when `window.print()` is called from JavaScript side.
|
///Event fired when `window.print()` is called from JavaScript side.
|
||||||
///
|
///
|
||||||
///[url] represents the url on which is called.
|
///[url] represents the url on which is called.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 21+.
|
///**NOTE**: available on Android 21+.
|
||||||
void onPrint(String url) {}
|
void onPrint(String? url) {}
|
||||||
|
|
||||||
///Event fired when an HTML element of the webview has been clicked and held.
|
///Event fired when an HTML element of the webview has been clicked and held.
|
||||||
///
|
///
|
||||||
|
@ -559,14 +543,14 @@ class InAppBrowser {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageCommitVisible(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageCommitVisible(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview
|
||||||
void onPageCommitVisible(String url) {}
|
void onPageCommitVisible(String? url) {}
|
||||||
|
|
||||||
///Event fired when a change in the document title occurred.
|
///Event fired when a change in the document title occurred.
|
||||||
///
|
///
|
||||||
///[title] represents the string containing the new title of the document.
|
///[title] represents the string containing the new title of the document.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)
|
||||||
void onTitleChanged(String title) {}
|
void onTitleChanged(String? title) {}
|
||||||
|
|
||||||
///Event fired when the WebView notifies that a loading URL has been flagged by Safe Browsing.
|
///Event fired when the WebView notifies that a loading URL has been flagged by Safe Browsing.
|
||||||
///The default behavior is to show an interstitial to the user, with the reporting checkbox visible.
|
///The default behavior is to show an interstitial to the user, with the reporting checkbox visible.
|
||||||
|
@ -578,9 +562,8 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android 27+.
|
///**NOTE**: available only on Android 27+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)
|
||||||
// ignore: missing_return
|
Future<SafeBrowsingResponse?>? androidOnSafeBrowsingHit(
|
||||||
Future<SafeBrowsingResponse> androidOnSafeBrowsingHit(
|
String url, SafeBrowsingThreat? threatType) {}
|
||||||
String url, SafeBrowsingThreat threatType) {}
|
|
||||||
|
|
||||||
///Event fired when the WebView is requesting permission to access the specified resources and the permission currently isn't granted or denied.
|
///Event fired when the WebView is requesting permission to access the specified resources and the permission currently isn't granted or denied.
|
||||||
///
|
///
|
||||||
|
@ -591,8 +574,7 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android 23+.
|
///**NOTE**: available only on Android 23+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)
|
||||||
// ignore: missing_return
|
Future<PermissionRequestResponse?>? androidOnPermissionRequest(
|
||||||
Future<PermissionRequestResponse> androidOnPermissionRequest(
|
|
||||||
String origin, List<String> resources) {}
|
String origin, List<String> resources) {}
|
||||||
|
|
||||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||||
|
@ -604,8 +586,7 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsShowPrompt(java.lang.String,%20android.webkit.GeolocationPermissions.Callback)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsShowPrompt(java.lang.String,%20android.webkit.GeolocationPermissions.Callback)
|
||||||
Future<GeolocationPermissionShowPromptResponse>
|
Future<GeolocationPermissionShowPromptResponse?>?
|
||||||
// ignore: missing_return
|
|
||||||
androidOnGeolocationPermissionsShowPrompt(String origin) {}
|
androidOnGeolocationPermissionsShowPrompt(String origin) {}
|
||||||
|
|
||||||
///Notify the host application that a request for Geolocation permissions, made with a previous call to [androidOnGeolocationPermissionsShowPrompt] has been canceled.
|
///Notify the host application that a request for Geolocation permissions, made with a previous call to [androidOnGeolocationPermissionsShowPrompt] has been canceled.
|
||||||
|
@ -633,8 +614,7 @@ class InAppBrowser {
|
||||||
///**Official Android API**:
|
///**Official Android API**:
|
||||||
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
|
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
|
||||||
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20java.lang.String)
|
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20java.lang.String)
|
||||||
Future<WebResourceResponse>
|
Future<WebResourceResponse?>?
|
||||||
// ignore: missing_return
|
|
||||||
androidShouldInterceptRequest(WebResourceRequest request) {}
|
androidShouldInterceptRequest(WebResourceRequest request) {}
|
||||||
|
|
||||||
///Event called when the renderer currently associated with the WebView becomes unresponsive as a result of a long running blocking task such as the execution of JavaScript.
|
///Event called when the renderer currently associated with the WebView becomes unresponsive as a result of a long running blocking task such as the execution of JavaScript.
|
||||||
|
@ -655,9 +635,8 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android 29+.
|
///**NOTE**: available only on Android 29+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessUnresponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessUnresponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
||||||
Future<WebViewRenderProcessAction>
|
Future<WebViewRenderProcessAction?>?
|
||||||
// ignore: missing_return
|
androidOnRenderProcessUnresponsive(String? url) {}
|
||||||
androidOnRenderProcessUnresponsive(String url) {}
|
|
||||||
|
|
||||||
///Event called once when an unresponsive renderer currently associated with the WebView becomes responsive.
|
///Event called once when an unresponsive renderer currently associated with the WebView becomes responsive.
|
||||||
///
|
///
|
||||||
|
@ -670,9 +649,8 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android 29+.
|
///**NOTE**: available only on Android 29+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessResponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessResponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
||||||
Future<WebViewRenderProcessAction>
|
Future<WebViewRenderProcessAction?>?
|
||||||
// ignore: missing_return
|
androidOnRenderProcessResponsive(String? url) {}
|
||||||
androidOnRenderProcessResponsive(String url) {}
|
|
||||||
|
|
||||||
///Event fired when the given WebView's render process has exited.
|
///Event fired when the given WebView's render process has exited.
|
||||||
///The application's implementation of this callback should only attempt to clean up the WebView.
|
///The application's implementation of this callback should only attempt to clean up the WebView.
|
||||||
|
@ -690,9 +668,8 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onFormResubmission(android.webkit.WebView,%20android.os.Message,%20android.os.Message)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onFormResubmission(android.webkit.WebView,%20android.os.Message,%20android.os.Message)
|
||||||
Future<FormResubmissionAction>
|
Future<FormResubmissionAction?>?
|
||||||
// ignore: missing_return
|
androidOnFormResubmission(String? url) {}
|
||||||
androidOnFormResubmission(String url) {}
|
|
||||||
|
|
||||||
///Event fired when the scale applied to the WebView has changed.
|
///Event fired when the scale applied to the WebView has changed.
|
||||||
///
|
///
|
||||||
|
@ -746,8 +723,7 @@ class InAppBrowser {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsBeforeUnload(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsBeforeUnload(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
// ignore: missing_return
|
Future<JsBeforeUnloadResponse?>? androidOnJsBeforeUnload(
|
||||||
Future<JsBeforeUnloadResponse> androidOnJsBeforeUnload(
|
|
||||||
JsBeforeUnloadRequest jsBeforeUnloadRequest) {}
|
JsBeforeUnloadRequest jsBeforeUnloadRequest) {}
|
||||||
|
|
||||||
///Event fired when a request to automatically log in the user has been processed.
|
///Event fired when a request to automatically log in the user has been processed.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:mime/mime.dart';
|
||||||
|
|
||||||
///This class allows you to create a simple server on `http://localhost:[port]/` in order to be able to load your assets file on a server. The default [port] value is `8080`.
|
///This class allows you to create a simple server on `http://localhost:[port]/` in order to be able to load your assets file on a server. The default [port] value is `8080`.
|
||||||
class InAppLocalhostServer {
|
class InAppLocalhostServer {
|
||||||
HttpServer _server;
|
HttpServer? _server;
|
||||||
int _port = 8080;
|
int _port = 8080;
|
||||||
|
|
||||||
InAppLocalhostServer({int port = 8080}) {
|
InAppLocalhostServer({int port = 8080}) {
|
||||||
|
@ -38,7 +38,7 @@ class InAppLocalhostServer {
|
||||||
this._server = server;
|
this._server = server;
|
||||||
|
|
||||||
server.listen((HttpRequest request) async {
|
server.listen((HttpRequest request) async {
|
||||||
var body = List<int>();
|
var body = [] as List<int>;
|
||||||
var path = request.requestedUri.path;
|
var path = request.requestedUri.path;
|
||||||
path = (path.startsWith('/')) ? path.substring(1) : path;
|
path = (path.startsWith('/')) ? path.substring(1) : path;
|
||||||
path += (path.endsWith('/')) ? 'index.html' : '';
|
path += (path.endsWith('/')) ? 'index.html' : '';
|
||||||
|
@ -77,7 +77,7 @@ class InAppLocalhostServer {
|
||||||
///Closes the server.
|
///Closes the server.
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
if (this._server != null) {
|
if (this._server != null) {
|
||||||
await this._server.close(force: true);
|
await this._server!.close(force: true);
|
||||||
print('Server running on http://localhost:$_port closed');
|
print('Server running on http://localhost:$_port closed');
|
||||||
this._server = null;
|
this._server = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,13 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||||
/// recognizers on this list.
|
/// recognizers on this list.
|
||||||
/// When `gestureRecognizers` is empty or null, the web view will only handle pointer events for gestures that
|
/// When `gestureRecognizers` is empty or null, the web view will only handle pointer events for gestures that
|
||||||
/// were not claimed by any other gesture recognizer.
|
/// were not claimed by any other gesture recognizer.
|
||||||
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
|
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
|
||||||
|
|
||||||
///The window id of a [CreateWindowRequest.windowId].
|
///The window id of a [CreateWindowRequest.windowId].
|
||||||
final int windowId;
|
final int? windowId;
|
||||||
|
|
||||||
const InAppWebView({
|
const InAppWebView({
|
||||||
Key key,
|
Key? key,
|
||||||
this.windowId,
|
this.windowId,
|
||||||
this.initialUrl = "about:blank",
|
this.initialUrl = "about:blank",
|
||||||
this.initialFile,
|
this.initialFile,
|
||||||
|
@ -94,248 +94,248 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||||
_InAppWebViewState createState() => _InAppWebViewState();
|
_InAppWebViewState createState() => _InAppWebViewState();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
androidOnGeolocationPermissionsHidePrompt;
|
androidOnGeolocationPermissionsHidePrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<GeolocationPermissionShowPromptResponse> Function(
|
final Future<GeolocationPermissionShowPromptResponse?> Function(
|
||||||
InAppWebViewController controller, String origin)
|
InAppWebViewController controller, String origin)?
|
||||||
androidOnGeolocationPermissionsShowPrompt;
|
androidOnGeolocationPermissionsShowPrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<PermissionRequestResponse> Function(
|
final Future<PermissionRequestResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
String origin,
|
String origin,
|
||||||
List<String> resources) androidOnPermissionRequest;
|
List<String> resources)? androidOnPermissionRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<SafeBrowsingResponse> Function(InAppWebViewController controller,
|
final Future<SafeBrowsingResponse?> Function(InAppWebViewController controller,
|
||||||
String url, SafeBrowsingThreat threatType) androidOnSafeBrowsingHit;
|
String url, SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final InAppWebViewInitialData initialData;
|
final InAppWebViewInitialData? initialData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String initialFile;
|
final String? initialFile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Map<String, String> initialHeaders;
|
final Map<String, String>? initialHeaders;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final InAppWebViewGroupOptions initialOptions;
|
final InAppWebViewGroupOptions? initialOptions;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String initialUrl;
|
final String? initialUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final ContextMenu contextMenu;
|
final ContextMenu? contextMenu;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onPageCommitVisible;
|
onPageCommitVisible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String title)
|
final void Function(InAppWebViewController controller, String? title)?
|
||||||
onTitleChanged;
|
onTitleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnWebContentProcessDidTerminate;
|
iosOnWebContentProcessDidTerminate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxProgress;
|
onAjaxProgress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxReadyStateChange;
|
onAjaxReadyStateChange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, ConsoleMessage consoleMessage)
|
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
||||||
onConsoleMessage;
|
onConsoleMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<bool> Function(InAppWebViewController controller,
|
final Future<bool?> Function(InAppWebViewController controller,
|
||||||
CreateWindowRequest createWindowRequest) onCreateWindow;
|
CreateWindowRequest createWindowRequest)? onCreateWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onCloseWindow;
|
final void Function(InAppWebViewController controller)? onCloseWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWindowFocus;
|
final void Function(InAppWebViewController controller)? onWindowFocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWindowBlur;
|
final void Function(InAppWebViewController controller)? onWindowBlur;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) androidOnRequestFocus;
|
final void Function(InAppWebViewController controller)? androidOnRequestFocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uint8List icon)
|
final void Function(InAppWebViewController controller, Uint8List icon)?
|
||||||
androidOnReceivedIcon;
|
androidOnReceivedIcon;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool precomposed)
|
InAppWebViewController controller, String url, bool precomposed)?
|
||||||
androidOnReceivedTouchIconUrl;
|
androidOnReceivedTouchIconUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String url)?
|
||||||
onDownloadStart;
|
onDownloadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||||
int numberOfMatches, bool isDoneCounting) onFindResultReceived;
|
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsAlertResponse> Function(
|
final Future<JsAlertResponse?> Function(
|
||||||
InAppWebViewController controller, JsAlertRequest jsAlertRequest)
|
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
||||||
onJsAlert;
|
onJsAlert;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsConfirmResponse> Function(
|
final Future<JsConfirmResponse?> Function(
|
||||||
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)
|
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
||||||
onJsConfirm;
|
onJsConfirm;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsPromptResponse> Function(
|
final Future<JsPromptResponse?> Function(
|
||||||
InAppWebViewController controller, JsPromptRequest jsPromptRequest)
|
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
||||||
onJsPrompt;
|
onJsPrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url, int code,
|
final void Function(InAppWebViewController controller, String? url, int code,
|
||||||
String message) onLoadError;
|
String message)? onLoadError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url,
|
final void Function(InAppWebViewController controller, String? url,
|
||||||
int statusCode, String description) onLoadHttpError;
|
int statusCode, String description)? onLoadHttpError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoadedResource resource)
|
InAppWebViewController controller, LoadedResource resource)?
|
||||||
onLoadResource;
|
onLoadResource;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<CustomSchemeResponse> Function(
|
final Future<CustomSchemeResponse?> Function(
|
||||||
InAppWebViewController controller, String scheme, String url)
|
InAppWebViewController controller, String scheme, String url)?
|
||||||
onLoadResourceCustomScheme;
|
onLoadResourceCustomScheme;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onLoadStart;
|
onLoadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url) onLoadStop;
|
final void Function(InAppWebViewController controller, String? url)? onLoadStop;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller,
|
final void Function(InAppWebViewController controller,
|
||||||
InAppWebViewHitTestResult hitTestResult) onLongPressHitTestResult;
|
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String url) onPrint;
|
final void Function(InAppWebViewController controller, String? url)? onPrint;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int progress)
|
final void Function(InAppWebViewController controller, int progress)?
|
||||||
onProgressChanged;
|
onProgressChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ClientCertResponse> Function(
|
final Future<ClientCertResponse?> Function(
|
||||||
InAppWebViewController controller, ClientCertChallenge challenge)
|
InAppWebViewController controller, ClientCertChallenge challenge)?
|
||||||
onReceivedClientCertRequest;
|
onReceivedClientCertRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<HttpAuthResponse> Function(
|
final Future<HttpAuthResponse?> Function(
|
||||||
InAppWebViewController controller, HttpAuthChallenge challenge)
|
InAppWebViewController controller, HttpAuthChallenge challenge)?
|
||||||
onReceivedHttpAuthRequest;
|
onReceivedHttpAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ServerTrustAuthResponse> Function(
|
final Future<ServerTrustAuthResponse?> Function(
|
||||||
InAppWebViewController controller, ServerTrustChallenge challenge)
|
InAppWebViewController controller, ServerTrustChallenge challenge)?
|
||||||
onReceivedServerTrustAuthRequest;
|
onReceivedServerTrustAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int x, int y)
|
final void Function(InAppWebViewController controller, int x, int y)?
|
||||||
onScrollChanged;
|
onScrollChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool androidIsReload)
|
InAppWebViewController controller, String? url, bool? androidIsReload)?
|
||||||
onUpdateVisitedHistory;
|
onUpdateVisitedHistory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onWebViewCreated;
|
final void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequest> Function(
|
final Future<AjaxRequest?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
shouldInterceptAjaxRequest;
|
shouldInterceptAjaxRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FetchRequest> Function(
|
final Future<FetchRequest?> Function(
|
||||||
InAppWebViewController controller, FetchRequest fetchRequest)
|
InAppWebViewController controller, FetchRequest fetchRequest)?
|
||||||
shouldInterceptFetchRequest;
|
shouldInterceptFetchRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ShouldOverrideUrlLoadingAction> Function(
|
final Future<ShouldOverrideUrlLoadingAction?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)
|
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)?
|
||||||
shouldOverrideUrlLoading;
|
shouldOverrideUrlLoading;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onEnterFullscreen;
|
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller) onExitFullscreen;
|
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebResourceResponse> Function(
|
final Future<WebResourceResponse?> Function(
|
||||||
InAppWebViewController controller, WebResourceRequest request)
|
InAppWebViewController controller, WebResourceRequest request)?
|
||||||
androidShouldInterceptRequest;
|
androidShouldInterceptRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessUnresponsive;
|
androidOnRenderProcessUnresponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessResponsive;
|
androidOnRenderProcessResponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, RenderProcessGoneDetail detail)
|
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
||||||
androidOnRenderProcessGone;
|
androidOnRenderProcessGone;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FormResubmissionAction> Function(
|
final Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, String url) androidOnFormResubmission;
|
InAppWebViewController controller, String? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
androidOnScaleChanged;
|
androidOnScaleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsBeforeUnloadResponse> Function(
|
final Future<JsBeforeUnloadResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
JsBeforeUnloadRequest jsBeforeUnloadRequest) androidOnJsBeforeUnload;
|
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoginRequest loginRequest)
|
InAppWebViewController controller, LoginRequest loginRequest)?
|
||||||
androidOnReceivedLoginRequest;
|
androidOnReceivedLoginRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _InAppWebViewState extends State<InAppWebView> {
|
class _InAppWebViewState extends State<InAppWebView> {
|
||||||
InAppWebViewController _controller;
|
late InAppWebViewController _controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -348,7 +348,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
PlatformViewController controller,
|
PlatformViewController controller,
|
||||||
) {
|
) {
|
||||||
return AndroidViewSurface(
|
return AndroidViewSurface(
|
||||||
controller: controller,
|
controller: controller as AndroidViewController,
|
||||||
gestureRecognizers: widget.gestureRecognizers ?? const <Factory<OneSequenceGestureRecognizer>>{},
|
gestureRecognizers: widget.gestureRecognizers ?? const <Factory<OneSequenceGestureRecognizer>>{},
|
||||||
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
||||||
);
|
);
|
||||||
|
@ -359,7 +359,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
viewType: 'com.pichillilorenzo/flutter_inappwebview',
|
viewType: 'com.pichillilorenzo/flutter_inappwebview',
|
||||||
layoutDirection: TextDirection.rtl,
|
layoutDirection: TextDirection.rtl,
|
||||||
creationParams: <String, dynamic>{
|
creationParams: <String, dynamic>{
|
||||||
'initialUrl': '${Uri.parse(widget.initialUrl)}',
|
'initialUrl': widget.initialUrl != null ? '${Uri.parse(widget.initialUrl!)}' : '',
|
||||||
'initialFile': widget.initialFile,
|
'initialFile': widget.initialFile,
|
||||||
'initialData': widget.initialData?.toMap(),
|
'initialData': widget.initialData?.toMap(),
|
||||||
'initialHeaders': widget.initialHeaders,
|
'initialHeaders': widget.initialHeaders,
|
||||||
|
@ -381,7 +381,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
gestureRecognizers: widget.gestureRecognizers,
|
gestureRecognizers: widget.gestureRecognizers,
|
||||||
layoutDirection: TextDirection.rtl,
|
layoutDirection: TextDirection.rtl,
|
||||||
creationParams: <String, dynamic>{
|
creationParams: <String, dynamic>{
|
||||||
'initialUrl': '${Uri.parse(widget.initialUrl)}',
|
'initialUrl': widget.initialUrl != null ? '${Uri.parse(widget.initialUrl!)}' : '',
|
||||||
'initialFile': widget.initialFile,
|
'initialFile': widget.initialFile,
|
||||||
'initialData': widget.initialData?.toMap(),
|
'initialData': widget.initialData?.toMap(),
|
||||||
'initialHeaders': widget.initialHeaders,
|
'initialHeaders': widget.initialHeaders,
|
||||||
|
@ -398,7 +398,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
onPlatformViewCreated: _onPlatformViewCreated,
|
onPlatformViewCreated: _onPlatformViewCreated,
|
||||||
gestureRecognizers: widget.gestureRecognizers,
|
gestureRecognizers: widget.gestureRecognizers,
|
||||||
creationParams: <String, dynamic>{
|
creationParams: <String, dynamic>{
|
||||||
'initialUrl': '${Uri.parse(widget.initialUrl)}',
|
'initialUrl': widget.initialUrl != null ? '${Uri.parse(widget.initialUrl!)}' : '',
|
||||||
'initialFile': widget.initialFile,
|
'initialFile': widget.initialFile,
|
||||||
'initialData': widget.initialData?.toMap(),
|
'initialData': widget.initialData?.toMap(),
|
||||||
'initialHeaders': widget.initialHeaders,
|
'initialHeaders': widget.initialHeaders,
|
||||||
|
@ -426,7 +426,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
void _onPlatformViewCreated(int id) {
|
void _onPlatformViewCreated(int id) {
|
||||||
_controller = InAppWebViewController(id, widget);
|
_controller = InAppWebViewController(id, widget);
|
||||||
if (widget.onWebViewCreated != null) {
|
if (widget.onWebViewCreated != null) {
|
||||||
widget.onWebViewCreated(_controller);
|
widget.onWebViewCreated!(_controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@ import 'dart:math';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
static Color convertColorFromStringRepresentation(String colorValue) {
|
static Color? convertColorFromStringRepresentation(String colorValue) {
|
||||||
if (colorValue.startsWith("#")) {
|
if (colorValue.startsWith("#")) {
|
||||||
return Util.getColorFromHex(colorValue);
|
return Util.getColorFromHex(colorValue);
|
||||||
} else if (colorValue.startsWith("rgb(")) {
|
} else if (colorValue.startsWith("rgb(")) {
|
||||||
|
@ -391,7 +391,7 @@ class Util {
|
||||||
rgbaValues[0], rgbaValues[1], rgbaValues[2], hlsaValues[3]);
|
rgbaValues[0], rgbaValues[1], rgbaValues[2], hlsaValues[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<num> hslToRgb(double h, double s, double l) {
|
static List<int> hslToRgb(double h, double s, double l) {
|
||||||
double r, g, b;
|
double r, g, b;
|
||||||
|
|
||||||
if (s == 0) {
|
if (s == 0) {
|
||||||
|
@ -407,8 +407,8 @@ class Util {
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static num to255(double v) {
|
static int to255(double v) {
|
||||||
return min(255, 256 * v);
|
return min(255, (256 * v).round());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method that converts hue to rgb
|
/// Helper method that converts hue to rgb
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
import 'in_app_webview_controller.dart';
|
import 'in_app_webview_controller.dart';
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
|
|
||||||
|
@ -14,13 +12,13 @@ class WebStorage {
|
||||||
///Represents `window.sessionStorage`.
|
///Represents `window.sessionStorage`.
|
||||||
SessionStorage sessionStorage;
|
SessionStorage sessionStorage;
|
||||||
|
|
||||||
WebStorage({@required this.localStorage, @required this.sessionStorage});
|
WebStorage({required this.localStorage, required this.sessionStorage});
|
||||||
}
|
}
|
||||||
|
|
||||||
///Class that represents a single web storage item of the JavaScript `window.sessionStorage` and `window.localStorage` objects.
|
///Class that represents a single web storage item of the JavaScript `window.sessionStorage` and `window.localStorage` objects.
|
||||||
class WebStorageItem {
|
class WebStorageItem {
|
||||||
///Item key.
|
///Item key.
|
||||||
String key;
|
String? key;
|
||||||
|
|
||||||
///Item value.
|
///Item value.
|
||||||
dynamic value;
|
dynamic value;
|
||||||
|
@ -47,18 +45,17 @@ class WebStorageItem {
|
||||||
///Class that provides methods to manage the JavaScript [Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage) object.
|
///Class that provides methods to manage the JavaScript [Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage) object.
|
||||||
///It is used by [LocalStorage] and [SessionStorage].
|
///It is used by [LocalStorage] and [SessionStorage].
|
||||||
class Storage {
|
class Storage {
|
||||||
InAppWebViewController _controller;
|
late InAppWebViewController _controller;
|
||||||
|
|
||||||
///The web storage type: `window.sessionStorage` or `window.localStorage`.
|
///The web storage type: `window.sessionStorage` or `window.localStorage`.
|
||||||
WebStorageType webStorageType;
|
WebStorageType webStorageType;
|
||||||
|
|
||||||
Storage(InAppWebViewController controller, this.webStorageType) {
|
Storage(InAppWebViewController controller, this.webStorageType) {
|
||||||
assert(controller != null && this.webStorageType != null);
|
|
||||||
this._controller = controller;
|
this._controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Returns an integer representing the number of data items stored in the Storage object.
|
///Returns an integer representing the number of data items stored in the Storage object.
|
||||||
Future<int> length() async {
|
Future<int?> length() async {
|
||||||
var result = await _controller.evaluateJavascript(source: """
|
var result = await _controller.evaluateJavascript(source: """
|
||||||
window.$webStorageType.length;
|
window.$webStorageType.length;
|
||||||
""");
|
""");
|
||||||
|
@ -66,7 +63,7 @@ class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
///When passed a [key] name and [value], will add that key to the storage, or update that key's value if it already exists.
|
///When passed a [key] name and [value], will add that key to the storage, or update that key's value if it already exists.
|
||||||
Future<void> setItem({@required String key, @required dynamic value}) async {
|
Future<void> setItem({required String key, required dynamic value}) async {
|
||||||
var encodedValue = json.encode(value);
|
var encodedValue = json.encode(value);
|
||||||
await _controller.evaluateJavascript(source: """
|
await _controller.evaluateJavascript(source: """
|
||||||
window.$webStorageType.setItem("$key", ${value is String ? encodedValue : "JSON.stringify($encodedValue)"});
|
window.$webStorageType.setItem("$key", ${value is String ? encodedValue : "JSON.stringify($encodedValue)"});
|
||||||
|
@ -74,7 +71,7 @@ class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
///When passed a [key] name, will return that key's value, or `null` if the key does not exist, in the given Storage object.
|
///When passed a [key] name, will return that key's value, or `null` if the key does not exist, in the given Storage object.
|
||||||
Future<dynamic> getItem({@required String key}) async {
|
Future<dynamic> getItem({required String key}) async {
|
||||||
var itemValue = await _controller.evaluateJavascript(source: """
|
var itemValue = await _controller.evaluateJavascript(source: """
|
||||||
window.$webStorageType.getItem("$key");
|
window.$webStorageType.getItem("$key");
|
||||||
""");
|
""");
|
||||||
|
@ -91,7 +88,7 @@ class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
///When passed a [key] name, will remove that key from the given Storage object if it exists.
|
///When passed a [key] name, will remove that key from the given Storage object if it exists.
|
||||||
Future<void> removeItem({@required String key}) async {
|
Future<void> removeItem({required String key}) async {
|
||||||
await _controller.evaluateJavascript(source: """
|
await _controller.evaluateJavascript(source: """
|
||||||
window.$webStorageType.removeItem("$key");
|
window.$webStorageType.removeItem("$key");
|
||||||
""");
|
""");
|
||||||
|
@ -139,7 +136,7 @@ class Storage {
|
||||||
|
|
||||||
///When passed a number [index], returns the name of the nth key in a given Storage object.
|
///When passed a number [index], returns the name of the nth key in a given Storage object.
|
||||||
///The order of keys is user-agent defined, so you should not rely on it.
|
///The order of keys is user-agent defined, so you should not rely on it.
|
||||||
Future<String> key({@required int index}) async {
|
Future<String> key({required int index}) async {
|
||||||
var result = await _controller.evaluateJavascript(source: """
|
var result = await _controller.evaluateJavascript(source: """
|
||||||
window.$webStorageType.key($index);
|
window.$webStorageType.key($index);
|
||||||
""");
|
""");
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
|
@ -11,7 +10,7 @@ import 'types.dart';
|
||||||
///
|
///
|
||||||
///**NOTE for iOS**: available from iOS 9.0+.
|
///**NOTE for iOS**: available from iOS 9.0+.
|
||||||
class WebStorageManager {
|
class WebStorageManager {
|
||||||
static WebStorageManager _instance;
|
static WebStorageManager? _instance;
|
||||||
static const MethodChannel _channel = const MethodChannel(
|
static const MethodChannel _channel = const MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_webstoragemanager');
|
'com.pichillilorenzo/flutter_inappwebview_webstoragemanager');
|
||||||
|
|
||||||
|
@ -20,13 +19,13 @@ class WebStorageManager {
|
||||||
|
|
||||||
///Gets the WebStorage manager shared instance.
|
///Gets the WebStorage manager shared instance.
|
||||||
static WebStorageManager instance() {
|
static WebStorageManager instance() {
|
||||||
return (_instance != null) ? _instance : _init();
|
return (_instance != null) ? _instance! : _init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebStorageManager _init() {
|
static WebStorageManager _init() {
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
_instance = new WebStorageManager();
|
_instance = new WebStorageManager();
|
||||||
return _instance;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
||||||
|
@ -63,8 +62,7 @@ class AndroidWebStorageManager {
|
||||||
|
|
||||||
///Clears the storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin].
|
///Clears the storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin].
|
||||||
///The origin is specified using its string representation.
|
///The origin is specified using its string representation.
|
||||||
Future<void> deleteOrigin({@required String origin}) async {
|
Future<void> deleteOrigin({required String origin}) async {
|
||||||
assert(origin != null);
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("origin", () => origin);
|
args.putIfAbsent("origin", () => origin);
|
||||||
await WebStorageManager._channel.invokeMethod('deleteOrigin', args);
|
await WebStorageManager._channel.invokeMethod('deleteOrigin', args);
|
||||||
|
@ -73,8 +71,7 @@ class AndroidWebStorageManager {
|
||||||
///Gets the storage quota for the Web SQL Database API for the given [origin].
|
///Gets the storage quota for the Web SQL Database API for the given [origin].
|
||||||
///The quota is given in bytes and the origin is specified using its string representation.
|
///The quota is given in bytes and the origin is specified using its string representation.
|
||||||
///Note that a quota is not enforced on a per-origin basis for the Application Cache API.
|
///Note that a quota is not enforced on a per-origin basis for the Application Cache API.
|
||||||
Future<int> getQuotaForOrigin({@required String origin}) async {
|
Future<int> getQuotaForOrigin({required String origin}) async {
|
||||||
assert(origin != null);
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("origin", () => origin);
|
args.putIfAbsent("origin", () => origin);
|
||||||
return await WebStorageManager._channel
|
return await WebStorageManager._channel
|
||||||
|
@ -83,8 +80,7 @@ class AndroidWebStorageManager {
|
||||||
|
|
||||||
///Gets the amount of storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin].
|
///Gets the amount of storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin].
|
||||||
///The amount is given in bytes and the origin is specified using its string representation.
|
///The amount is given in bytes and the origin is specified using its string representation.
|
||||||
Future<int> getUsageForOrigin({@required String origin}) async {
|
Future<int> getUsageForOrigin({required String origin}) async {
|
||||||
assert(origin != null);
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent("origin", () => origin);
|
args.putIfAbsent("origin", () => origin);
|
||||||
return await WebStorageManager._channel
|
return await WebStorageManager._channel
|
||||||
|
@ -101,8 +97,7 @@ class IOSWebStorageManager {
|
||||||
///
|
///
|
||||||
///[dataTypes] represents the website data types to fetch records for.
|
///[dataTypes] represents the website data types to fetch records for.
|
||||||
Future<List<IOSWKWebsiteDataRecord>> fetchDataRecords(
|
Future<List<IOSWKWebsiteDataRecord>> fetchDataRecords(
|
||||||
{@required Set<IOSWKWebsiteDataType> dataTypes}) async {
|
{required Set<IOSWKWebsiteDataType> dataTypes}) async {
|
||||||
assert(dataTypes != null);
|
|
||||||
List<IOSWKWebsiteDataRecord> recordList = [];
|
List<IOSWKWebsiteDataRecord> recordList = [];
|
||||||
List<String> dataTypesList = [];
|
List<String> dataTypesList = [];
|
||||||
for (var dataType in dataTypes) {
|
for (var dataType in dataTypes) {
|
||||||
|
@ -116,8 +111,11 @@ class IOSWebStorageManager {
|
||||||
for (var record in records) {
|
for (var record in records) {
|
||||||
List<String> dataTypesString = record["dataTypes"].cast<String>();
|
List<String> dataTypesString = record["dataTypes"].cast<String>();
|
||||||
Set<IOSWKWebsiteDataType> dataTypes = Set();
|
Set<IOSWKWebsiteDataType> dataTypes = Set();
|
||||||
for (var dataType in dataTypesString) {
|
for (var dataTypeValue in dataTypesString) {
|
||||||
dataTypes.add(IOSWKWebsiteDataType.fromValue(dataType));
|
var dataType = IOSWKWebsiteDataType.fromValue(dataTypeValue);
|
||||||
|
if (dataType != null) {
|
||||||
|
dataTypes.add(dataType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
recordList.add(IOSWKWebsiteDataRecord(
|
recordList.add(IOSWKWebsiteDataRecord(
|
||||||
displayName: record["displayName"], dataTypes: dataTypes));
|
displayName: record["displayName"], dataTypes: dataTypes));
|
||||||
|
@ -131,10 +129,8 @@ class IOSWebStorageManager {
|
||||||
///
|
///
|
||||||
///[dataRecords] represents the website data records to delete website data for.
|
///[dataRecords] represents the website data records to delete website data for.
|
||||||
Future<void> removeDataFor(
|
Future<void> removeDataFor(
|
||||||
{@required Set<IOSWKWebsiteDataType> dataTypes,
|
{required Set<IOSWKWebsiteDataType> dataTypes,
|
||||||
@required List<IOSWKWebsiteDataRecord> dataRecords}) async {
|
required List<IOSWKWebsiteDataRecord> dataRecords}) async {
|
||||||
assert(dataTypes != null && dataRecords != null);
|
|
||||||
|
|
||||||
List<String> dataTypesList = [];
|
List<String> dataTypesList = [];
|
||||||
for (var dataType in dataTypes) {
|
for (var dataType in dataTypes) {
|
||||||
dataTypesList.add(dataType.toValue());
|
dataTypesList.add(dataType.toValue());
|
||||||
|
@ -157,10 +153,8 @@ class IOSWebStorageManager {
|
||||||
///
|
///
|
||||||
///[date] represents a date. All website data modified after this date will be removed.
|
///[date] represents a date. All website data modified after this date will be removed.
|
||||||
Future<void> removeDataModifiedSince(
|
Future<void> removeDataModifiedSince(
|
||||||
{@required Set<IOSWKWebsiteDataType> dataTypes,
|
{required Set<IOSWKWebsiteDataType> dataTypes,
|
||||||
@required DateTime date}) async {
|
required DateTime date}) async {
|
||||||
assert(dataTypes != null && date != null);
|
|
||||||
|
|
||||||
List<String> dataTypesList = [];
|
List<String> dataTypesList = [];
|
||||||
for (var dataType in dataTypes) {
|
for (var dataType in dataTypes) {
|
||||||
dataTypesList.add(dataType.toValue());
|
dataTypesList.add(dataType.toValue());
|
||||||
|
|
|
@ -10,17 +10,17 @@ import 'headless_in_app_webview.dart';
|
||||||
///Abstract class that represents a WebView. Used by [WebView] and [HeadlessInAppWebView].
|
///Abstract class that represents a WebView. Used by [WebView] and [HeadlessInAppWebView].
|
||||||
abstract class WebView {
|
abstract class WebView {
|
||||||
///The window id of a [CreateWindowRequest.windowId].
|
///The window id of a [CreateWindowRequest.windowId].
|
||||||
final int windowId;
|
final int? windowId;
|
||||||
|
|
||||||
///Event fired when the [WebView] is created.
|
///Event fired when the [WebView] is created.
|
||||||
final void Function(InAppWebViewController controller) onWebViewCreated;
|
final void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||||
|
|
||||||
///Event fired when the [WebView] starts to load an [url].
|
///Event fired when the [WebView] starts to load an [url].
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onLoadStart;
|
onLoadStart;
|
||||||
|
|
||||||
///Event fired when the [WebView] finishes loading an [url].
|
///Event fired when the [WebView] finishes loading an [url].
|
||||||
|
@ -28,15 +28,15 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
|
||||||
final void Function(InAppWebViewController controller, String url) onLoadStop;
|
final void Function(InAppWebViewController controller, String? url)? onLoadStop;
|
||||||
|
|
||||||
///Event fired when the [WebView] encounters an error loading an [url].
|
///Event fired when the [WebView] encounters an error loading an [url].
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20int,%20java.lang.String,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20int,%20java.lang.String,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview
|
||||||
final void Function(InAppWebViewController controller, String url, int code,
|
final void Function(InAppWebViewController controller, String? url, int code,
|
||||||
String message) onLoadError;
|
String message)? onLoadError;
|
||||||
|
|
||||||
///Event fired when the [WebView] main page receives an HTTP error.
|
///Event fired when the [WebView] main page receives an HTTP error.
|
||||||
///
|
///
|
||||||
|
@ -51,20 +51,20 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
||||||
final void Function(InAppWebViewController controller, String url,
|
final void Function(InAppWebViewController controller, String? url,
|
||||||
int statusCode, String description) onLoadHttpError;
|
int statusCode, String description)? onLoadHttpError;
|
||||||
|
|
||||||
///Event fired when the current [progress] of loading a page is changed.
|
///Event fired when the current [progress] of loading a page is changed.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onProgressChanged(android.webkit.WebView,%20int)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onProgressChanged(android.webkit.WebView,%20int)
|
||||||
final void Function(InAppWebViewController controller, int progress)
|
final void Function(InAppWebViewController controller, int progress)?
|
||||||
onProgressChanged;
|
onProgressChanged;
|
||||||
|
|
||||||
///Event fired when the [WebView] receives a [ConsoleMessage].
|
///Event fired when the [WebView] receives a [ConsoleMessage].
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onConsoleMessage(android.webkit.ConsoleMessage)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onConsoleMessage(android.webkit.ConsoleMessage)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, ConsoleMessage consoleMessage)
|
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
||||||
onConsoleMessage;
|
onConsoleMessage;
|
||||||
|
|
||||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView. This event is not called on the initial load of the WebView.
|
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView. This event is not called on the initial load of the WebView.
|
||||||
|
@ -82,16 +82,16 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview
|
||||||
final Future<ShouldOverrideUrlLoadingAction> Function(
|
final Future<ShouldOverrideUrlLoadingAction?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)
|
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)?
|
||||||
shouldOverrideUrlLoading;
|
shouldOverrideUrlLoading;
|
||||||
|
|
||||||
///Event fired when the [WebView] loads a resource.
|
///Event fired when the [WebView] loads a resource.
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnLoadResource] and [InAppWebViewOptions.javaScriptEnabled] options to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnLoadResource] and [InAppWebViewOptions.javaScriptEnabled] options to `true`.
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoadedResource resource)
|
InAppWebViewController controller, LoadedResource resource)?
|
||||||
onLoadResource;
|
onLoadResource;
|
||||||
|
|
||||||
///Event fired when the [WebView] scrolls.
|
///Event fired when the [WebView] scrolls.
|
||||||
|
@ -103,7 +103,7 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#onScrollChanged(int,%20int,%20int,%20int)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#onScrollChanged(int,%20int,%20int,%20int)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll
|
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll
|
||||||
final void Function(InAppWebViewController controller, int x, int y)
|
final void Function(InAppWebViewController controller, int x, int y)?
|
||||||
onScrollChanged;
|
onScrollChanged;
|
||||||
|
|
||||||
///Event fired when [WebView] recognizes a downloadable file.
|
///Event fired when [WebView] recognizes a downloadable file.
|
||||||
|
@ -116,7 +116,7 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#setDownloadListener(android.webkit.DownloadListener)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#setDownloadListener(android.webkit.DownloadListener)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String url)?
|
||||||
onDownloadStart;
|
onDownloadStart;
|
||||||
|
|
||||||
///Event fired when the [WebView] finds the `custom-scheme` while loading a resource. Here you can handle the url request and return a [CustomSchemeResponse] to load a specific resource encoded to `base64`.
|
///Event fired when the [WebView] finds the `custom-scheme` while loading a resource. Here you can handle the url request and return a [CustomSchemeResponse] to load a specific resource encoded to `base64`.
|
||||||
|
@ -126,8 +126,8 @@ abstract class WebView {
|
||||||
///[url] represents the url of the request.
|
///[url] represents the url of the request.
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkurlschemehandler
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkurlschemehandler
|
||||||
final Future<CustomSchemeResponse> Function(
|
final Future<CustomSchemeResponse?> Function(
|
||||||
InAppWebViewController controller, String scheme, String url)
|
InAppWebViewController controller, String scheme, String url)?
|
||||||
onLoadResourceCustomScheme;
|
onLoadResourceCustomScheme;
|
||||||
|
|
||||||
///Event fired when the [WebView] requests the host application to create a new window,
|
///Event fired when the [WebView] requests the host application to create a new window,
|
||||||
|
@ -160,8 +160,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview
|
||||||
final Future<bool> Function(InAppWebViewController controller,
|
final Future<bool?> Function(InAppWebViewController controller,
|
||||||
CreateWindowRequest createWindowRequest) onCreateWindow;
|
CreateWindowRequest createWindowRequest)? onCreateWindow;
|
||||||
|
|
||||||
///Event fired when the host application should close the given WebView and remove it from the view system if necessary.
|
///Event fired when the host application should close the given WebView and remove it from the view system if necessary.
|
||||||
///At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.
|
///At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.
|
||||||
|
@ -169,15 +169,15 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCloseWindow(android.webkit.WebView)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onCloseWindow(android.webkit.WebView)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537390-webviewdidclose
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537390-webviewdidclose
|
||||||
final void Function(InAppWebViewController controller) onCloseWindow;
|
final void Function(InAppWebViewController controller)? onCloseWindow;
|
||||||
|
|
||||||
///Event fired when the JavaScript `window` object of the WebView has received focus.
|
///Event fired when the JavaScript `window` object of the WebView has received focus.
|
||||||
///This is the result of the `focus` JavaScript event applied to the `window` object.
|
///This is the result of the `focus` JavaScript event applied to the `window` object.
|
||||||
final void Function(InAppWebViewController controller) onWindowFocus;
|
final void Function(InAppWebViewController controller)? onWindowFocus;
|
||||||
|
|
||||||
///Event fired when the JavaScript `window` object of the WebView has lost focus.
|
///Event fired when the JavaScript `window` object of the WebView has lost focus.
|
||||||
///This is the result of the `blur` JavaScript event applied to the `window` object.
|
///This is the result of the `blur` JavaScript event applied to the `window` object.
|
||||||
final void Function(InAppWebViewController controller) onWindowBlur;
|
final void Function(InAppWebViewController controller)? onWindowBlur;
|
||||||
|
|
||||||
///Event fired when javascript calls the `alert()` method to display an alert dialog.
|
///Event fired when javascript calls the `alert()` method to display an alert dialog.
|
||||||
///If [JsAlertResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
///If [JsAlertResponse.handledByClient] is `true`, the webview will assume that the client will handle the dialog.
|
||||||
|
@ -187,8 +187,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsAlert(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsAlert(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview
|
||||||
final Future<JsAlertResponse> Function(
|
final Future<JsAlertResponse?> Function(
|
||||||
InAppWebViewController controller, JsAlertRequest jsAlertRequest)
|
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
||||||
onJsAlert;
|
onJsAlert;
|
||||||
|
|
||||||
///Event fired when javascript calls the `confirm()` method to display a confirm dialog.
|
///Event fired when javascript calls the `confirm()` method to display a confirm dialog.
|
||||||
|
@ -199,8 +199,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsConfirm(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsConfirm(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview
|
||||||
final Future<JsConfirmResponse> Function(
|
final Future<JsConfirmResponse?> Function(
|
||||||
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)
|
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
||||||
onJsConfirm;
|
onJsConfirm;
|
||||||
|
|
||||||
///Event fired when javascript calls the `prompt()` method to display a prompt dialog.
|
///Event fired when javascript calls the `prompt()` method to display a prompt dialog.
|
||||||
|
@ -211,8 +211,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview
|
||||||
final Future<JsPromptResponse> Function(
|
final Future<JsPromptResponse?> Function(
|
||||||
InAppWebViewController controller, JsPromptRequest jsPromptRequest)
|
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
||||||
onJsPrompt;
|
onJsPrompt;
|
||||||
|
|
||||||
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
///Event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
||||||
|
@ -222,8 +222,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
final Future<HttpAuthResponse> Function(
|
final Future<HttpAuthResponse?> Function(
|
||||||
InAppWebViewController controller, HttpAuthChallenge challenge)
|
InAppWebViewController controller, HttpAuthChallenge challenge)?
|
||||||
onReceivedHttpAuthRequest;
|
onReceivedHttpAuthRequest;
|
||||||
|
|
||||||
///Event fired when the WebView need to perform server trust authentication (certificate validation).
|
///Event fired when the WebView need to perform server trust authentication (certificate validation).
|
||||||
|
@ -234,8 +234,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
final Future<ServerTrustAuthResponse> Function(
|
final Future<ServerTrustAuthResponse?> Function(
|
||||||
InAppWebViewController controller, ServerTrustChallenge challenge)
|
InAppWebViewController controller, ServerTrustChallenge challenge)?
|
||||||
onReceivedServerTrustAuthRequest;
|
onReceivedServerTrustAuthRequest;
|
||||||
|
|
||||||
///Notify the host application to handle an SSL client certificate request.
|
///Notify the host application to handle an SSL client certificate request.
|
||||||
|
@ -248,8 +248,8 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview
|
||||||
final Future<ClientCertResponse> Function(
|
final Future<ClientCertResponse?> Function(
|
||||||
InAppWebViewController controller, ClientCertChallenge challenge)
|
InAppWebViewController controller, ClientCertChallenge challenge)?
|
||||||
onReceivedClientCertRequest;
|
onReceivedClientCertRequest;
|
||||||
|
|
||||||
///Event fired as find-on-page operations progress.
|
///Event fired as find-on-page operations progress.
|
||||||
|
@ -263,7 +263,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#setFindListener(android.webkit.WebView.FindListener)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#setFindListener(android.webkit.WebView.FindListener)
|
||||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||||
int numberOfMatches, bool isDoneCounting) onFindResultReceived;
|
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
||||||
|
|
||||||
///Event fired when an `XMLHttpRequest` is sent to a server.
|
///Event fired when an `XMLHttpRequest` is sent to a server.
|
||||||
///It gives the host application a chance to take control over the request before sending it.
|
///It gives the host application a chance to take control over the request before sending it.
|
||||||
|
@ -275,8 +275,8 @@ abstract class WebView {
|
||||||
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
||||||
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
||||||
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
||||||
final Future<AjaxRequest> Function(
|
final Future<AjaxRequest?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
shouldInterceptAjaxRequest;
|
shouldInterceptAjaxRequest;
|
||||||
|
|
||||||
///Event fired whenever the `readyState` attribute of an `XMLHttpRequest` changes.
|
///Event fired whenever the `readyState` attribute of an `XMLHttpRequest` changes.
|
||||||
|
@ -289,8 +289,8 @@ abstract class WebView {
|
||||||
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
||||||
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
||||||
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxReadyStateChange;
|
onAjaxReadyStateChange;
|
||||||
|
|
||||||
///Event fired as an `XMLHttpRequest` progress.
|
///Event fired as an `XMLHttpRequest` progress.
|
||||||
|
@ -303,8 +303,8 @@ abstract class WebView {
|
||||||
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
||||||
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
||||||
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the ajax requests will be intercept for sure.
|
||||||
final Future<AjaxRequestAction> Function(
|
final Future<AjaxRequestAction?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxProgress;
|
onAjaxProgress;
|
||||||
|
|
||||||
///Event fired when a request is sent to a server through [Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API).
|
///Event fired when a request is sent to a server through [Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API).
|
||||||
|
@ -317,8 +317,8 @@ abstract class WebView {
|
||||||
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code
|
||||||
///used to intercept fetch requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
///used to intercept fetch requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms).
|
||||||
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the fetch requests will be intercept for sure.
|
///Inside the `window.addEventListener("flutterInAppWebViewPlatformReady")` event, the fetch requests will be intercept for sure.
|
||||||
final Future<FetchRequest> Function(
|
final Future<FetchRequest?> Function(
|
||||||
InAppWebViewController controller, FetchRequest fetchRequest)
|
InAppWebViewController controller, FetchRequest fetchRequest)?
|
||||||
shouldInterceptFetchRequest;
|
shouldInterceptFetchRequest;
|
||||||
|
|
||||||
///Event fired when the host application updates its visited links database.
|
///Event fired when the host application updates its visited links database.
|
||||||
|
@ -332,7 +332,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool androidIsReload)
|
InAppWebViewController controller, String? url, bool? androidIsReload)?
|
||||||
onUpdateVisitedHistory;
|
onUpdateVisitedHistory;
|
||||||
|
|
||||||
///Event fired when `window.print()` is called from JavaScript side.
|
///Event fired when `window.print()` is called from JavaScript side.
|
||||||
|
@ -340,7 +340,7 @@ abstract class WebView {
|
||||||
///[url] represents the url on which is called.
|
///[url] represents the url on which is called.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 21+.
|
///**NOTE**: available on Android 21+.
|
||||||
final void Function(InAppWebViewController controller, String url) onPrint;
|
final void Function(InAppWebViewController controller, String? url)? onPrint;
|
||||||
|
|
||||||
///Event fired when an HTML element of the webview has been clicked and held.
|
///Event fired when an HTML element of the webview has been clicked and held.
|
||||||
///
|
///
|
||||||
|
@ -350,21 +350,21 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer
|
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer
|
||||||
final void Function(InAppWebViewController controller,
|
final void Function(InAppWebViewController controller,
|
||||||
InAppWebViewHitTestResult hitTestResult) onLongPressHitTestResult;
|
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
||||||
|
|
||||||
///Event fired when the current page has entered full screen mode.
|
///Event fired when the current page has entered full screen mode.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onShowCustomView(android.view.View,%20android.webkit.WebChromeClient.CustomViewCallback)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onShowCustomView(android.view.View,%20android.webkit.WebChromeClient.CustomViewCallback)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiwindow/1621621-didbecomevisiblenotification
|
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiwindow/1621621-didbecomevisiblenotification
|
||||||
final void Function(InAppWebViewController controller) onEnterFullscreen;
|
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||||
|
|
||||||
///Event fired when the current page has exited full screen mode.
|
///Event fired when the current page has exited full screen mode.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onHideCustomView()
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onHideCustomView()
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiwindow/1621617-didbecomehiddennotification
|
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiwindow/1621617-didbecomehiddennotification
|
||||||
final void Function(InAppWebViewController controller) onExitFullscreen;
|
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||||
|
|
||||||
///Called when the web view begins to receive web content.
|
///Called when the web view begins to receive web content.
|
||||||
///
|
///
|
||||||
|
@ -376,7 +376,7 @@ abstract class WebView {
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageCommitVisible(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onPageCommitVisible(android.webkit.WebView,%20java.lang.String)
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview
|
||||||
final void Function(InAppWebViewController controller, String url)
|
final void Function(InAppWebViewController controller, String? url)?
|
||||||
onPageCommitVisible;
|
onPageCommitVisible;
|
||||||
|
|
||||||
///Event fired when a change in the document title occurred.
|
///Event fired when a change in the document title occurred.
|
||||||
|
@ -384,7 +384,7 @@ abstract class WebView {
|
||||||
///[title] represents the string containing the new title of the document.
|
///[title] represents the string containing the new title of the document.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)
|
||||||
final void Function(InAppWebViewController controller, String title)
|
final void Function(InAppWebViewController controller, String? title)?
|
||||||
onTitleChanged;
|
onTitleChanged;
|
||||||
|
|
||||||
///Event fired when the webview notifies that a loading URL has been flagged by Safe Browsing.
|
///Event fired when the webview notifies that a loading URL has been flagged by Safe Browsing.
|
||||||
|
@ -397,8 +397,8 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android 27+.
|
///**NOTE**: available only on Android 27+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onSafeBrowsingHit(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20int,%20android.webkit.SafeBrowsingResponse)
|
||||||
final Future<SafeBrowsingResponse> Function(InAppWebViewController controller,
|
final Future<SafeBrowsingResponse?> Function(InAppWebViewController controller,
|
||||||
String url, SafeBrowsingThreat threatType) androidOnSafeBrowsingHit;
|
String url, SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
|
||||||
|
|
||||||
///Event fired when the WebView is requesting permission to access the specified resources and the permission currently isn't granted or denied.
|
///Event fired when the WebView is requesting permission to access the specified resources and the permission currently isn't granted or denied.
|
||||||
///
|
///
|
||||||
|
@ -409,10 +409,10 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android 23+.
|
///**NOTE**: available only on Android 23+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest)
|
||||||
final Future<PermissionRequestResponse> Function(
|
final Future<PermissionRequestResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
String origin,
|
String origin,
|
||||||
List<String> resources) androidOnPermissionRequest;
|
List<String> resources)? androidOnPermissionRequest;
|
||||||
|
|
||||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||||
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
||||||
|
@ -423,8 +423,8 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsShowPrompt(java.lang.String,%20android.webkit.GeolocationPermissions.Callback)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsShowPrompt(java.lang.String,%20android.webkit.GeolocationPermissions.Callback)
|
||||||
final Future<GeolocationPermissionShowPromptResponse> Function(
|
final Future<GeolocationPermissionShowPromptResponse?> Function(
|
||||||
InAppWebViewController controller, String origin)
|
InAppWebViewController controller, String origin)?
|
||||||
androidOnGeolocationPermissionsShowPrompt;
|
androidOnGeolocationPermissionsShowPrompt;
|
||||||
|
|
||||||
///Notify the host application that a request for Geolocation permissions, made with a previous call to [androidOnGeolocationPermissionsShowPrompt] has been canceled.
|
///Notify the host application that a request for Geolocation permissions, made with a previous call to [androidOnGeolocationPermissionsShowPrompt] has been canceled.
|
||||||
|
@ -433,7 +433,7 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsHidePrompt()
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onGeolocationPermissionsHidePrompt()
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
androidOnGeolocationPermissionsHidePrompt;
|
androidOnGeolocationPermissionsHidePrompt;
|
||||||
|
|
||||||
///Notify the host application of a resource request and allow the application to return the data.
|
///Notify the host application of a resource request and allow the application to return the data.
|
||||||
|
@ -453,8 +453,8 @@ abstract class WebView {
|
||||||
///**Official Android API**:
|
///**Official Android API**:
|
||||||
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
|
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
|
||||||
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20java.lang.String)
|
///- https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20java.lang.String)
|
||||||
final Future<WebResourceResponse> Function(
|
final Future<WebResourceResponse?> Function(
|
||||||
InAppWebViewController controller, WebResourceRequest request)
|
InAppWebViewController controller, WebResourceRequest request)?
|
||||||
androidShouldInterceptRequest;
|
androidShouldInterceptRequest;
|
||||||
|
|
||||||
///Event called when the renderer currently associated with the WebView becomes unresponsive as a result of a long running blocking task such as the execution of JavaScript.
|
///Event called when the renderer currently associated with the WebView becomes unresponsive as a result of a long running blocking task such as the execution of JavaScript.
|
||||||
|
@ -475,8 +475,8 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android 29+.
|
///**NOTE**: available only on Android 29+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessUnresponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessUnresponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessUnresponsive;
|
androidOnRenderProcessUnresponsive;
|
||||||
|
|
||||||
///Event called once when an unresponsive renderer currently associated with the WebView becomes responsive.
|
///Event called once when an unresponsive renderer currently associated with the WebView becomes responsive.
|
||||||
|
@ -490,8 +490,8 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android 29+.
|
///**NOTE**: available only on Android 29+.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessResponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewRenderProcessClient#onRenderProcessResponsive(android.webkit.WebView,%20android.webkit.WebViewRenderProcess)
|
||||||
final Future<WebViewRenderProcessAction> Function(
|
final Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, String url)
|
InAppWebViewController controller, String? url)?
|
||||||
androidOnRenderProcessResponsive;
|
androidOnRenderProcessResponsive;
|
||||||
|
|
||||||
///Event fired when the given WebView's render process has exited.
|
///Event fired when the given WebView's render process has exited.
|
||||||
|
@ -504,7 +504,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onRenderProcessGone(android.webkit.WebView,%20android.webkit.RenderProcessGoneDetail)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onRenderProcessGone(android.webkit.WebView,%20android.webkit.RenderProcessGoneDetail)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, RenderProcessGoneDetail detail)
|
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
||||||
androidOnRenderProcessGone;
|
androidOnRenderProcessGone;
|
||||||
|
|
||||||
///As the host application if the browser should resend data as the requested page was a result of a POST. The default is to not resend the data.
|
///As the host application if the browser should resend data as the requested page was a result of a POST. The default is to not resend the data.
|
||||||
|
@ -512,8 +512,8 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onFormResubmission(android.webkit.WebView,%20android.os.Message,%20android.os.Message)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onFormResubmission(android.webkit.WebView,%20android.os.Message,%20android.os.Message)
|
||||||
final Future<FormResubmissionAction> Function(
|
final Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, String url) androidOnFormResubmission;
|
InAppWebViewController controller, String? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
///Event fired when the scale applied to the WebView has changed.
|
///Event fired when the scale applied to the WebView has changed.
|
||||||
///
|
///
|
||||||
|
@ -525,7 +525,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
androidOnScaleChanged;
|
androidOnScaleChanged;
|
||||||
|
|
||||||
///Event fired when there is a request to display and focus for this WebView.
|
///Event fired when there is a request to display and focus for this WebView.
|
||||||
|
@ -534,7 +534,7 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onRequestFocus(android.webkit.WebView)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onRequestFocus(android.webkit.WebView)
|
||||||
final void Function(InAppWebViewController controller) androidOnRequestFocus;
|
final void Function(InAppWebViewController controller)? androidOnRequestFocus;
|
||||||
|
|
||||||
///Event fired when there is new favicon for the current page.
|
///Event fired when there is new favicon for the current page.
|
||||||
///
|
///
|
||||||
|
@ -543,7 +543,7 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedIcon(android.webkit.WebView,%20android.graphics.Bitmap)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedIcon(android.webkit.WebView,%20android.graphics.Bitmap)
|
||||||
final void Function(InAppWebViewController controller, Uint8List icon)
|
final void Function(InAppWebViewController controller, Uint8List icon)?
|
||||||
androidOnReceivedIcon;
|
androidOnReceivedIcon;
|
||||||
|
|
||||||
///Event fired when there is an url for an apple-touch-icon.
|
///Event fired when there is an url for an apple-touch-icon.
|
||||||
|
@ -556,7 +556,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTouchIconUrl(android.webkit.WebView,%20java.lang.String,%20boolean)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTouchIconUrl(android.webkit.WebView,%20java.lang.String,%20boolean)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, String url, bool precomposed)
|
InAppWebViewController controller, String url, bool precomposed)?
|
||||||
androidOnReceivedTouchIconUrl;
|
androidOnReceivedTouchIconUrl;
|
||||||
|
|
||||||
///Event fired when the client should display a dialog to confirm navigation away from the current page.
|
///Event fired when the client should display a dialog to confirm navigation away from the current page.
|
||||||
|
@ -572,9 +572,9 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on Android.
|
///**NOTE**: available only on Android.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsBeforeUnload(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsBeforeUnload(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult)
|
||||||
final Future<JsBeforeUnloadResponse> Function(
|
final Future<JsBeforeUnloadResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
JsBeforeUnloadRequest jsBeforeUnloadRequest) androidOnJsBeforeUnload;
|
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
||||||
|
|
||||||
///Event fired when a request to automatically log in the user has been processed.
|
///Event fired when a request to automatically log in the user has been processed.
|
||||||
///
|
///
|
||||||
|
@ -584,7 +584,7 @@ abstract class WebView {
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedLoginRequest(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedLoginRequest(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String)
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, LoginRequest loginRequest)
|
InAppWebViewController controller, LoginRequest loginRequest)?
|
||||||
androidOnReceivedLoginRequest;
|
androidOnReceivedLoginRequest;
|
||||||
|
|
||||||
///Invoked when the web view's web content process is terminated.
|
///Invoked when the web view's web content process is terminated.
|
||||||
|
@ -592,7 +592,7 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on iOS.
|
///**NOTE**: available only on iOS.
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnWebContentProcessDidTerminate;
|
iosOnWebContentProcessDidTerminate;
|
||||||
|
|
||||||
///Called when a web view receives a server redirect.
|
///Called when a web view receives a server redirect.
|
||||||
|
@ -600,26 +600,26 @@ abstract class WebView {
|
||||||
///**NOTE**: available only on iOS.
|
///**NOTE**: available only on iOS.
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455627-webview
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455627-webview
|
||||||
final void Function(InAppWebViewController controller)
|
final void Function(InAppWebViewController controller)?
|
||||||
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
||||||
|
|
||||||
///Initial url that will be loaded.
|
///Initial url that will be loaded.
|
||||||
final String initialUrl;
|
final String? initialUrl;
|
||||||
|
|
||||||
///Initial asset file that will be loaded. See [InAppWebViewController.loadFile] for explanation.
|
///Initial asset file that will be loaded. See [InAppWebViewController.loadFile] for explanation.
|
||||||
final String initialFile;
|
final String? initialFile;
|
||||||
|
|
||||||
///Initial [InAppWebViewInitialData] that will be loaded.
|
///Initial [InAppWebViewInitialData] that will be loaded.
|
||||||
final InAppWebViewInitialData initialData;
|
final InAppWebViewInitialData? initialData;
|
||||||
|
|
||||||
///Initial headers that will be used.
|
///Initial headers that will be used.
|
||||||
final Map<String, String> initialHeaders;
|
final Map<String, String>? initialHeaders;
|
||||||
|
|
||||||
///Initial options that will be used.
|
///Initial options that will be used.
|
||||||
final InAppWebViewGroupOptions initialOptions;
|
final InAppWebViewGroupOptions? initialOptions;
|
||||||
|
|
||||||
///Context menu which contains custom menu items to be shown when [ContextMenu] is presented.
|
///Context menu which contains custom menu items to be shown when [ContextMenu] is presented.
|
||||||
final ContextMenu contextMenu;
|
final ContextMenu? contextMenu;
|
||||||
|
|
||||||
WebView(
|
WebView(
|
||||||
{this.windowId,
|
{this.windowId,
|
||||||
|
|
|
@ -14,7 +14,7 @@ class WebViewOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebViewOptions fromMap(Map<String, dynamic> map) {
|
static WebViewOptions fromMap(Map<String, dynamic> map) {
|
||||||
return null;
|
return new WebViewOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
WebViewOptions copy() {
|
WebViewOptions copy() {
|
||||||
|
@ -37,7 +37,7 @@ class BrowserOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
static BrowserOptions fromMap(Map<String, dynamic> map) {
|
static BrowserOptions fromMap(Map<String, dynamic> map) {
|
||||||
return null;
|
return new BrowserOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserOptions copy() {
|
BrowserOptions copy() {
|
||||||
|
@ -60,7 +60,7 @@ class ChromeSafariBrowserOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChromeSafariBrowserOptions fromMap(Map<String, dynamic> map) {
|
static ChromeSafariBrowserOptions fromMap(Map<String, dynamic> map) {
|
||||||
return null;
|
return new ChromeSafariBrowserOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChromeSafariBrowserOptions copy() {
|
ChromeSafariBrowserOptions copy() {
|
||||||
|
@ -105,12 +105,6 @@ class InAppWebViewOptions
|
||||||
///Set to `true` to enable JavaScript. The default value is `true`.
|
///Set to `true` to enable JavaScript. The default value is `true`.
|
||||||
bool javaScriptEnabled;
|
bool javaScriptEnabled;
|
||||||
|
|
||||||
///Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
|
|
||||||
///This flag can be enabled in order to facilitate debugging of web layouts and JavaScript code running inside WebViews. The default is `false`.
|
|
||||||
///
|
|
||||||
///**NOTE**: on iOS the debugging mode is always enabled.
|
|
||||||
bool debuggingEnabled;
|
|
||||||
|
|
||||||
///Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`.
|
///Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`.
|
||||||
bool javaScriptCanOpenWindowsAutomatically;
|
bool javaScriptCanOpenWindowsAutomatically;
|
||||||
|
|
||||||
|
@ -120,7 +114,7 @@ class InAppWebViewOptions
|
||||||
bool mediaPlaybackRequiresUserGesture;
|
bool mediaPlaybackRequiresUserGesture;
|
||||||
|
|
||||||
///Sets the minimum font size. The default value is `8` for Android, `0` for iOS.
|
///Sets the minimum font size. The default value is `8` for Android, `0` for iOS.
|
||||||
int minimumFontSize;
|
int? minimumFontSize;
|
||||||
|
|
||||||
///Define whether the vertical scrollbar should be drawn or not. The default value is `true`.
|
///Define whether the vertical scrollbar should be drawn or not. The default value is `true`.
|
||||||
bool verticalScrollBarEnabled;
|
bool verticalScrollBarEnabled;
|
||||||
|
@ -141,7 +135,7 @@ class InAppWebViewOptions
|
||||||
///Sets the content mode that the WebView needs to use when loading and rendering a webpage. The default value is [UserPreferredContentMode.RECOMMENDED].
|
///Sets the content mode that the WebView needs to use when loading and rendering a webpage. The default value is [UserPreferredContentMode.RECOMMENDED].
|
||||||
///
|
///
|
||||||
///**NOTE**: available on iOS 13.0+.
|
///**NOTE**: available on iOS 13.0+.
|
||||||
UserPreferredContentMode preferredContentMode;
|
UserPreferredContentMode? preferredContentMode;
|
||||||
|
|
||||||
///Set to `true` to be able to listen at the [shouldInterceptAjaxRequest] event. The default value is `false`.
|
///Set to `true` to be able to listen at the [shouldInterceptAjaxRequest] event. The default value is `false`.
|
||||||
bool useShouldInterceptAjaxRequest;
|
bool useShouldInterceptAjaxRequest;
|
||||||
|
@ -152,6 +146,8 @@ class InAppWebViewOptions
|
||||||
///Set to `true` to open a browser window with incognito mode. The default value is `false`.
|
///Set to `true` to open a browser window with incognito mode. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on iOS 9.0+.
|
///**NOTE**: available on iOS 9.0+.
|
||||||
|
///On Android, by setting this option to `true`, it will clear all the cookies of all WebView instances,
|
||||||
|
///because there isn't any way to make the website data store non-persistent for the specific WebView instance such as on iOS.
|
||||||
bool incognito;
|
bool incognito;
|
||||||
|
|
||||||
///Sets whether WebView should use browser caching. The default value is `true`.
|
///Sets whether WebView should use browser caching. The default value is `true`.
|
||||||
|
@ -182,7 +178,6 @@ class InAppWebViewOptions
|
||||||
this.userAgent = "",
|
this.userAgent = "",
|
||||||
this.applicationNameForUserAgent = "",
|
this.applicationNameForUserAgent = "",
|
||||||
this.javaScriptEnabled = true,
|
this.javaScriptEnabled = true,
|
||||||
this.debuggingEnabled = false,
|
|
||||||
this.javaScriptCanOpenWindowsAutomatically = false,
|
this.javaScriptCanOpenWindowsAutomatically = false,
|
||||||
this.mediaPlaybackRequiresUserGesture = true,
|
this.mediaPlaybackRequiresUserGesture = true,
|
||||||
this.minimumFontSize,
|
this.minimumFontSize,
|
||||||
|
@ -221,7 +216,6 @@ class InAppWebViewOptions
|
||||||
"userAgent": userAgent,
|
"userAgent": userAgent,
|
||||||
"applicationNameForUserAgent": applicationNameForUserAgent,
|
"applicationNameForUserAgent": applicationNameForUserAgent,
|
||||||
"javaScriptEnabled": javaScriptEnabled,
|
"javaScriptEnabled": javaScriptEnabled,
|
||||||
"debuggingEnabled": debuggingEnabled,
|
|
||||||
"javaScriptCanOpenWindowsAutomatically":
|
"javaScriptCanOpenWindowsAutomatically":
|
||||||
javaScriptCanOpenWindowsAutomatically,
|
javaScriptCanOpenWindowsAutomatically,
|
||||||
"mediaPlaybackRequiresUserGesture": mediaPlaybackRequiresUserGesture,
|
"mediaPlaybackRequiresUserGesture": mediaPlaybackRequiresUserGesture,
|
||||||
|
@ -244,7 +238,7 @@ class InAppWebViewOptions
|
||||||
|
|
||||||
static InAppWebViewOptions fromMap(Map<String, dynamic> map) {
|
static InAppWebViewOptions fromMap(Map<String, dynamic> map) {
|
||||||
List<ContentBlocker> contentBlockers = [];
|
List<ContentBlocker> contentBlockers = [];
|
||||||
List<dynamic> contentBlockersMapList = map["contentBlockers"];
|
List<dynamic>? contentBlockersMapList = map["contentBlockers"];
|
||||||
if (contentBlockersMapList != null) {
|
if (contentBlockersMapList != null) {
|
||||||
contentBlockersMapList.forEach((contentBlocker) {
|
contentBlockersMapList.forEach((contentBlocker) {
|
||||||
contentBlockers.add(ContentBlocker.fromMap(
|
contentBlockers.add(ContentBlocker.fromMap(
|
||||||
|
@ -261,7 +255,6 @@ class InAppWebViewOptions
|
||||||
options.userAgent = map["userAgent"];
|
options.userAgent = map["userAgent"];
|
||||||
options.applicationNameForUserAgent = map["applicationNameForUserAgent"];
|
options.applicationNameForUserAgent = map["applicationNameForUserAgent"];
|
||||||
options.javaScriptEnabled = map["javaScriptEnabled"];
|
options.javaScriptEnabled = map["javaScriptEnabled"];
|
||||||
options.debuggingEnabled = map["debuggingEnabled"];
|
|
||||||
options.javaScriptCanOpenWindowsAutomatically =
|
options.javaScriptCanOpenWindowsAutomatically =
|
||||||
map["javaScriptCanOpenWindowsAutomatically"];
|
map["javaScriptCanOpenWindowsAutomatically"];
|
||||||
options.mediaPlaybackRequiresUserGesture =
|
options.mediaPlaybackRequiresUserGesture =
|
||||||
|
@ -339,7 +332,7 @@ class AndroidInAppWebViewOptions
|
||||||
///Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin.
|
///Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 21+.
|
///**NOTE**: available on Android 21+.
|
||||||
AndroidMixedContentMode mixedContentMode;
|
AndroidMixedContentMode? mixedContentMode;
|
||||||
|
|
||||||
///Enables or disables content URL access within WebView. Content URL access allows WebView to load content from a content provider installed in the system. The default value is `true`.
|
///Enables or disables content URL access within WebView. Content URL access allows WebView to load content from a content provider installed in the system. The default value is `true`.
|
||||||
bool allowContentAccess;
|
bool allowContentAccess;
|
||||||
|
@ -360,7 +353,7 @@ class AndroidInAppWebViewOptions
|
||||||
|
|
||||||
///Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this option must be set a path to which the application can write.
|
///Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this option must be set a path to which the application can write.
|
||||||
///This option is used one time: repeated calls are ignored.
|
///This option is used one time: repeated calls are ignored.
|
||||||
String appCachePath;
|
String? appCachePath;
|
||||||
|
|
||||||
///Sets whether the WebView should not load image resources from the network (resources accessed via http and https URI schemes). The default value is `false`.
|
///Sets whether the WebView should not load image resources from the network (resources accessed via http and https URI schemes). The default value is `false`.
|
||||||
bool blockNetworkImage;
|
bool blockNetworkImage;
|
||||||
|
@ -370,7 +363,7 @@ class AndroidInAppWebViewOptions
|
||||||
|
|
||||||
///Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed.
|
///Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed.
|
||||||
///When navigating back, content is not revalidated, instead the content is just retrieved from the cache. The default value is [AndroidCacheMode.LOAD_DEFAULT].
|
///When navigating back, content is not revalidated, instead the content is just retrieved from the cache. The default value is [AndroidCacheMode.LOAD_DEFAULT].
|
||||||
AndroidCacheMode cacheMode;
|
AndroidCacheMode? cacheMode;
|
||||||
|
|
||||||
///Sets the cursive font family name. The default value is `"cursive"`.
|
///Sets the cursive font family name. The default value is `"cursive"`.
|
||||||
String cursiveFontFamily;
|
String cursiveFontFamily;
|
||||||
|
@ -387,7 +380,7 @@ class AndroidInAppWebViewOptions
|
||||||
///Disables the action mode menu items according to menuItems flag.
|
///Disables the action mode menu items according to menuItems flag.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 24+.
|
///**NOTE**: available on Android 24+.
|
||||||
AndroidActionModeMenuItem disabledActionModeMenuItems;
|
AndroidActionModeMenuItem? disabledActionModeMenuItems;
|
||||||
|
|
||||||
///Sets the fantasy font family name. The default value is `"fantasy"`.
|
///Sets the fantasy font family name. The default value is `"fantasy"`.
|
||||||
String fantasyFontFamily;
|
String fantasyFontFamily;
|
||||||
|
@ -398,13 +391,13 @@ class AndroidInAppWebViewOptions
|
||||||
///Set the force dark mode for this WebView. The default value is [AndroidForceDark.FORCE_DARK_OFF].
|
///Set the force dark mode for this WebView. The default value is [AndroidForceDark.FORCE_DARK_OFF].
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 29+.
|
///**NOTE**: available on Android 29+.
|
||||||
AndroidForceDark forceDark;
|
AndroidForceDark? forceDark;
|
||||||
|
|
||||||
///Sets whether Geolocation API is enabled. The default value is `true`.
|
///Sets whether Geolocation API is enabled. The default value is `true`.
|
||||||
bool geolocationEnabled;
|
bool geolocationEnabled;
|
||||||
|
|
||||||
///Sets the underlying layout algorithm. This will cause a re-layout of the WebView.
|
///Sets the underlying layout algorithm. This will cause a re-layout of the WebView.
|
||||||
AndroidLayoutAlgorithm layoutAlgorithm;
|
AndroidLayoutAlgorithm? layoutAlgorithm;
|
||||||
|
|
||||||
///Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width.
|
///Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width.
|
||||||
///This setting is taken into account when the content width is greater than the width of the WebView control, for example, when [useWideViewPort] is enabled.
|
///This setting is taken into account when the content width is greater than the width of the WebView control, for example, when [useWideViewPort] is enabled.
|
||||||
|
@ -468,7 +461,7 @@ class AndroidInAppWebViewOptions
|
||||||
|
|
||||||
///Regular expression used by [shouldOverrideUrlLoading] event to cancel navigation requests for frames that are not the main frame.
|
///Regular expression used by [shouldOverrideUrlLoading] event to cancel navigation requests for frames that are not the main frame.
|
||||||
///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
|
///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
|
||||||
String regexToCancelSubFramesLoading;
|
String? regexToCancelSubFramesLoading;
|
||||||
|
|
||||||
///Set to `true` to enable Flutter's new Hybrid Composition. The default value is `false`.
|
///Set to `true` to enable Flutter's new Hybrid Composition. The default value is `false`.
|
||||||
///Hybrid Composition is supported starting with Flutter v1.20+.
|
///Hybrid Composition is supported starting with Flutter v1.20+.
|
||||||
|
@ -486,11 +479,11 @@ class AndroidInAppWebViewOptions
|
||||||
///Sets the WebView's over-scroll mode.
|
///Sets the WebView's over-scroll mode.
|
||||||
///Setting the over-scroll mode of a WebView will have an effect only if the WebView is capable of scrolling.
|
///Setting the over-scroll mode of a WebView will have an effect only if the WebView is capable of scrolling.
|
||||||
///The default value is [AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS].
|
///The default value is [AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS].
|
||||||
AndroidOverScrollMode overScrollMode;
|
AndroidOverScrollMode? overScrollMode;
|
||||||
|
|
||||||
///Informs WebView of the network state.
|
///Informs WebView of the network state.
|
||||||
///This is used to set the JavaScript property `window.navigator.isOnline` and generates the online/offline event as specified in HTML5, sec. 5.7.7.
|
///This is used to set the JavaScript property `window.navigator.isOnline` and generates the online/offline event as specified in HTML5, sec. 5.7.7.
|
||||||
bool networkAvailable;
|
bool? networkAvailable;
|
||||||
|
|
||||||
///Specifies the style of the scrollbars. The scrollbars can be overlaid or inset.
|
///Specifies the style of the scrollbars. The scrollbars can be overlaid or inset.
|
||||||
///When inset, they add to the padding of the view. And the scrollbars can be drawn inside the padding area or on the edge of the view.
|
///When inset, they add to the padding of the view. And the scrollbars can be drawn inside the padding area or on the edge of the view.
|
||||||
|
@ -498,28 +491,28 @@ class AndroidInAppWebViewOptions
|
||||||
///you can use SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to appear at the edge of the view, ignoring the padding,
|
///you can use SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to appear at the edge of the view, ignoring the padding,
|
||||||
///then you can use SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
|
///then you can use SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
|
||||||
///The default value is [AndroidScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY].
|
///The default value is [AndroidScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY].
|
||||||
AndroidScrollBarStyle scrollBarStyle;
|
AndroidScrollBarStyle? scrollBarStyle;
|
||||||
|
|
||||||
///Sets the position of the vertical scroll bar.
|
///Sets the position of the vertical scroll bar.
|
||||||
///The default value is [AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT].
|
///The default value is [AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT].
|
||||||
AndroidVerticalScrollbarPosition verticalScrollbarPosition;
|
AndroidVerticalScrollbarPosition? verticalScrollbarPosition;
|
||||||
|
|
||||||
///Defines the delay in milliseconds that a scrollbar waits before fade out.
|
///Defines the delay in milliseconds that a scrollbar waits before fade out.
|
||||||
int scrollBarDefaultDelayBeforeFade;
|
int? scrollBarDefaultDelayBeforeFade;
|
||||||
|
|
||||||
///Defines whether scrollbars will fade when the view is not scrolling.
|
///Defines whether scrollbars will fade when the view is not scrolling.
|
||||||
///The default value is `true`.
|
///The default value is `true`.
|
||||||
bool scrollbarFadingEnabled;
|
bool scrollbarFadingEnabled;
|
||||||
|
|
||||||
///Defines the scrollbar fade duration in milliseconds.
|
///Defines the scrollbar fade duration in milliseconds.
|
||||||
int scrollBarFadeDuration;
|
int? scrollBarFadeDuration;
|
||||||
|
|
||||||
///Sets the renderer priority policy for this WebView.
|
///Sets the renderer priority policy for this WebView.
|
||||||
RendererPriorityPolicy rendererPriorityPolicy;
|
RendererPriorityPolicy? rendererPriorityPolicy;
|
||||||
|
|
||||||
///Sets whether the default Android error page should be disabled.
|
///Sets whether the default Android error page should be disabled.
|
||||||
///The default value is `false`.
|
///The default value is `false`.
|
||||||
bool disableDefaultErrorPage;
|
bool? disableDefaultErrorPage;
|
||||||
|
|
||||||
AndroidInAppWebViewOptions({
|
AndroidInAppWebViewOptions({
|
||||||
this.textZoom = 100,
|
this.textZoom = 100,
|
||||||
|
@ -899,8 +892,11 @@ class IOSInAppWebViewOptions
|
||||||
List<IOSWKDataDetectorTypes> dataDetectorTypes = [];
|
List<IOSWKDataDetectorTypes> dataDetectorTypes = [];
|
||||||
List<String> dataDetectorTypesList =
|
List<String> dataDetectorTypesList =
|
||||||
List<String>.from(map["dataDetectorTypes"] ?? []);
|
List<String>.from(map["dataDetectorTypes"] ?? []);
|
||||||
dataDetectorTypesList.forEach((dataDetectorType) {
|
dataDetectorTypesList.forEach((dataDetectorTypeValue) {
|
||||||
dataDetectorTypes.add(IOSWKDataDetectorTypes.fromValue(dataDetectorType));
|
var dataDetectorType = IOSWKDataDetectorTypes.fromValue(dataDetectorTypeValue);
|
||||||
|
if (dataDetectorType != null) {
|
||||||
|
dataDetectorTypes.add(dataDetectorType);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
IOSInAppWebViewOptions options = IOSInAppWebViewOptions();
|
IOSInAppWebViewOptions options = IOSInAppWebViewOptions();
|
||||||
|
@ -920,7 +916,7 @@ class IOSInAppWebViewOptions
|
||||||
options.isFraudulentWebsiteWarningEnabled =
|
options.isFraudulentWebsiteWarningEnabled =
|
||||||
map["isFraudulentWebsiteWarningEnabled"];
|
map["isFraudulentWebsiteWarningEnabled"];
|
||||||
options.selectionGranularity =
|
options.selectionGranularity =
|
||||||
IOSWKSelectionGranularity.fromValue(map["selectionGranularity"]);
|
IOSWKSelectionGranularity.fromValue(map["selectionGranularity"])!;
|
||||||
options.dataDetectorTypes = dataDetectorTypes;
|
options.dataDetectorTypes = dataDetectorTypes;
|
||||||
options.sharedCookiesEnabled = map["sharedCookiesEnabled"];
|
options.sharedCookiesEnabled = map["sharedCookiesEnabled"];
|
||||||
options.automaticallyAdjustsScrollIndicatorInsets =
|
options.automaticallyAdjustsScrollIndicatorInsets =
|
||||||
|
@ -928,7 +924,7 @@ class IOSInAppWebViewOptions
|
||||||
options.accessibilityIgnoresInvertColors =
|
options.accessibilityIgnoresInvertColors =
|
||||||
map["accessibilityIgnoresInvertColors"];
|
map["accessibilityIgnoresInvertColors"];
|
||||||
options.decelerationRate =
|
options.decelerationRate =
|
||||||
IOSUIScrollViewDecelerationRate.fromValue(map["decelerationRate"]);
|
IOSUIScrollViewDecelerationRate.fromValue(map["decelerationRate"])!;
|
||||||
options.alwaysBounceVertical = map["alwaysBounceVertical"];
|
options.alwaysBounceVertical = map["alwaysBounceVertical"];
|
||||||
options.alwaysBounceHorizontal = map["alwaysBounceHorizontal"];
|
options.alwaysBounceHorizontal = map["alwaysBounceHorizontal"];
|
||||||
options.scrollsToTop = map["scrollsToTop"];
|
options.scrollsToTop = map["scrollsToTop"];
|
||||||
|
@ -937,7 +933,7 @@ class IOSInAppWebViewOptions
|
||||||
options.minimumZoomScale = map["minimumZoomScale"];
|
options.minimumZoomScale = map["minimumZoomScale"];
|
||||||
options.contentInsetAdjustmentBehavior =
|
options.contentInsetAdjustmentBehavior =
|
||||||
IOSUIScrollViewContentInsetAdjustmentBehavior.fromValue(
|
IOSUIScrollViewContentInsetAdjustmentBehavior.fromValue(
|
||||||
map["contentInsetAdjustmentBehavior"]);
|
map["contentInsetAdjustmentBehavior"])!;
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,9 +1123,9 @@ class IOSInAppBrowserOptions implements BrowserOptions, IosOptions {
|
||||||
options.closeButtonCaption = map["closeButtonCaption"];
|
options.closeButtonCaption = map["closeButtonCaption"];
|
||||||
options.closeButtonColor = map["closeButtonColor"];
|
options.closeButtonColor = map["closeButtonColor"];
|
||||||
options.presentationStyle =
|
options.presentationStyle =
|
||||||
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"]);
|
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"])!;
|
||||||
options.transitionStyle =
|
options.transitionStyle =
|
||||||
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"]);
|
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"])!;
|
||||||
options.spinner = map["spinner"];
|
options.spinner = map["spinner"];
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -1173,7 +1169,7 @@ class AndroidChromeCustomTabsOptions
|
||||||
///value of null, all components in all applications will considered.
|
///value of null, all components in all applications will considered.
|
||||||
///If non-null, the Intent can only match the components in the given
|
///If non-null, the Intent can only match the components in the given
|
||||||
///application package.
|
///application package.
|
||||||
String packageName;
|
String? packageName;
|
||||||
|
|
||||||
///Set to `true` to enable Keep Alive. The default value is `false`.
|
///Set to `true` to enable Keep Alive. The default value is `false`.
|
||||||
bool keepAliveEnabled;
|
bool keepAliveEnabled;
|
||||||
|
@ -1285,13 +1281,13 @@ class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
|
||||||
options.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
options.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
||||||
options.barCollapsingEnabled = map["barCollapsingEnabled"];
|
options.barCollapsingEnabled = map["barCollapsingEnabled"];
|
||||||
options.dismissButtonStyle =
|
options.dismissButtonStyle =
|
||||||
IOSSafariDismissButtonStyle.fromValue(map["dismissButtonStyle"]);
|
IOSSafariDismissButtonStyle.fromValue(map["dismissButtonStyle"])!;
|
||||||
options.preferredBarTintColor = map["preferredBarTintColor"];
|
options.preferredBarTintColor = map["preferredBarTintColor"];
|
||||||
options.preferredControlTintColor = map["preferredControlTintColor"];
|
options.preferredControlTintColor = map["preferredControlTintColor"];
|
||||||
options.presentationStyle =
|
options.presentationStyle =
|
||||||
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"]);
|
IOSUIModalPresentationStyle.fromValue(map["presentationStyle"])!;
|
||||||
options.transitionStyle =
|
options.transitionStyle =
|
||||||
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"]);
|
IOSUIModalTransitionStyle.fromValue(map["transitionStyle"])!;
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,6 @@ app.post("/test-ajax-post", (req, res) => {
|
||||||
res.send(JSON.stringify({
|
res.send(JSON.stringify({
|
||||||
"firstname": req.body.firstname,
|
"firstname": req.body.firstname,
|
||||||
"lastname": req.body.lastname,
|
"lastname": req.body.lastname,
|
||||||
"fullname": req.body.firstname + " " + req.body.lastname,
|
|
||||||
}))
|
}))
|
||||||
res.end()
|
res.end()
|
||||||
})
|
})
|
||||||
|
|
15
pubspec.yaml
15
pubspec.yaml
|
@ -1,17 +1,22 @@
|
||||||
name: flutter_inappwebview
|
name: flutter_inappwebview
|
||||||
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
|
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
|
||||||
version: 5.0.0
|
version: 5.0.0-nullsafety.0
|
||||||
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.12.0-0 <3.0.0"
|
||||||
flutter: ">=1.12.13+hotfix.5"
|
flutter: ">=1.22.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
uuid: ^2.0.0
|
uuid: ^3.0.0-nullsafety.0
|
||||||
mime: ^0.9.6+2
|
mime: ^1.0.0-nullsafety.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
pedantic: ^1.10.0-nullsafety.1
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||||
|
|
4
test.sh
4
test.sh
|
@ -1,4 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# flutter clean && flutter run -t ./lib/main.dart -d 'iPhone di Lorenzo' --debug --no-sound-null-safety
|
||||||
|
|
||||||
# on linux/macOS local IP can be found using $(ipconfig getifaddr en0)
|
# on linux/macOS local IP can be found using $(ipconfig getifaddr en0)
|
||||||
export NODE_SERVER_IP=$1
|
export NODE_SERVER_IP=$1
|
||||||
dart tool/env.dart
|
dart tool/env.dart
|
||||||
|
@ -7,5 +9,5 @@ node index.js &
|
||||||
flutter clean
|
flutter clean
|
||||||
cd ../example
|
cd ../example
|
||||||
flutter clean
|
flutter clean
|
||||||
flutter driver -t test_driver/app.dart
|
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart
|
||||||
kill $(jobs -p)
|
kill $(jobs -p)
|
|
@ -7,6 +7,6 @@ Future<void> main() async {
|
||||||
'NODE_SERVER_IP': Platform.environment['NODE_SERVER_IP'],
|
'NODE_SERVER_IP': Platform.environment['NODE_SERVER_IP'],
|
||||||
};
|
};
|
||||||
|
|
||||||
final filename = 'example/test_driver/.env.dart';
|
final filename = 'example/integration_test/.env.dart';
|
||||||
await File(filename).writeAsString('final environment = ${json.encode(config)};');
|
await File(filename).writeAsString('final environment = ${json.encode(config)};');
|
||||||
}
|
}
|
Loading…
Reference in New Issue