Commit 3f1ed3ba authored by Lorenzo Pichilli's avatar Lorenzo Pichilli

added ScreenshotConfiguration class and screenshotConfiguration optional...

added ScreenshotConfiguration class and screenshotConfiguration optional argument to takeScreenshot WebView method
parent 7b681df9
......@@ -5,12 +5,14 @@
- Added `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options also for iOS (also thanks to [liranhao](https://github.com/liranhao))
- Added limited cookies support on iOS below 11.0 using JavaScript
- Added `IOSCookieManager` class and `CookieManager.instance().ios.getAllCookies` iOS-specific method
- Added `UserScript`, `UserScriptInjectionTime`, `ContentWorld`, `AndroidWebViewFeature`, `AndroidServiceWorkerController`, `AndroidServiceWorkerClient` classes
- Added `UserScript`, `UserScriptInjectionTime`, `ContentWorld`, `AndroidWebViewFeature`, `AndroidServiceWorkerController`, `AndroidServiceWorkerClient`, `ScreenshotConfiguration` classes
- Added `initialUserScripts` WebView option
- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeAllUserScripts`, `callAsyncJavaScript` WebView methods
- Added `contentWorld` argument to `evaluateJavascript` WebView method
- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains` iOS-specific webview options
- Added `handlesURLScheme` iOS-specific webview method
- Added `iosAnimated` optional argument to `zoomBy` WebView method
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
- Updated integration tests
- 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))
......@@ -41,7 +43,7 @@
- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
- Added `iosAnimated` optional argument to `zoomBy` WebView method
- Changed `zoomBy` WebView method signature
## 4.0.0+4
......
......@@ -1132,7 +1132,7 @@ final public class InAppWebView extends InputAwareWebView {
WebStorage.getInstance().deleteAllData();
}
public void takeScreenshot(final MethodChannel.Result result) {
public void takeScreenshot(final Map<String, Object> screenshotConfiguration, final MethodChannel.Result result) {
headlessHandler.post(new Runnable() {
@Override
public void run() {
......@@ -1156,29 +1156,59 @@ final public class InAppWebView extends InputAwareWebView {
scrollOffset = 0;
}
Bitmap resized = Bitmap.createBitmap(
b, 0, scrollOffset, b.getWidth(), measuredHeight);
int rectX = 0;
int rectY = scrollOffset;
int rectWidth = b.getWidth();
int rectHeight = measuredHeight;
Bitmap resized = Bitmap.createBitmap(b, rectX, rectY, rectWidth, rectHeight);
Map<String, Double> rect = (Map<String, Double>) screenshotConfiguration.get("rect");
if (rect != null) {
rectX = (int) Math.floor(rect.get("x") * scale + 0.5);
rectY = (int) Math.floor(rect.get("y") * scale + 0.5);
rectWidth = Math.min(resized.getWidth(), (int) Math.floor(rect.get("width") * scale + 0.5));
rectHeight = Math.min(resized.getHeight(), (int) Math.floor(rect.get("height") * scale + 0.5));
resized = Bitmap.createBitmap(
b,
rectX,
rectY,
rectWidth,
rectHeight);
}
Double snapshotWidth = (Double) screenshotConfiguration.get("snapshotWidth");
if (snapshotWidth != null) {
int dstWidth = (int) Math.floor(snapshotWidth * scale + 0.5);
float ratioBitmap = (float) resized.getWidth() / (float) resized.getHeight();
int dstHeight = (int) ((float) dstWidth / ratioBitmap);
resized = Bitmap.createScaledBitmap(resized, dstWidth, dstHeight, true);
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.PNG;
try {
compressFormat = Bitmap.CompressFormat.valueOf((String) screenshotConfiguration.get("compressFormat"));
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
resized.compress(
compressFormat,
(Integer) screenshotConfiguration.get("quality"),
byteArrayOutputStream);
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
String errorMessage = e.getMessage();
if (errorMessage != null) {
Log.e(LOG_TAG, errorMessage);
}
}
resized.recycle();
result.success(byteArrayOutputStream.toByteArray());
} catch (IllegalArgumentException e) {
String errorMessage = e.getMessage();
if (errorMessage != null) {
Log.e(LOG_TAG, errorMessage);
}
e.printStackTrace();
result.success(null);
}
}
......
......@@ -140,8 +140,10 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
result.success((webView != null) && webView.isLoading());
break;
case "takeScreenshot":
if (webView != null)
webView.takeScreenshot(result);
if (webView != null) {
Map<String, Object> screenshotConfiguration = (Map<String, Object>) call.argument("screenshotConfiguration");
webView.takeScreenshot(screenshotConfiguration, result);
}
else
result.success(null);
break;
......
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.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":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.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":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-07 16:14:15.833284","version":"1.26.0-18.0.pre.90"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.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":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.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":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-08 01:11:20.039088","version":"1.26.0-18.0.pre.90"}
\ No newline at end of file
#
# 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|
s.name = 'Flutter'
s.version = '1.0.0'
s.summary = 'High-performance, high-fidelity mobile apps.'
s.homepage = 'https://flutter.io'
s.license = { :type => 'MIT' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
# 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
......@@ -2,13 +2,12 @@
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue,FLUTTER_WEB_AUTO_DETECT%3Dtrue"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json"
export "PACKAGE_CONFIG=.packages"
......@@ -14,6 +14,8 @@ class InAppWebViewExampleScreen extends StatefulWidget {
}
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webView;
late ContextMenu contextMenu;
String url = "";
......@@ -80,6 +82,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
key: webViewKey,
// contextMenu: contextMenu,
initialUrl: "https://flutter.dev",
// initialFile: "assets/index.html",
......@@ -135,6 +138,8 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
setState(() {
this.url = url ?? '';
});
// RenderObject renderBox = webViewKey.currentContext!.findRenderObject()!;
// print(renderBox.paintBounds.size);
},
onProgressChanged: (controller, progress) {
setState(() {
......
......@@ -1700,12 +1700,40 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
: currentIndex + steps >= 0
}
public func takeScreenshot (completionHandler: @escaping (_ screenshot: Data?) -> Void) {
public func takeScreenshot (with: [String: Any?]?, completionHandler: @escaping (_ screenshot: Data?) -> Void) {
if #available(iOS 11.0, *) {
takeSnapshot(with: nil, completionHandler: {(image, error) -> Void in
var snapshotConfiguration: WKSnapshotConfiguration? = nil
if let with = with {
snapshotConfiguration = WKSnapshotConfiguration()
if let rect = with["rect"] as? [String: Double] {
snapshotConfiguration!.rect = CGRect(x: rect["x"]!, y: rect["y"]!, width: rect["width"]!, height: rect["height"]!)
}
if let snapshotWidth = with["snapshotWidth"] as? Double {
snapshotConfiguration!.snapshotWidth = NSNumber(value: snapshotWidth)
}
if #available(iOS 13.0, *), let afterScreenUpdates = with["iosAfterScreenUpdates"] as? Bool {
snapshotConfiguration!.afterScreenUpdates = afterScreenUpdates
}
}
takeSnapshot(with: snapshotConfiguration, completionHandler: {(image, error) -> Void in
var imageData: Data? = nil
if let screenshot = image {
imageData = screenshot.pngData()!
if let with = with {
switch with["compressFormat"] as! String {
case "JPEG":
let quality = Float(with["quality"] as! Int) / 100
imageData = screenshot.jpegData(compressionQuality: CGFloat(quality))!
break
case "PNG":
imageData = screenshot.pngData()!
break
default:
imageData = screenshot.pngData()!
}
}
else {
imageData = screenshot.pngData()!
}
}
completionHandler(imageData)
})
......
......@@ -129,7 +129,8 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
break
case "takeScreenshot":
if webView != nil {
webView!.takeScreenshot(completionHandler: { (screenshot) -> Void in
let screenshotConfiguration = arguments!["screenshotConfiguration"] as? [String: Any?]
webView!.takeScreenshot(with: screenshotConfiguration, completionHandler: { (screenshot) -> Void in
result(screenshot)
})
}
......
......@@ -1504,13 +1504,16 @@ class InAppWebViewController {
return this.javaScriptHandlersMap.remove(handlerName);
}
///Takes a screenshot (in PNG format) of the WebView's visible viewport and returns a `Uint8List`. Returns `null` if it wasn't be able to take it.
///Takes a screenshot (in PNG format) of the WebView's visible viewport and returns a [Uint8List]. Returns `null` if it wasn't be able to take it.
///
///[screenshotConfiguration] represents the configuration data to use when generating an image from a web view’s contents.
///
///**NOTE for iOS**: available from iOS 11.0+.
///
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot
Future<Uint8List?> takeScreenshot() async {
Future<Uint8List?> takeScreenshot({ScreenshotConfiguration? screenshotConfiguration}) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('screenshotConfiguration', () => screenshotConfiguration?.toMap());
return await _channel.invokeMethod('takeScreenshot', args);
}
......@@ -1716,7 +1719,8 @@ class InAppWebViewController {
///
///[zoomFactor] represents the zoom factor to apply. On Android, the zoom factor will be clamped to the Webview's zoom limits and, also, this value must be in the range 0.01 (excluded) to 100.0 (included).
///
///[iosAnimated] `true` to animate the transition to the new scale, `false` to make the transition immediate. Available only on iOS.
///[iosAnimated] `true` to animate the transition to the new scale, `false` to make the transition immediate.
///**NOTE**: available only on iOS.
///
///**NOTE**: available on Android 21+.
///
......@@ -1748,7 +1752,8 @@ class InAppWebViewController {
///Gets the selected text.
///
///**NOTE**: This method is implemented with using JavaScript.
///Available only on Android 19+.
///
///**NOTE for Android**: available only on Android 19+.
Future<String?> getSelectedText() async {
Map<String, dynamic> args = <String, dynamic>{};
return await _channel.invokeMethod('getSelectedText', args);
......
......@@ -168,7 +168,7 @@ class InAppWebViewInitialData {
}
///Class representing a resource request of the WebView used by the event [WebView.androidShouldInterceptRequest].
///Available only on Android.
///**NOTE**: available only on Android.
///
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebResourceRequest
class WebResourceRequest {
......@@ -177,12 +177,12 @@ class WebResourceRequest {
///The headers associated with the request.
///
///**NOTE**: Available on Android 21+. For Android < 21 it will be always `null`.
///**NOTE**: available on Android 21+. For Android < 21 it will be always `null`.
Map<String, String>? headers;
///The method associated with the request, for example `GET`.
///
///**NOTE**: Available on Android 21+. For Android < 21 it will be always "GET".
///**NOTE**: available on Android 21+. For Android < 21 it will be always "GET".
String? method;
///Gets whether a gesture (such as a click) was associated with the request.
......@@ -190,17 +190,17 @@ class WebResourceRequest {
///the sequence of events which caused the request to be created was initiated by a user
///gesture.
///
///**NOTE**: Available on Android 21+. For Android < 21 it will be always `false`.
///**NOTE**: available on Android 21+. For Android < 21 it will be always `false`.
bool? hasGesture;
///Whether the request was made in order to fetch the main frame's document.
///
///**NOTE**: Available on Android 21+. For Android < 21 it will be always `true`.
///**NOTE**: available on Android 21+. For Android < 21 it will be always `true`.
bool? isForMainFrame;
///Whether the request was a result of a server-side redirect.
///
///**NOTE**: Available on Android 21+. For Android < 21 it will be always `false`.
///**NOTE**: available on Android 21+. For Android < 21 it will be always `false`.
bool? isRedirect;
WebResourceRequest(
......@@ -233,7 +233,7 @@ class WebResourceRequest {
}
///Class representing a resource response of the WebView used by the event [WebView.androidShouldInterceptRequest].
///Available only on Android.
///**NOTE**: available only on Android.
///
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebResourceResponse
class WebResourceResponse {
......@@ -248,19 +248,19 @@ class WebResourceResponse {
///The headers for the resource response. If [headers] isn't `null`, then you need to set also [statusCode] and [reasonPhrase].
///
///**NOTE**: Available on Android 21+. For Android < 21 it won't be used.
///**NOTE**: available on Android 21+. For Android < 21 it won't be used.
Map<String, String>? headers;
///The status code needs to be in the ranges [100, 299], [400, 599]. Causing a redirect by specifying a 3xx code is not supported.
///If statusCode is set, then you need to set also [headers] and [reasonPhrase]. This value cannot be `null`.
///
///**NOTE**: Available on Android 21+. For Android < 21 it won't be used.
///**NOTE**: available on Android 21+. For Android < 21 it won't be used.
int? statusCode;
///The phrase describing the status code, for example `"OK"`. Must be non-empty.
///If reasonPhrase is set, then you need to set also [headers] and [reasonPhrase]. This value cannot be `null`.
///
///**NOTE**: Available on Android 21+. For Android < 21 it won't be used.
///**NOTE**: available on Android 21+. For Android < 21 it won't be used.
String? reasonPhrase;
WebResourceResponse(
......@@ -452,7 +452,9 @@ class JsAlertRequest {
///Message to be displayed in the window.
String? message;
///Indicates whether the request was made for the main frame. Available only on iOS.
///Indicates whether the request was made for the main frame.
///
///**NOTE**: available only on iOS.
bool? iosIsMainFrame;
JsAlertRequest({this.url, this.message, this.iosIsMainFrame});
......@@ -534,7 +536,9 @@ class JsConfirmRequest {
///Message to be displayed in the window.
String? message;
///Indicates whether the request was made for the main frame. Available only on iOS.
///Indicates whether the request was made for the main frame.
///
///**NOTE**: available only on iOS.
bool? iosIsMainFrame;
JsConfirmRequest({this.url, this.message, this.iosIsMainFrame});
......@@ -625,7 +629,9 @@ class JsPromptRequest {
///The default value displayed in the prompt dialog.
String? defaultValue;
///Indicates whether the request was made for the main frame. Available only on iOS.
///Indicates whether the request was made for the main frame.
///
///**NOTE**: available only on iOS.
bool? iosIsMainFrame;
JsPromptRequest(
......@@ -729,7 +735,9 @@ class JsBeforeUnloadRequest {
///Message to be displayed in the window.
String? message;
///Indicates whether the request was made for the main frame. Available only on iOS.
///Indicates whether the request was made for the main frame.
///
///**NOTE**: available only on iOS.
bool? iosIsMainFrame;
JsBeforeUnloadRequest({this.url, this.message, this.iosIsMainFrame});
......@@ -3168,13 +3176,17 @@ class ShouldOverrideUrlLoadingRequest {
///the sequence of events which caused the request to be created was initiated by a user
///gesture.
///
///Available only on Android. On Android < 24, this is always `false`.
///**NOTE**: available only on Android. On Android < 24, this is always `false`.
bool? androidHasGesture;
///Gets whether the request was a result of a server-side redirect. Available only on Android. On Android < 21, this is always `false`.
///Gets whether the request was a result of a server-side redirect.
///
///**NOTE**: available only on Android. On Android < 21, this is always `false`.
bool? androidIsRedirect;
///The type of action triggering the navigation. Available only on iOS.
///The type of action triggering the navigation.
///
///**NOTE**: available only on iOS.
IOSWKNavigationType? iosWKNavigationType;
ShouldOverrideUrlLoadingRequest(
......@@ -3218,16 +3230,24 @@ class CreateWindowRequest {
///The window id. Used by [WebView] to create a new WebView.
int windowId;
///Indicates if the new window should be a dialog, rather than a full-size window. Available only on Android.
///Indicates if the new window should be a dialog, rather than a full-size window.
///
///**NOTE**: available only on Android.
bool? androidIsDialog;
///Indicates if the request was initiated by a user gesture, such as the user clicking a link. Available only on Android.
///Indicates if the request was initiated by a user gesture, such as the user clicking a link.
///
///**NOTE**: available only on Android.
bool? androidIsUserGesture;
///The type of action triggering the navigation. Available only on iOS.
///The type of action triggering the navigation.
///
///**NOTE**: available only on iOS.
IOSWKNavigationType? iosWKNavigationType;
///Whether the request was made in order to fetch the main frame's document. Available only on iOS.
///Whether the request was made in order to fetch the main frame's document.
///
///**NOTE**: available only on iOS.
bool? iosIsForMainFrame;
CreateWindowRequest(
......@@ -4568,7 +4588,9 @@ class UserScript {
///A Boolean value that indicates whether to inject the script into the main frame.
///Specify true to inject the script only into the main frame, or false to inject it into all frames.
///The default value is `true`. Available only on iOS.
///The default value is `true`.
///
///**NOTE**: available only on iOS.
bool iosForMainFrameOnly;
///**NOTE for iOS 14.0+**: The namespace in which to evaluate the script.
......@@ -4656,6 +4678,169 @@ class CallAsyncJavaScriptResult {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///A class that represents a structure that contains the location and dimensions of a rectangle.
class InAppWebViewRect {
///
double x;
///
double y;
///
double width;
///
double height;
InAppWebViewRect({required this.x, required this.y, required this.width, required this.height}) {
assert(this.x >= 0 && this.y >= 0 && this.width >= 0 && this.height >= 0);
}
Map<String, dynamic> toMap() {
return {"x": x, "y": y, "width": width, "height": height};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///Class that represents the known formats a bitmap can be compressed into.
class CompressFormat {
final String _value;
const CompressFormat._internal(this._value);
static final Set<CompressFormat> values = [
CompressFormat.JPEG,
CompressFormat.PNG,
CompressFormat.WEBP,
CompressFormat.WEBP_LOSSY,
CompressFormat.WEBP_LOSSLESS,
].toSet();
static CompressFormat? fromValue(String? value) {
if (value != null) {
try {
return CompressFormat.values.firstWhere(
(element) => element.toValue() == value);
} catch (e) {
return null;
}
}
return null;
}
String toValue() => _value;
@override
String toString() => _value;
///Compress to the `PNG` format.
///PNG is lossless, so `quality` is ignored.
static const PNG = const CompressFormat._internal("PNG");
///Compress to the `JPEG` format.
///Quality of `0` means compress for the smallest size.
///`100` means compress for max visual quality.
static const JPEG = const CompressFormat._internal("JPEG");
///Compress to the `WEBP` lossy format.
///Quality of `0` means compress for the smallest size.
///`100` means compress for max visual quality.
///
///**NOTE**: available only on Android.
static const WEBP = const CompressFormat._internal("WEBP");
///Compress to the `WEBP` lossy format.
///Quality of `0` means compress for the smallest size.
///`100` means compress for max visual quality.
///
///**NOTE**: available only on Android.
///
///**NOTE for Android**: available on Android 30+.
static const WEBP_LOSSY = const CompressFormat._internal("WEBP_LOSSY");
///Compress to the `WEBP` lossless format.
///Quality refers to how much effort to put into compression.
///A value of `0` means to compress quickly, resulting in a relatively large file size.
///`100` means to spend more time compressing, resulting in a smaller file.
///
///**NOTE**: available only on Android.
///
///**NOTE for Android**: available on Android 30+.
static const WEBP_LOSSLESS = const CompressFormat._internal("WEBP_LOSSLESS");
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
}
///Class that represents the configuration data to use when generating an image from a web view’s contents using [InAppWebViewController.takeScreenshot].
///
///**NOTE for iOS**: available from iOS 11.0+.
class ScreenshotConfiguration {
///The portion of your web view to capture, specified as a rectangle in the view’s coordinate system.
///The default value of this property is `null`, which captures everything in the view’s bounds rectangle.
///If you specify a custom rectangle, it must lie within the bounds rectangle of the [WebView] object.
InAppWebViewRect? rect;
///The width of the captured image, in points.
///Use this property to scale the generated image to the specified width.
///The web view maintains the aspect ratio of the captured content, but scales it to match the width you specify.
///
///The default value of this property is `null`, which returns an image whose size matches the original size of the captured rectangle.
double? snapshotWidth;
///The compression format of the captured image.
///The default value is [CompressFormat.PNG].
CompressFormat compressFormat;
///Hint to the compressor, `0-100`. The value is interpreted differently depending on the [CompressFormat].
///[CompressFormat.PNG] is lossless, so this value is ignored.
int quality;
///A Boolean value that indicates whether to take the snapshot after incorporating any pending screen updates.
///The default value of this property is `true`, which causes the web view to incorporate any recent changes to the view’s content and then generate the snapshot.
///If you change the value to `false`, the [WebView] takes the snapshot immediately, and before incorporating any new changes.
///
///**NOTE**: available only on iOS.
///
///**NOTE for iOS**: available only on iOS. Available from iOS 13.0+.
bool iosAfterScreenUpdates;
ScreenshotConfiguration({
this.rect,
this.snapshotWidth,
this.compressFormat = CompressFormat.PNG,
this.quality = 100,
this.iosAfterScreenUpdates = true}) {
assert(this.quality >= 0);
}
Map<String, dynamic> toMap() {
return {
"rect": rect?.toMap(),
"snapshotWidth": snapshotWidth,
"compressFormat": compressFormat.toValue(),
"quality": quality,
"iosAfterScreenUpdates": iosAfterScreenUpdates};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment