added onDownloadStartRequest event
This commit is contained in:
parent
1e287fd1d3
commit
22649342e8
|
@ -3,6 +3,8 @@
|
||||||
- `getOriginalUrl` method is cross-platform now
|
- `getOriginalUrl` method is cross-platform now
|
||||||
- Updated Android `compileSdkVersion` to 31
|
- Updated Android `compileSdkVersion` to 31
|
||||||
- Added `singleInstance` option for Android `ChromeSafariBrowser` implementation
|
- Added `singleInstance` option for Android `ChromeSafariBrowser` implementation
|
||||||
|
- Added `onDownloadStartRequest` event and deprecated old `onDownloadStart` event
|
||||||
|
- Fixed missing `onZoomScaleChanged` call for `InAppBrowser` class
|
||||||
- Fixed `requestImageRef` method always `null` on iOS
|
- Fixed `requestImageRef` method always `null` on iOS
|
||||||
- Fixed "applicationNameForUserAgent is not work in ios" [#525](https://github.com/pichillilorenzo/flutter_inappwebview/issues/525)
|
- Fixed "applicationNameForUserAgent is not work in ios" [#525](https://github.com/pichillilorenzo/flutter_inappwebview/issues/525)
|
||||||
- Fixed "Crash when try select file from webview input on Android" [#867](https://github.com/pichillilorenzo/flutter_inappwebview/issues/867)
|
- Fixed "Crash when try select file from webview input on Android" [#867](https://github.com/pichillilorenzo/flutter_inappwebview/issues/867)
|
||||||
|
|
|
@ -37,6 +37,7 @@ import android.view.inputmethod.InputConnection;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.DownloadListener;
|
import android.webkit.DownloadListener;
|
||||||
|
import android.webkit.URLUtil;
|
||||||
import android.webkit.ValueCallback;
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebBackForwardList;
|
import android.webkit.WebBackForwardList;
|
||||||
import android.webkit.WebHistoryItem;
|
import android.webkit.WebHistoryItem;
|
||||||
|
@ -54,6 +55,7 @@ import androidx.webkit.WebViewCompat;
|
||||||
import androidx.webkit.WebViewFeature;
|
import androidx.webkit.WebViewFeature;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.types.DownloadStartRequest;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.InAppWebViewInterface;
|
import com.pichillilorenzo.flutter_inappwebview.types.InAppWebViewInterface;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
|
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||||
|
@ -1181,14 +1183,17 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
|
|
||||||
class DownloadStartListener implements DownloadListener {
|
class DownloadStartListener implements DownloadListener {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
|
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
|
||||||
Map<String, Object> obj = new HashMap<>();
|
DownloadStartRequest downloadStartRequest = new DownloadStartRequest(
|
||||||
obj.put("url", url);
|
url,
|
||||||
obj.put("userAgent", userAgent);
|
userAgent,
|
||||||
obj.put("contentDisposition", contentDisposition);
|
contentDisposition,
|
||||||
obj.put("mimetype", mimetype);
|
mimeType,
|
||||||
obj.put("contentLength", contentLength);
|
contentLength,
|
||||||
channel.invokeMethod("onDownloadStart", obj);
|
URLUtil.guessFileName(url, contentDisposition, mimeType),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
channel.invokeMethod("onDownloadStartRequest", downloadStartRequest.toMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DownloadStartRequest {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String url;
|
||||||
|
@NonNull
|
||||||
|
private String userAgent;
|
||||||
|
@NonNull
|
||||||
|
private String contentDisposition;
|
||||||
|
@NonNull
|
||||||
|
private String mimeType;
|
||||||
|
private long contentLength;
|
||||||
|
@Nullable
|
||||||
|
private String suggestedFilename;
|
||||||
|
@Nullable
|
||||||
|
private String textEncodingName;
|
||||||
|
|
||||||
|
public DownloadStartRequest(@NonNull String url, @NonNull String userAgent, @NonNull String contentDisposition, @NonNull String mimeType, long contentLength, @Nullable String suggestedFilename, @Nullable String textEncodingName) {
|
||||||
|
this.url = url;
|
||||||
|
this.userAgent = userAgent;
|
||||||
|
this.contentDisposition = contentDisposition;
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
this.suggestedFilename = suggestedFilename;
|
||||||
|
this.textEncodingName = textEncodingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> obj = new HashMap<>();
|
||||||
|
obj.put("url", url);
|
||||||
|
obj.put("userAgent", userAgent);
|
||||||
|
obj.put("contentDisposition", contentDisposition);
|
||||||
|
obj.put("mimeType", mimeType);
|
||||||
|
obj.put("contentLength", contentLength);
|
||||||
|
obj.put("suggestedFilename", suggestedFilename);
|
||||||
|
obj.put("textEncodingName", textEncodingName);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(@NonNull String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getUserAgent() {
|
||||||
|
return userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserAgent(@NonNull String userAgent) {
|
||||||
|
this.userAgent = userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getContentDisposition() {
|
||||||
|
return contentDisposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentDisposition(@NonNull String contentDisposition) {
|
||||||
|
this.contentDisposition = contentDisposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMimeType(@NonNull String mimeType) {
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getContentLength() {
|
||||||
|
return contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentLength(long contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getSuggestedFilename() {
|
||||||
|
return suggestedFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuggestedFilename(@Nullable String suggestedFilename) {
|
||||||
|
this.suggestedFilename = suggestedFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getTextEncodingName() {
|
||||||
|
return textEncodingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextEncodingName(@Nullable String textEncodingName) {
|
||||||
|
this.textEncodingName = textEncodingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
DownloadStartRequest that = (DownloadStartRequest) o;
|
||||||
|
|
||||||
|
if (contentLength != that.contentLength) return false;
|
||||||
|
if (!url.equals(that.url)) return false;
|
||||||
|
if (!userAgent.equals(that.userAgent)) return false;
|
||||||
|
if (!contentDisposition.equals(that.contentDisposition)) return false;
|
||||||
|
if (!mimeType.equals(that.mimeType)) return false;
|
||||||
|
if (suggestedFilename != null ? !suggestedFilename.equals(that.suggestedFilename) : that.suggestedFilename != null)
|
||||||
|
return false;
|
||||||
|
return textEncodingName != null ? textEncodingName.equals(that.textEncodingName) : that.textEncodingName == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = url.hashCode();
|
||||||
|
result = 31 * result + userAgent.hashCode();
|
||||||
|
result = 31 * result + contentDisposition.hashCode();
|
||||||
|
result = 31 * result + mimeType.hashCode();
|
||||||
|
result = 31 * result + (int) (contentLength ^ (contentLength >>> 32));
|
||||||
|
result = 31 * result + (suggestedFilename != null ? suggestedFilename.hashCode() : 0);
|
||||||
|
result = 31 * result + (textEncodingName != null ? textEncodingName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DownloadStartRequest{" +
|
||||||
|
"url='" + url + '\'' +
|
||||||
|
", userAgent='" + userAgent + '\'' +
|
||||||
|
", contentDisposition='" + contentDisposition + '\'' +
|
||||||
|
", mimeType='" + mimeType + '\'' +
|
||||||
|
", contentLength=" + contentLength +
|
||||||
|
", suggestedFilename='" + suggestedFilename + '\'' +
|
||||||
|
", textEncodingName='" + textEncodingName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.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/fvm/versions/2.10.4/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.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/fvm/versions/2.10.4/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/.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":"2022-04-16 12:29:54.757036","version":"2.10.4"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.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/fvm/versions/2.10.4/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.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/fvm/versions/2.10.4/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/.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":"2022-04-17 16:15:55.135230","version":"2.10.4"}
|
|
@ -2705,7 +2705,7 @@ void main() {
|
||||||
expect(numberOfMatches, 2);
|
expect(numberOfMatches, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('onDownloadStart', (WidgetTester tester) async {
|
testWidgets('onDownloadStartRequest', (WidgetTester tester) async {
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
final Completer<String> onDownloadStartCompleter = Completer<String>();
|
final Completer<String> onDownloadStartCompleter = Completer<String>();
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
|
@ -2739,8 +2739,8 @@ void main() {
|
||||||
onWebViewCreated: (controller) {
|
onWebViewCreated: (controller) {
|
||||||
controllerCompleter.complete(controller);
|
controllerCompleter.complete(controller);
|
||||||
},
|
},
|
||||||
onDownloadStart:(controller, url, userAgent, contentDisposition, mimeType, contentLength) {
|
onDownloadStartRequest: (controller, request) {
|
||||||
onDownloadStartCompleter.complete(url.toString());
|
onDownloadStartCompleter.complete(request.url.toString());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -24,7 +24,8 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
|
InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
useShouldOverrideUrlLoading: true,
|
useShouldOverrideUrlLoading: true,
|
||||||
mediaPlaybackRequiresUserGesture: false
|
mediaPlaybackRequiresUserGesture: false,
|
||||||
|
useOnDownloadStart: true
|
||||||
),
|
),
|
||||||
android: AndroidInAppWebViewOptions(
|
android: AndroidInAppWebViewOptions(
|
||||||
useHybridComposition: true,
|
useHybridComposition: true,
|
||||||
|
@ -123,7 +124,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
key: webViewKey,
|
key: webViewKey,
|
||||||
// contextMenu: contextMenu,
|
// contextMenu: contextMenu,
|
||||||
initialUrlRequest:
|
initialUrlRequest:
|
||||||
URLRequest(url: Uri.parse("https://github.com/flutter")),
|
URLRequest(url: Uri.parse("https://testfiledownload.com/")),
|
||||||
// initialFile: "assets/index.html",
|
// initialFile: "assets/index.html",
|
||||||
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
||||||
initialOptions: options,
|
initialOptions: options,
|
||||||
|
@ -131,6 +132,9 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
onWebViewCreated: (controller) {
|
onWebViewCreated: (controller) {
|
||||||
webViewController = controller;
|
webViewController = controller;
|
||||||
},
|
},
|
||||||
|
onDownloadStartRequest: (controller, request) {
|
||||||
|
print(request);
|
||||||
|
},
|
||||||
onLoadStart: (controller, url) {
|
onLoadStart: (controller, url) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.url = url.toString();
|
this.url = url.toString();
|
||||||
|
|
|
@ -1546,7 +1546,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
let mimeType = navigationResponse.response.mimeType
|
let mimeType = navigationResponse.response.mimeType
|
||||||
if let url = navigationResponse.response.url, navigationResponse.isForMainFrame {
|
if let url = navigationResponse.response.url, navigationResponse.isForMainFrame {
|
||||||
if url.scheme != "file", mimeType != nil, !mimeType!.starts(with: "text/") {
|
if url.scheme != "file", mimeType != nil, !mimeType!.starts(with: "text/") {
|
||||||
onDownloadStart(url: url.absoluteString)
|
let downloadStartRequest = DownloadStartRequest(url: url.absoluteString,
|
||||||
|
userAgent: nil,
|
||||||
|
contentDisposition: nil,
|
||||||
|
mimeType: mimeType,
|
||||||
|
contentLength: navigationResponse.response.expectedContentLength,
|
||||||
|
suggestedFilename: navigationResponse.response.suggestedFilename,
|
||||||
|
textEncodingName: navigationResponse.response.textEncodingName)
|
||||||
|
onDownloadStartRequest(request: downloadStartRequest)
|
||||||
if useOnNavigationResponse == nil || !useOnNavigationResponse! {
|
if useOnNavigationResponse == nil || !useOnNavigationResponse! {
|
||||||
decisionHandler(.cancel)
|
decisionHandler(.cancel)
|
||||||
}
|
}
|
||||||
|
@ -2363,9 +2370,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onDownloadStart(url: String) {
|
public func onDownloadStartRequest(request: DownloadStartRequest) {
|
||||||
let arguments: [String: Any] = ["url": url]
|
channel?.invokeMethod("onDownloadStartRequest", arguments: request.toMap())
|
||||||
channel?.invokeMethod("onDownloadStart", arguments: arguments)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onLoadResourceCustomScheme(url: String, result: FlutterResult?) {
|
public func onLoadResourceCustomScheme(url: String, result: FlutterResult?) {
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// DownloadStartRequest.swift
|
||||||
|
// flutter_inappwebview
|
||||||
|
//
|
||||||
|
// Created by Lorenzo Pichilli on 17/04/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class DownloadStartRequest: NSObject {
|
||||||
|
var url: String
|
||||||
|
var userAgent: String?
|
||||||
|
var contentDisposition: String?
|
||||||
|
var mimeType: String?
|
||||||
|
var contentLength: Int64
|
||||||
|
var suggestedFilename: String?
|
||||||
|
var textEncodingName: String?
|
||||||
|
|
||||||
|
public init(url: String, userAgent: String?, contentDisposition: String?,
|
||||||
|
mimeType: String?, contentLength: Int64,
|
||||||
|
suggestedFilename: String?, textEncodingName: String?) {
|
||||||
|
self.url = url
|
||||||
|
self.userAgent = userAgent
|
||||||
|
self.contentDisposition = contentDisposition
|
||||||
|
self.mimeType = mimeType
|
||||||
|
self.contentLength = contentLength
|
||||||
|
self.suggestedFilename = suggestedFilename
|
||||||
|
self.textEncodingName = textEncodingName
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toMap () -> [String:Any?] {
|
||||||
|
return [
|
||||||
|
"url": url,
|
||||||
|
"userAgent": userAgent,
|
||||||
|
"contentDisposition": contentDisposition,
|
||||||
|
"mimeType": mimeType,
|
||||||
|
"contentLength": contentLength,
|
||||||
|
"suggestedFilename": suggestedFilename,
|
||||||
|
"textEncodingName": textEncodingName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -377,16 +377,21 @@ class InAppBrowser {
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll
|
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll
|
||||||
void onScrollChanged(int x, int y) {}
|
void onScrollChanged(int x, int y) {}
|
||||||
|
|
||||||
///Event fired when [InAppBrowser] recognizes and starts a downloadable file.
|
///Use [onDownloadStartRequest] instead
|
||||||
|
@Deprecated('Use `onDownloadStartRequest` instead')
|
||||||
|
void onDownloadStart(Uri url) {}
|
||||||
|
|
||||||
|
///Event fired when [WebView] recognizes a downloadable file.
|
||||||
|
///To download the file, you can use the [flutter_downloader](https://pub.dev/packages/flutter_downloader) plugin.
|
||||||
///
|
///
|
||||||
///[url] represents the url of the file.
|
///[downloadStartRequest] represents the request of the file to download.
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnDownloadStart] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnDownloadStart] option to `true`.
|
||||||
///
|
///
|
||||||
///**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
|
||||||
void onDownloadStart(Uri url, String userAgent, String contentDisposition, String mimeType, int contentLength) {}
|
void onDownloadStartRequest(DownloadStartRequest downloadStartRequest) {}
|
||||||
|
|
||||||
///Event fired when the [InAppBrowser] 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 [InAppBrowser] 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`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -64,7 +64,8 @@ class HeadlessInAppWebView implements WebView {
|
||||||
this.shouldOverrideUrlLoading,
|
this.shouldOverrideUrlLoading,
|
||||||
this.onLoadResource,
|
this.onLoadResource,
|
||||||
this.onScrollChanged,
|
this.onScrollChanged,
|
||||||
this.onDownloadStart,
|
@Deprecated('Use `onDownloadStartRequest` instead') this.onDownloadStart,
|
||||||
|
this.onDownloadStartRequest,
|
||||||
this.onLoadResourceCustomScheme,
|
this.onLoadResourceCustomScheme,
|
||||||
this.onCreateWindow,
|
this.onCreateWindow,
|
||||||
this.onCloseWindow,
|
this.onCloseWindow,
|
||||||
|
@ -301,14 +302,15 @@ class HeadlessInAppWebView implements WebView {
|
||||||
@override
|
@override
|
||||||
void Function(InAppWebViewController controller)? onWindowBlur;
|
void Function(InAppWebViewController controller)? onWindowBlur;
|
||||||
|
|
||||||
|
///Use [onDownloadStartRequest] instead
|
||||||
|
@Deprecated('Use `onDownloadStartRequest` instead')
|
||||||
@override
|
@override
|
||||||
void Function(
|
final void Function(InAppWebViewController controller, Uri url)?
|
||||||
InAppWebViewController controller,
|
onDownloadStart;
|
||||||
Uri url,
|
|
||||||
String userAgent,
|
@override
|
||||||
String contentDisposition,
|
final void Function(InAppWebViewController controller, DownloadStartRequest downloadStartRequest)?
|
||||||
String mimeType,
|
onDownloadStartRequest;
|
||||||
int contentLength)? onDownloadStart;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||||
|
|
|
@ -53,7 +53,8 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||||
this.shouldOverrideUrlLoading,
|
this.shouldOverrideUrlLoading,
|
||||||
this.onLoadResource,
|
this.onLoadResource,
|
||||||
this.onScrollChanged,
|
this.onScrollChanged,
|
||||||
this.onDownloadStart,
|
@Deprecated('Use `onDownloadStartRequest` instead') this.onDownloadStart,
|
||||||
|
this.onDownloadStartRequest,
|
||||||
this.onLoadResourceCustomScheme,
|
this.onLoadResourceCustomScheme,
|
||||||
this.onCreateWindow,
|
this.onCreateWindow,
|
||||||
this.onCloseWindow,
|
this.onCloseWindow,
|
||||||
|
@ -211,10 +212,16 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||||
InAppWebViewController controller, Uri url, bool precomposed)?
|
InAppWebViewController controller, Uri url, bool precomposed)?
|
||||||
androidOnReceivedTouchIconUrl;
|
androidOnReceivedTouchIconUrl;
|
||||||
|
|
||||||
|
///Use [onDownloadStartRequest] instead
|
||||||
|
@Deprecated('Use `onDownloadStartRequest` instead')
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri url, String userAgent, String contentDisposition, String mimeType, int contentLength)?
|
final void Function(InAppWebViewController controller, Uri url)?
|
||||||
onDownloadStart;
|
onDownloadStart;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final void Function(InAppWebViewController controller, DownloadStartRequest downloadStartRequest)?
|
||||||
|
onDownloadStartRequest;
|
||||||
|
|
||||||
@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;
|
||||||
|
|
|
@ -201,20 +201,26 @@ class InAppWebViewController {
|
||||||
_inAppBrowser!.onScrollChanged(x, y);
|
_inAppBrowser!.onScrollChanged(x, y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "onDownloadStart":
|
case "onDownloadStartRequest":
|
||||||
if ((_webview != null && _webview!.onDownloadStart != null) ||
|
if ((_webview != null &&
|
||||||
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
(_webview!.onDownloadStart != null || _webview!.onDownloadStartRequest != null)) ||
|
||||||
_inAppBrowser != null) {
|
_inAppBrowser != null) {
|
||||||
String url = call.arguments["url"];
|
Map<String, dynamic> arguments = call.arguments.cast<String, dynamic>();
|
||||||
String userAgent = call.arguments["userAgent"];
|
DownloadStartRequest downloadStartRequest = DownloadStartRequest.fromMap(arguments)!;
|
||||||
String contentDisposition = call.arguments["contentDisposition"];
|
|
||||||
String mimeType = call.arguments["mimetype"];
|
|
||||||
int contentLength = call.arguments["contentLength"] as int;
|
|
||||||
Uri uri = Uri.parse(url);
|
|
||||||
|
|
||||||
if (_webview != null && _webview!.onDownloadStart != null)
|
if (_webview != null) {
|
||||||
_webview!.onDownloadStart!(this, uri, userAgent, contentDisposition, mimeType, contentLength);
|
if (_webview!.onDownloadStartRequest != null)
|
||||||
else
|
_webview!.onDownloadStartRequest!(this, downloadStartRequest);
|
||||||
_inAppBrowser!.onDownloadStart(uri, userAgent, contentDisposition, mimeType, contentLength);
|
else {
|
||||||
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
_webview!.onDownloadStart!(this, downloadStartRequest.url);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
_inAppBrowser!.onDownloadStart(downloadStartRequest.url);
|
||||||
|
_inAppBrowser!.onDownloadStartRequest(downloadStartRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "onLoadResourceCustomScheme":
|
case "onLoadResourceCustomScheme":
|
||||||
|
@ -380,6 +386,7 @@ class InAppWebViewController {
|
||||||
} else {
|
} else {
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
|
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
|
||||||
|
_inAppBrowser!.onZoomScaleChanged(oldScale, newScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -112,18 +112,23 @@ abstract class WebView {
|
||||||
final void Function(InAppWebViewController controller, int x, int y)?
|
final void Function(InAppWebViewController controller, int x, int y)?
|
||||||
onScrollChanged;
|
onScrollChanged;
|
||||||
|
|
||||||
|
///Use [onDownloadStartRequest] instead
|
||||||
|
@Deprecated('Use `onDownloadStartRequest` instead')
|
||||||
|
final void Function(InAppWebViewController controller, Uri url)?
|
||||||
|
onDownloadStart;
|
||||||
|
|
||||||
///Event fired when [WebView] recognizes a downloadable file.
|
///Event fired when [WebView] recognizes a downloadable file.
|
||||||
///To download the file, you can use the [flutter_downloader](https://pub.dev/packages/flutter_downloader) plugin.
|
///To download the file, you can use the [flutter_downloader](https://pub.dev/packages/flutter_downloader) plugin.
|
||||||
///
|
///
|
||||||
///[url] represents the url of the file.
|
///[downloadStartRequest] represents the request of the file to download.
|
||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnDownloadStart] option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnDownloadStart] option to `true`.
|
||||||
///
|
///
|
||||||
///**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, Uri url, String userAgent, String contentDisposition, String mimeType, int contentLength)?
|
final void Function(InAppWebViewController controller, DownloadStartRequest downloadStartRequest)?
|
||||||
onDownloadStart;
|
onDownloadStartRequest;
|
||||||
|
|
||||||
///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`.
|
||||||
///
|
///
|
||||||
|
@ -696,7 +701,8 @@ abstract class WebView {
|
||||||
this.shouldOverrideUrlLoading,
|
this.shouldOverrideUrlLoading,
|
||||||
this.onLoadResource,
|
this.onLoadResource,
|
||||||
this.onScrollChanged,
|
this.onScrollChanged,
|
||||||
this.onDownloadStart,
|
@Deprecated('Use `onDownloadStartRequest` instead') this.onDownloadStart,
|
||||||
|
this.onDownloadStartRequest,
|
||||||
this.onLoadResourceCustomScheme,
|
this.onLoadResourceCustomScheme,
|
||||||
this.onCreateWindow,
|
this.onCreateWindow,
|
||||||
this.onCloseWindow,
|
this.onCloseWindow,
|
||||||
|
|
|
@ -6891,4 +6891,73 @@ class WebViewImplementation {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => _value.hashCode;
|
int get hashCode => _value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class representing a download request of the WebView used by the event [WebView.onDownloadStartRequest].
|
||||||
|
class DownloadStartRequest {
|
||||||
|
///The full url to the content that should be downloaded.
|
||||||
|
Uri url;
|
||||||
|
|
||||||
|
///the user agent to be used for the download.
|
||||||
|
String? userAgent;
|
||||||
|
|
||||||
|
///Content-disposition http header, if present.
|
||||||
|
String? contentDisposition;
|
||||||
|
|
||||||
|
///The mimetype of the content reported by the server.
|
||||||
|
String? mimeType;
|
||||||
|
|
||||||
|
///The file size reported by the server.
|
||||||
|
int contentLength;
|
||||||
|
|
||||||
|
///A suggested filename to use if saving the resource to disk.
|
||||||
|
String? suggestedFilename;
|
||||||
|
|
||||||
|
///The name of the text encoding of the receiver, or `null` if no text encoding was specified.
|
||||||
|
String? textEncodingName;
|
||||||
|
|
||||||
|
DownloadStartRequest(
|
||||||
|
{required this.url,
|
||||||
|
this.userAgent,
|
||||||
|
this.contentDisposition,
|
||||||
|
this.mimeType,
|
||||||
|
required this.contentLength,
|
||||||
|
this.suggestedFilename,
|
||||||
|
this.textEncodingName});
|
||||||
|
|
||||||
|
static DownloadStartRequest? fromMap(Map<String, dynamic>? map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DownloadStartRequest(
|
||||||
|
url: Uri.parse(map["url"]),
|
||||||
|
userAgent: map["userAgent"],
|
||||||
|
contentDisposition: map["contentDisposition"],
|
||||||
|
mimeType: map["mimeType"],
|
||||||
|
contentLength: map["contentLength"],
|
||||||
|
suggestedFilename: map["suggestedFilename"],
|
||||||
|
textEncodingName: map["textEncodingName"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"url": url.toString(),
|
||||||
|
"userAgent": userAgent,
|
||||||
|
"contentDisposition": contentDisposition,
|
||||||
|
"mimeType": mimeType,
|
||||||
|
"contentLength": contentLength,
|
||||||
|
"suggestedFilename": suggestedFilename,
|
||||||
|
"textEncodingName": textEncodingName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue