From 3bad02d6e43f47cc2ab0378817d8619db1a73fe5 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Wed, 27 Apr 2022 13:39:00 +0200 Subject: [PATCH] fixed plugin dependencies, added getUrl web support --- .../in_app_webview/initial_url_request.dart | 7 +- .../webview_flutter_test.dart | 446 +++++++++--------- example/lib/in_app_webiew_example.screen.dart | 3 +- lib/assets/web/web_support.js | 12 +- .../in_app_webview_controller.dart | 4 + lib/src/web/in_app_web_view_web_element.dart | 10 + pubspec.yaml | 4 +- 7 files changed, 259 insertions(+), 227 deletions(-) diff --git a/example/integration_test/in_app_webview/initial_url_request.dart b/example/integration_test/in_app_webview/initial_url_request.dart index 1c9d8bb2..12279d12 100644 --- a/example/integration_test/in_app_webview/initial_url_request.dart +++ b/example/integration_test/in_app_webview/initial_url_request.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -24,5 +25,9 @@ void initialUrlRequest() { await controllerCompleter.future; final String? currentUrl = (await controller.getUrl())?.toString(); expect(currentUrl, 'https://github.com/flutter'); - }); + }, skip: !kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform)); } \ No newline at end of file diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index 7c6cb6dc..871a671f 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:collection'; import 'dart:convert'; -import 'dart:io'; +// import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/foundation.dart'; @@ -89,7 +89,7 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser { void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - if (Platform.isAndroid) { + if (defaultTargetPlatform == TargetPlatform.android) { InAppWebViewController.setWebContentsDebuggingEnabled(true); } @@ -350,141 +350,141 @@ void main() { pageLoads.close(); }); - group("iOS loadFileURL", () { - late Directory appSupportDir; - late File fileHtml; - late File fileJs; - - setUpAll(() async { - appSupportDir = (await getApplicationSupportDirectory()); - - final Directory htmlFolder = Directory('${appSupportDir.path}/html/'); - if (!await htmlFolder.exists()) { - await htmlFolder.create(recursive: true); - } - - final Directory jsFolder = Directory('${appSupportDir.path}/js/'); - if (!await jsFolder.exists()) { - await jsFolder.create(recursive: true); - } - - var html = """ - - - file scheme - - - - - - """; - fileHtml = File(htmlFolder.path + "index.html"); - fileHtml.writeAsStringSync(html); - - var js = """ - console.log('message'); - """; - fileJs = File(jsFolder.path + "main.js"); - fileJs.writeAsStringSync(js); - }); - - testWidgets('initialUrl with file:// scheme and allowingReadAccessTo', - (WidgetTester tester) async { - final Completer consoleMessageShouldNotComplete = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('file://${fileHtml.path}')), - onConsoleMessage: (controller, consoleMessage) { - consoleMessageShouldNotComplete.complete(consoleMessage); - }, - ), - ), - ); - var result = await consoleMessageShouldNotComplete.future - .timeout(const Duration(seconds: 2), onTimeout: () => null); - expect(result, null); - - final Completer consoleMessageCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('file://${fileHtml.path}')), - initialOptions: InAppWebViewGroupOptions( - ios: IOSInAppWebViewOptions( - allowingReadAccessTo: - Uri.parse('file://${appSupportDir.path}/'))), - onConsoleMessage: (controller, consoleMessage) { - consoleMessageCompleter.complete(consoleMessage); - }, - ), - ), - ); - final ConsoleMessage consoleMessage = - await consoleMessageCompleter.future; - expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); - expect(consoleMessage.message, 'message'); - }, skip: !Platform.isIOS); - - testWidgets( - 'loadUrl with file:// scheme and allowingReadAccessTo argument', - (WidgetTester tester) async { - final Completer consoleMessageShouldNotComplete = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - onWebViewCreated: (controller) { - controller.loadUrl( - urlRequest: - URLRequest(url: Uri.parse('file://${fileHtml.path}'))); - }, - onConsoleMessage: (controller, consoleMessage) { - consoleMessageShouldNotComplete.complete(consoleMessage); - }, - ), - ), - ); - var result = await consoleMessageShouldNotComplete.future - .timeout(const Duration(seconds: 2), onTimeout: () => null); - expect(result, null); - - final Completer consoleMessageCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - onWebViewCreated: (controller) { - controller.loadUrl( - urlRequest: - URLRequest(url: Uri.parse('file://${fileHtml.path}')), - allowingReadAccessTo: - Uri.parse('file://${appSupportDir.path}/')); - }, - onConsoleMessage: (controller, consoleMessage) { - consoleMessageCompleter.complete(consoleMessage); - }, - ), - ), - ); - final ConsoleMessage consoleMessage = - await consoleMessageCompleter.future; - expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); - expect(consoleMessage.message, 'message'); - }, skip: !Platform.isIOS); - }, skip: !Platform.isIOS); + // group("iOS loadFileURL", () { + // late Directory appSupportDir; + // late File fileHtml; + // late File fileJs; + // + // setUpAll(() async { + // appSupportDir = (await getApplicationSupportDirectory()); + // + // final Directory htmlFolder = Directory('${appSupportDir.path}/html/'); + // if (!await htmlFolder.exists()) { + // await htmlFolder.create(recursive: true); + // } + // + // final Directory jsFolder = Directory('${appSupportDir.path}/js/'); + // if (!await jsFolder.exists()) { + // await jsFolder.create(recursive: true); + // } + // + // var html = """ + // + // + // file scheme + // + // + // + // + // + // """; + // fileHtml = File(htmlFolder.path + "index.html"); + // fileHtml.writeAsStringSync(html); + // + // var js = """ + // console.log('message'); + // """; + // fileJs = File(jsFolder.path + "main.js"); + // fileJs.writeAsStringSync(js); + // }); + // + // testWidgets('initialUrl with file:// scheme and allowingReadAccessTo', + // (WidgetTester tester) async { + // final Completer consoleMessageShouldNotComplete = + // Completer(); + // await tester.pumpWidget( + // Directionality( + // textDirection: TextDirection.ltr, + // child: InAppWebView( + // key: GlobalKey(), + // initialUrlRequest: + // URLRequest(url: Uri.parse('file://${fileHtml.path}')), + // onConsoleMessage: (controller, consoleMessage) { + // consoleMessageShouldNotComplete.complete(consoleMessage); + // }, + // ), + // ), + // ); + // var result = await consoleMessageShouldNotComplete.future + // .timeout(const Duration(seconds: 2), onTimeout: () => null); + // expect(result, null); + // + // final Completer consoleMessageCompleter = + // Completer(); + // await tester.pumpWidget( + // Directionality( + // textDirection: TextDirection.ltr, + // child: InAppWebView( + // key: GlobalKey(), + // initialUrlRequest: + // URLRequest(url: Uri.parse('file://${fileHtml.path}')), + // initialOptions: InAppWebViewGroupOptions( + // ios: IOSInAppWebViewOptions( + // allowingReadAccessTo: + // Uri.parse('file://${appSupportDir.path}/'))), + // onConsoleMessage: (controller, consoleMessage) { + // consoleMessageCompleter.complete(consoleMessage); + // }, + // ), + // ), + // ); + // final ConsoleMessage consoleMessage = + // await consoleMessageCompleter.future; + // expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); + // expect(consoleMessage.message, 'message'); + // }, skip: defaultTargetPlatform != TargetPlatform.iOS); + // + // testWidgets( + // 'loadUrl with file:// scheme and allowingReadAccessTo argument', + // (WidgetTester tester) async { + // final Completer consoleMessageShouldNotComplete = + // Completer(); + // await tester.pumpWidget( + // Directionality( + // textDirection: TextDirection.ltr, + // child: InAppWebView( + // key: GlobalKey(), + // onWebViewCreated: (controller) { + // controller.loadUrl( + // urlRequest: + // URLRequest(url: Uri.parse('file://${fileHtml.path}'))); + // }, + // onConsoleMessage: (controller, consoleMessage) { + // consoleMessageShouldNotComplete.complete(consoleMessage); + // }, + // ), + // ), + // ); + // var result = await consoleMessageShouldNotComplete.future + // .timeout(const Duration(seconds: 2), onTimeout: () => null); + // expect(result, null); + // + // final Completer consoleMessageCompleter = + // Completer(); + // await tester.pumpWidget( + // Directionality( + // textDirection: TextDirection.ltr, + // child: InAppWebView( + // key: GlobalKey(), + // onWebViewCreated: (controller) { + // controller.loadUrl( + // urlRequest: + // URLRequest(url: Uri.parse('file://${fileHtml.path}')), + // allowingReadAccessTo: + // Uri.parse('file://${appSupportDir.path}/')); + // }, + // onConsoleMessage: (controller, consoleMessage) { + // consoleMessageCompleter.complete(consoleMessage); + // }, + // ), + // ), + // ); + // final ConsoleMessage consoleMessage = + // await consoleMessageCompleter.future; + // expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); + // expect(consoleMessage.message, 'message'); + // }, skip: defaultTargetPlatform != TargetPlatform.iOS); + // }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('JavaScript Handler', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -899,7 +899,7 @@ void main() { await controller.evaluateJavascript(source: "exitFullscreen();"); await expectLater(onExitFullscreenCompleter.future, completes); - }, skip: true /*!Platform.isAndroid*/); + }, skip: true /*defaultTargetPlatform != TargetPlatform.android*/); }); group('Audio playback policy', () { @@ -1205,8 +1205,8 @@ void main() { scrollPosY = await controller.getScrollY(); expect(scrollPosX, X_SCROLL * 2); expect(scrollPosY, Y_SCROLL * 2); - }, skip: !Platform.isAndroid); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); + }, skip: defaultTargetPlatform != TargetPlatform.android); group('shouldOverrideUrlLoading', () { final String page = @@ -1318,7 +1318,7 @@ void main() { 'https://github.com/pichillilorenzo/flutter_inappwebview'); pageLoads.close(); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('can block requests', (WidgetTester tester) async { final Completer controllerCompleter = @@ -1439,9 +1439,9 @@ void main() { final String url = await errorUrlCompleter.future; final int code = await errorCodeCompleter.future; - if (Platform.isAndroid) { + if (defaultTargetPlatform == TargetPlatform.android) { expect(code, -2); - } else if (Platform.isIOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS) { expect(code, -1003); } expect(url, 'https://www.notawebsite..com/'); @@ -1502,7 +1502,7 @@ void main() { await controllerCompleter.future; final String? currentUrl = (await controller.getUrl())?.toString(); expect(currentUrl, 'https://github.com/flutter'); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('target _blank opens in same window', (WidgetTester tester) async { @@ -1587,7 +1587,7 @@ void main() { pageLoads.close(); }, - skip: true /* !Platform.isAndroid */, + skip: true /* defaultTargetPlatform != TargetPlatform.android */, ); testWidgets( @@ -1663,7 +1663,7 @@ void main() { completion(null), ); }, - skip: !Platform.isAndroid, + skip: defaultTargetPlatform != TargetPlatform.android, ); group('intercept ajax request', () { @@ -3016,7 +3016,7 @@ setTimeout(function() { final String url = await pageLoaded.future; expect(url, "chrome://safe-browsing/match?type=malware"); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('onScrollChanged', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -3295,7 +3295,7 @@ setTimeout(function() { expect(listEquals(resources, ['android.webkit.resource.VIDEO_CAPTURE']), true); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('androidShouldInterceptRequest', (WidgetTester tester) async { List resourceList = [ @@ -3352,7 +3352,7 @@ setTimeout(function() { await pageLoaded.future; await loadedResourceCompleter.future; expect(resourceLoaded, containsAll(resourceList)); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('androidOnReceivedIcon', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -3383,7 +3383,7 @@ setTimeout(function() { await pageLoaded.future; final Uint8List icon = await onReceivedIconCompleter.future; expect(icon, isNotNull); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('androidOnReceivedTouchIconUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -3423,7 +3423,7 @@ setTimeout(function() { final String url = await onReceivedTouchIconUrlCompleter.future; expect(url, "https://placehold.it/72x72"); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('androidOnJsBeforeUnload', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -3466,7 +3466,7 @@ setTimeout(function() { source: "window.location.href = 'https://github.com/flutter';"); final String url = await onJsBeforeUnloadCompleter.future; expect(url, 'https://github.com/flutter'); - }, skip: true /*!Platform.isAndroid*/); + }, skip: true /*defaultTargetPlatform != TargetPlatform.android*/); group("iosOnNavigationResponse", () { testWidgets('allow navigation', (WidgetTester tester) async { @@ -3503,7 +3503,7 @@ setTimeout(function() { await pageLoaded.future; final String url = await onNavigationResponseCompleter.future; expect(url, 'https://github.com/flutter'); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('cancel navigation', (WidgetTester tester) async { final Completer controllerCompleter = @@ -3539,8 +3539,8 @@ setTimeout(function() { final String url = await onNavigationResponseCompleter.future; expect(url, 'https://github.com/flutter'); expect(pageLoaded.future, doesNotComplete); - }, skip: !Platform.isIOS); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('initialUserScripts', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -4104,11 +4104,11 @@ setTimeout(function() { final InAppWebViewController controller = await controllerCompleter.future; - if (Platform.isAndroid) { + if (defaultTargetPlatform == TargetPlatform.android) { await pageLoaded.future; expect(await controller.evaluateJavascript(source: "document.body"), isNullOrEmpty); - } else if (Platform.isIOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS) { expect(pageLoaded.future, doesNotComplete); } }); @@ -4797,52 +4797,52 @@ setTimeout(function() { pageLoads.close(); }); - testWidgets('saveWebArchive', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - // wait a little bit after page load otherwise Android will not save the web archive - await Future.delayed(Duration(seconds: 1)); - - var supportDir = await getApplicationSupportDirectory(); - - var fileName = "flutter-website."; - if (Platform.isAndroid) { - fileName = fileName + WebArchiveFormat.MHT.toValue(); - } else if (Platform.isIOS) { - fileName = fileName + WebArchiveFormat.WEBARCHIVE.toValue(); - } - - var fullPath = supportDir.path + Platform.pathSeparator + fileName; - var path = await controller.saveWebArchive(filePath: fullPath); - expect(path, isNotNull); - expect(path, endsWith(fileName)); - - path = await controller.saveWebArchive( - filePath: supportDir.path, autoname: true); - expect(path, isNotNull); - }); + // testWidgets('saveWebArchive', (WidgetTester tester) async { + // final Completer controllerCompleter = Completer(); + // final Completer pageLoaded = Completer(); + // + // await tester.pumpWidget( + // Directionality( + // textDirection: TextDirection.ltr, + // child: InAppWebView( + // key: GlobalKey(), + // initialUrlRequest: + // URLRequest(url: Uri.parse('https://github.com/flutter')), + // onWebViewCreated: (controller) { + // controllerCompleter.complete(controller); + // }, + // onLoadStop: (controller, url) { + // pageLoaded.complete(); + // }, + // ), + // ), + // ); + // + // final InAppWebViewController controller = + // await controllerCompleter.future; + // await pageLoaded.future; + // + // // wait a little bit after page load otherwise Android will not save the web archive + // await Future.delayed(Duration(seconds: 1)); + // + // var supportDir = await getApplicationSupportDirectory(); + // + // var fileName = "flutter-website."; + // if (defaultTargetPlatform == TargetPlatform.android) { + // fileName = fileName + WebArchiveFormat.MHT.toValue(); + // } else if (defaultTargetPlatform == TargetPlatform.iOS) { + // fileName = fileName + WebArchiveFormat.WEBARCHIVE.toValue(); + // } + // + // var fullPath = supportDir.path + Platform.pathSeparator + fileName; + // var path = await controller.saveWebArchive(filePath: fullPath); + // expect(path, isNotNull); + // expect(path, endsWith(fileName)); + // + // path = await controller.saveWebArchive( + // filePath: supportDir.path, autoname: true); + // expect(path, isNotNull); + // }); testWidgets('isSecureContext', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -5070,7 +5070,7 @@ setTimeout(function() { await controllerCompleter.future; await pageLoaded.future; await expectLater(controller.android.clearSslPreferences(), completes); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('pause/resume', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5100,7 +5100,7 @@ setTimeout(function() { await expectLater(controller.android.pause(), completes); await Future.delayed(Duration(seconds: 1)); await expectLater(controller.android.resume(), completes); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('getOriginalUrl', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5159,7 +5159,7 @@ setTimeout(function() { expect(await controller.android.pageDown(bottom: false), true); await Future.delayed(Duration(seconds: 1)); expect(await controller.android.pageUp(top: false), true); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('zoomIn/zoomOut', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5189,7 +5189,7 @@ setTimeout(function() { expect(await controller.android.zoomIn(), true); await Future.delayed(Duration(seconds: 1)); expect(await controller.android.zoomOut(), true); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('clearHistory', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5231,39 +5231,39 @@ setTimeout(function() { expect(webHistory!.list!.length, 1); pageLoads.close(); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); test('clearClientCertPreferences', () async { await expectLater( AndroidInAppWebViewController.clearClientCertPreferences(), completes); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); test('getSafeBrowsingPrivacyPolicyUrl', () async { expect( await AndroidInAppWebViewController .getSafeBrowsingPrivacyPolicyUrl(), isNotNull); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); test('setSafeBrowsingWhitelist', () async { expect( await AndroidInAppWebViewController.setSafeBrowsingWhitelist( hosts: ["flutter.dev", "github.com"]), true); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); test('getCurrentWebViewPackage', () async { expect(await AndroidInAppWebViewController.getCurrentWebViewPackage(), isNotNull); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); test('setWebContentsDebuggingEnabled', () async { expect( AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true), completes); - }, skip: !Platform.isAndroid); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); + }, skip: defaultTargetPlatform != TargetPlatform.android); group('ios methods', () { testWidgets('reloadFromOrigin', (WidgetTester tester) async { @@ -5292,7 +5292,7 @@ setTimeout(function() { await controllerCompleter.future; await pageLoaded.future; await expectLater(controller.ios.reloadFromOrigin(), completes); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('createPdf', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5325,7 +5325,7 @@ setTimeout(function() { var pdf = await controller.ios .createPdf(iosWKPdfConfiguration: iosWKPdfConfiguration); expect(pdf, isNotNull); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('createWebArchiveData', (WidgetTester tester) async { final Completer controllerCompleter = @@ -5354,7 +5354,7 @@ setTimeout(function() { await pageLoaded.future; expect(await controller.ios.createWebArchiveData(), isNotNull); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); testWidgets('Apple Pay API enabled', (WidgetTester tester) async { final Completer pageLoaded = Completer(); @@ -5398,13 +5398,13 @@ setTimeout(function() { await pageLoaded.future; final message = await alertMessageCompleter.future; expect(message, 'true'); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); test('handlesURLScheme', () async { expect(await IOSInAppWebViewController.handlesURLScheme("http"), true); expect(await IOSInAppWebViewController.handlesURLScheme("https"), true); - }, skip: !Platform.isIOS); - }, skip: !Platform.isIOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); }); group('Service Worker', () { @@ -5445,7 +5445,7 @@ setTimeout(function() { ); expect(completer.future, completes); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); testWidgets('setServiceWorkerClient to null', (WidgetTester tester) async { final Completer pageLoaded = Completer(); @@ -5478,7 +5478,7 @@ setTimeout(function() { final String url = await pageLoaded.future; expect(url, "https://mdn.github.io/sw-test/"); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); }); group('Cookie Manager', () { @@ -5924,7 +5924,7 @@ setTimeout(function() { await chromeSafariBrowser.browserClosed.future; expect(chromeSafariBrowser.isOpened(), false); }); - }, skip: !Platform.isAndroid); + }, skip: defaultTargetPlatform != TargetPlatform.android); }); group('InAppLocalhostServer', () { diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 5af467eb..c3a4a746 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -121,8 +121,9 @@ class _InAppWebViewExampleScreenState extends State { initialSettings: settings, // contextMenu: contextMenu, pullToRefreshController: pullToRefreshController, - onWebViewCreated: (controller) { + onWebViewCreated: (controller) async { webViewController = controller; + print(await controller.getUrl()); }, onLoadStart: (controller, url) async { setState(() { diff --git a/lib/assets/web/web_support.js b/lib/assets/web/web_support.js index 5e2b18a6..4b829c24 100644 --- a/lib/assets/web/web_support.js +++ b/lib/assets/web/web_support.js @@ -354,7 +354,17 @@ window.flutter_inappwebview = { console.log(e); } } - } + }, + getUrl: function () { + var iframe = webView.iframe; + var url = iframe.src; + try { + url = iframe.contentWindow.location.href; + } catch (e) { + console.log(e); + } + return url; + }, }; return webView; diff --git a/lib/src/in_app_webview/in_app_webview_controller.dart b/lib/src/in_app_webview/in_app_webview_controller.dart index bc69f471..6570bdf4 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -1179,9 +1179,13 @@ class InAppWebViewController ///Gets the URL for the current page. ///This is not always the same as the URL passed to [WebView.onLoadStart] because although the load for that URL has begun, the current page may not have changed. /// + ///**NOTE for Web**: If `window.location.href` isn't accessible inside the iframe, + ///it will return the current value of the `iframe.src` attribute. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.getUrl](https://developer.android.com/reference/android/webkit/WebView#getUrl())) ///- iOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url)) + ///- Web Future getUrl() async { Map args = {}; String? url = await _channel.invokeMethod('getUrl', args); diff --git a/lib/src/web/in_app_web_view_web_element.dart b/lib/src/web/in_app_web_view_web_element.dart index a053113a..0456a397 100644 --- a/lib/src/web/in_app_web_view_web_element.dart +++ b/lib/src/web/in_app_web_view_web_element.dart @@ -92,6 +92,8 @@ class InAppWebViewWebElement { call.arguments["settings"].cast()); setSettings(newSettings); break; + case "getUrl": + return getUrl(); case "dispose": dispose(); break; @@ -217,6 +219,14 @@ class InAppWebViewWebElement { _callMethod("stopLoading"); } + Future getUrl() async { + String? url = _callMethod("getUrl"); + if (url == null || url.isEmpty || url == 'about:blank') { + url = iframe.src; + } + return url; + } + Set getSandbox() { var sandbox = iframe.sandbox; Set values = Set(); diff --git a/pubspec.yaml b/pubspec.yaml index e4dc4208..e23f8df1 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,12 +10,14 @@ environment: dependencies: flutter: sdk: flutter + flutter_web_plugins: + sdk: flutter js: ^0.6.3 dev_dependencies: flutter_test: sdk: flutter - flutter_web_plugins: + flutter_driver: sdk: flutter pedantic: ^1.11.1