diff --git a/README.md b/README.md index 3b0f4b04..65c22317 100755 --- a/README.md +++ b/README.md @@ -45,6 +45,18 @@ Send a submission request to the [Submit App](https://inappwebview.dev/submit-ap Add `flutter_inappwebview` as a [dependency in your pubspec.yaml file](https://flutter.io/using-packages/). +### Installation - Web support + +To make it work properly on the Web platformm, you need to add the `web_support.js` file inside the `` of your `web/index.html` file: + +```html + + + + + +``` + ## Main Classes Overview * [InAppWebView](https://inappwebview.dev/docs/in-app-webview/basic-usage/): Flutter Widget for adding an inline native WebView integrated into the flutter widget tree. diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index 31b6e369..776845e5 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -5498,7 +5498,7 @@ setTimeout(function() { if (swAvailable && swInterceptAvailable) { AndroidServiceWorkerController serviceWorkerController = - AndroidServiceWorkerController.instance(); + AndroidServiceWorkerController.instance(); await serviceWorkerController.setServiceWorkerClient(null); } @@ -5509,7 +5509,7 @@ setTimeout(function() { child: InAppWebView( key: GlobalKey(), initialUrlRequest: - URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')), + URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')), onLoadStop: (controller, url) { pageLoaded.complete(url!.toString()); }, @@ -5874,7 +5874,8 @@ setTimeout(function() { group('Android Custom Tabs', () { test('add custom action button', () async { var chromeSafariBrowser = new MyChromeSafariBrowser(); - var actionButtonIcon = await rootBundle.load('test_assets/images/flutter-logo.png'); + var actionButtonIcon = + await rootBundle.load('test_assets/images/flutter-logo.png'); chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton( id: 1, description: 'Action Button description', @@ -5892,7 +5893,8 @@ setTimeout(function() { await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); }, throwsA(isInstanceOf())); - await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await expectLater( + chromeSafariBrowser.firstPageLoaded.future, completes); await chromeSafariBrowser.close(); await chromeSafariBrowser.browserClosed.future; expect(chromeSafariBrowser.isOpened(), false); diff --git a/example/lib/headless_in_app_webview.screen.dart b/example/lib/headless_in_app_webview.screen.dart index 33b46e1a..38e63a72 100755 --- a/example/lib/headless_in_app_webview.screen.dart +++ b/example/lib/headless_in_app_webview.screen.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; @@ -19,8 +20,12 @@ class _HeadlessInAppWebViewExampleScreenState void initState() { super.initState(); + var url = !kIsWeb + ? Uri.parse("https://flutter.dev") + : Uri.parse("http://localhost:${Uri.base.port}/page.html"); + headlessWebView = new HeadlessInAppWebView( - initialUrlRequest: URLRequest(url: Uri.parse("https://flutter.dev")), + initialUrlRequest: URLRequest(url: url), initialSettings: InAppWebViewSettings(), onWebViewCreated: (controller) { print('HeadlessInAppWebView created!'); @@ -78,6 +83,9 @@ class _HeadlessInAppWebViewExampleScreenState }, child: Text("Run HeadlessInAppWebView")), ), + Container( + height: 10, + ), Center( child: ElevatedButton( onPressed: () async { @@ -91,6 +99,9 @@ class _HeadlessInAppWebViewExampleScreenState }, child: Text("Send console.log message")), ), + Container( + height: 10, + ), Center( child: ElevatedButton( onPressed: () { diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index a8d56638..5af467eb 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -13,17 +13,16 @@ class InAppWebViewExampleScreen extends StatefulWidget { } class _InAppWebViewExampleScreenState extends State { - final GlobalKey webViewKey = GlobalKey(); InAppWebViewController? webViewController; InAppWebViewSettings settings = InAppWebViewSettings( - useShouldOverrideUrlLoading: true, - mediaPlaybackRequiresUserGesture: false, - useHybridComposition: true, - allowsInlineMediaPlayback: true, - iframeAllow: "camera; microphone", - iframeAllowFullscreen: true, + useShouldOverrideUrlLoading: true, + mediaPlaybackRequiresUserGesture: false, + useHybridComposition: true, + allowsInlineMediaPlayback: true, + iframeAllow: "camera; microphone", + iframeAllowFullscreen: true, ); PullToRefreshController? pullToRefreshController; @@ -57,25 +56,30 @@ class _InAppWebViewExampleScreenState extends State { print("onHideContextMenu"); }, onContextMenuActionItemClicked: (contextMenuItemClicked) async { + var id = contextMenuItemClicked.id; print("onContextMenuActionItemClicked: " + - contextMenuItemClicked.id.toString() + + id.toString() + " " + contextMenuItemClicked.title); }); - pullToRefreshController = !kIsWeb ? PullToRefreshController( - settings: PullToRefreshSettings( - color: Colors.blue, - ), - onRefresh: () async { - if (defaultTargetPlatform == TargetPlatform.android) { - webViewController?.reload(); - } else if (defaultTargetPlatform == TargetPlatform.iOS) { - webViewController?.loadUrl( - urlRequest: URLRequest(url: await webViewController?.getUrl())); - } - }, - ) : null; + pullToRefreshController = kIsWeb + ? null + : PullToRefreshController( + settings: PullToRefreshSettings( + color: Colors.blue, + ), + onRefresh: () async { + if (defaultTargetPlatform == TargetPlatform.android) { + webViewController?.reload(); + } else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { + webViewController?.loadUrl( + urlRequest: + URLRequest(url: await webViewController?.getUrl())); + } + }, + ); } @override @@ -91,108 +95,105 @@ class _InAppWebViewExampleScreenState extends State { body: SafeArea( child: Column(children: [ TextField( - decoration: InputDecoration( - prefixIcon: Icon(Icons.search) - ), + decoration: InputDecoration(prefixIcon: Icon(Icons.search)), controller: urlController, keyboardType: TextInputType.url, onSubmitted: (value) { var url = Uri.parse(value); if (url.scheme.isEmpty) { - url = Uri.parse("https://www.google.com/search?q=" + value); + url = Uri.parse((!kIsWeb + ? "https://www.google.com/search?q=" + : "https://www.bing.com/search?q=") + + value); } - webViewController?.loadUrl( - urlRequest: URLRequest(url: url)); + webViewController?.loadUrl(urlRequest: URLRequest(url: url)); }, ), Expanded( - child: Stack( - children: [ - InAppWebView( - key: webViewKey, - // contextMenu: contextMenu, - // initialUrlRequest: - // URLRequest(url: Uri.parse("https://www.pubnub.com/developers/demos/webrtc/launch/")), - initialUrlRequest: - URLRequest(url: Uri.parse(Uri.base.toString().replaceFirst("/#/", "/") + 'page.html')), - // initialUrlRequest: - // URLRequest(url: Uri.parse('https://flutter.dev')), - // initialFile: "assets/index.html", - initialUserScripts: UnmodifiableListView([]), - initialSettings: settings, - pullToRefreshController: pullToRefreshController, - onWebViewCreated: (controller) async { - webViewController = controller; - }, - onLoadStart: (controller, url) async { - setState(() { - this.url = url.toString(); - urlController.text = this.url; - }); - }, - onPermissionRequest: (controller, request) async { - return PermissionResponse( - resources: request.resources, - action: PermissionResponseAction.GRANT); - }, - shouldOverrideUrlLoading: (controller, navigationAction) async { - var uri = navigationAction.request.url!; + child: Stack( + children: [ + InAppWebView( + key: webViewKey, + initialUrlRequest: + URLRequest(url: Uri.parse("https://flutter.dev")), + // initialFile: "assets/index.html", + initialUserScripts: UnmodifiableListView([]), + initialSettings: settings, + // contextMenu: contextMenu, + pullToRefreshController: pullToRefreshController, + onWebViewCreated: (controller) { + webViewController = controller; + }, + onLoadStart: (controller, url) async { + setState(() { + this.url = url.toString(); + urlController.text = this.url; + }); + }, + onPermissionRequest: (controller, request) async { + return PermissionResponse( + resources: request.resources, + action: PermissionResponseAction.GRANT); + }, + shouldOverrideUrlLoading: + (controller, navigationAction) async { + var uri = navigationAction.request.url!; - if (![ - "http", - "https", - "file", - "chrome", - "data", - "javascript", - "about" - ].contains(uri.scheme)) { - if (await canLaunch(url)) { - // Launch the App - await launch( - url, - ); - // and cancel the request - return NavigationActionPolicy.CANCEL; - } + if (![ + "http", + "https", + "file", + "chrome", + "data", + "javascript", + "about" + ].contains(uri.scheme)) { + if (await canLaunch(url)) { + // Launch the App + await launch( + url, + ); + // and cancel the request + return NavigationActionPolicy.CANCEL; } + } - return NavigationActionPolicy.ALLOW; - }, - onLoadStop: (controller, url) async { + return NavigationActionPolicy.ALLOW; + }, + onLoadStop: (controller, url) async { + pullToRefreshController?.endRefreshing(); + setState(() { + this.url = url.toString(); + urlController.text = this.url; + }); + }, + onLoadError: (controller, url, code, message) { + pullToRefreshController?.endRefreshing(); + }, + onProgressChanged: (controller, progress) { + if (progress == 100) { pullToRefreshController?.endRefreshing(); - setState(() { - this.url = url.toString(); - urlController.text = this.url; - }); - }, - onLoadError: (controller, url, code, message) { - pullToRefreshController?.endRefreshing(); - }, - onProgressChanged: (controller, progress) { - if (progress == 100) { - pullToRefreshController?.endRefreshing(); - } - setState(() { - this.progress = progress / 100; - urlController.text = this.url; - }); - }, - onUpdateVisitedHistory: (controller, url, androidIsReload) { - setState(() { - this.url = url.toString(); - urlController.text = this.url; - }); - }, - onConsoleMessage: (controller, consoleMessage) { - print(consoleMessage); - }, - ), - !kIsWeb && progress < 1.0 - ? LinearProgressIndicator(value: progress) - : Container(), - ], - ), + } + setState(() { + this.progress = progress / 100; + urlController.text = this.url; + }); + }, + onUpdateVisitedHistory: (controller, url, androidIsReload) { + setState(() { + this.url = url.toString(); + urlController.text = this.url; + }); + }, + onConsoleMessage: (controller, consoleMessage) { + print(consoleMessage); + }, + ), + progress < 1.0 + ? LinearProgressIndicator(value: progress) + : Container(), + ], + ), ), ButtonBar( alignment: MainAxisAlignment.center, @@ -215,12 +216,6 @@ class _InAppWebViewExampleScreenState extends State { webViewController?.reload(); }, ), - ElevatedButton( - child: Icon(Icons.cancel), - onPressed: () { - webViewController?.stopLoading(); - }, - ), ], ), ]))); diff --git a/lib/flutter_inappwebview_web.dart b/lib/flutter_inappwebview_web.dart index 1b1883e1..1d2b2c00 100755 --- a/lib/flutter_inappwebview_web.dart +++ b/lib/flutter_inappwebview_web.dart @@ -25,4 +25,4 @@ library flutter_inappwebview; import 'package:js/js.dart'; export 'src/main.dart'; -export 'src/web/main.dart'; \ No newline at end of file +export 'src/web/main.dart'; diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart index b8a477f7..8e9ea0f7 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart @@ -251,7 +251,8 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions { } settings.screenOrientation = map["screenOrientation"]; } - if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { settings.entersReaderIfAvailable = map["entersReaderIfAvailable"]; settings.barCollapsingEnabled = map["barCollapsingEnabled"]; settings.dismissButtonStyle = diff --git a/lib/src/cookie_manager.dart b/lib/src/cookie_manager.dart index 11c93661..b615613a 100755 --- a/lib/src/cookie_manager.dart +++ b/lib/src/cookie_manager.dart @@ -82,7 +82,8 @@ class CookieManager { bool? isSecure, bool? isHttpOnly, HTTPCookieSameSitePolicy? sameSite, - @Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController, + @Deprecated("Use webViewController instead") + InAppWebViewController? iosBelow11WebViewController, InAppWebViewController? webViewController}) async { if (domain == null) domain = _getDomainName(url); @@ -200,7 +201,8 @@ class CookieManager { ///- Web Future> getCookies( {required Uri url, - @Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController, + @Deprecated("Use webViewController instead") + InAppWebViewController? iosBelow11WebViewController, InAppWebViewController? webViewController}) async { assert(url.toString().isNotEmpty); @@ -318,7 +320,8 @@ class CookieManager { Future getCookie( {required Uri url, required String name, - @Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController, + @Deprecated("Use webViewController instead") + InAppWebViewController? iosBelow11WebViewController, InAppWebViewController? webViewController}) async { assert(url.toString().isNotEmpty); assert(name.isNotEmpty); @@ -388,7 +391,8 @@ class CookieManager { required String name, String domain = "", String path = "/", - @Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController, + @Deprecated("Use webViewController instead") + InAppWebViewController? iosBelow11WebViewController, InAppWebViewController? webViewController}) async { if (domain.isEmpty) domain = _getDomainName(url); @@ -449,7 +453,8 @@ class CookieManager { {required Uri url, String domain = "", String path = "/", - @Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController, + @Deprecated("Use webViewController instead") + InAppWebViewController? iosBelow11WebViewController, InAppWebViewController? webViewController}) async { if (domain.isEmpty) domain = _getDomainName(url); @@ -537,13 +542,13 @@ class CookieManager { Future _getCookieExpirationDate(int expiresDate) async { var platformUtil = PlatformUtil.instance(); var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc(); - return !kIsWeb ? - await platformUtil.formatDate( - date: dateTime, - format: 'EEE, dd MMM yyyy hh:mm:ss z', - locale: 'en_US', - timezone: 'GMT') : - await platformUtil.getWebCookieExpirationDate(date: dateTime); + return !kIsWeb + ? await platformUtil.formatDate( + date: dateTime, + format: 'EEE, dd MMM yyyy hh:mm:ss z', + locale: 'en_US', + timezone: 'GMT') + : await platformUtil.getWebCookieExpirationDate(date: dateTime); } } diff --git a/lib/src/in_app_browser/in_app_browser_settings.dart b/lib/src/in_app_browser/in_app_browser_settings.dart index 02b38cd3..dad89bee 100755 --- a/lib/src/in_app_browser/in_app_browser_settings.dart +++ b/lib/src/in_app_browser/in_app_browser_settings.dart @@ -288,7 +288,8 @@ class InAppBrowserSettings settings.shouldCloseOnBackButtonPressed = map["shouldCloseOnBackButtonPressed"]; } - if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { settings.toolbarTopTranslucent = map["toolbarTopTranslucent"]; settings.toolbarTopTintColor = UtilColor.fromHex(map["toolbarTopTintColor"]); 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 de7b2b5a..12dab288 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -75,7 +75,8 @@ class InAppWebViewController InAppWebViewController(dynamic id, WebView webview) { this._id = id; - this._channel = MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id'); + this._channel = + MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id'); this._channel.setMethodCallHandler(handleMethod); this._webview = webview; this._userScripts = @@ -1700,7 +1701,8 @@ class InAppWebViewController args.putIfAbsent('source', () => source); args.putIfAbsent('contentWorld', () => contentWorld?.toMap()); var data = await _channel.invokeMethod('evaluateJavascript', args); - if (data != null && (defaultTargetPlatform == TargetPlatform.android || kIsWeb)) { + if (data != null && + (defaultTargetPlatform == TargetPlatform.android || kIsWeb)) { try { // try to json decode the data coming from JavaScript // otherwise return it as it is. diff --git a/lib/src/in_app_webview/in_app_webview_settings.dart b/lib/src/in_app_webview/in_app_webview_settings.dart index 2aed5e03..9731ef67 100755 --- a/lib/src/in_app_webview/in_app_webview_settings.dart +++ b/lib/src/in_app_webview/in_app_webview_settings.dart @@ -1053,132 +1053,133 @@ class InAppWebViewSettings ///- Web String? iframeCsp; - InAppWebViewSettings( - {this.useShouldOverrideUrlLoading = false, - this.useOnLoadResource = false, - this.useOnDownloadStart = false, - this.clearCache = false, - this.userAgent = "", - this.applicationNameForUserAgent = "", - this.javaScriptEnabled = true, - this.javaScriptCanOpenWindowsAutomatically = false, - this.mediaPlaybackRequiresUserGesture = true, - this.minimumFontSize, - this.verticalScrollBarEnabled = true, - this.horizontalScrollBarEnabled = true, - this.resourceCustomSchemes = const [], - this.contentBlockers = const [], - this.preferredContentMode = UserPreferredContentMode.RECOMMENDED, - this.useShouldInterceptAjaxRequest = false, - this.useShouldInterceptFetchRequest = false, - this.incognito = false, - this.cacheEnabled = true, - this.transparentBackground = false, - this.disableVerticalScroll = false, - this.disableHorizontalScroll = false, - this.disableContextMenu = false, - this.supportZoom = true, - this.allowFileAccessFromFileURLs = false, - this.allowUniversalAccessFromFileURLs = false, - this.textZoom = 100, - this.clearSessionCache = false, - this.builtInZoomControls = true, - this.displayZoomControls = false, - this.databaseEnabled = true, - this.domStorageEnabled = true, - this.useWideViewPort = true, - this.safeBrowsingEnabled = true, - this.mixedContentMode, - this.allowContentAccess = true, - this.allowFileAccess = true, - this.appCachePath, - this.blockNetworkImage = false, - this.blockNetworkLoads = false, - this.cacheMode = CacheMode.LOAD_DEFAULT, - this.cursiveFontFamily = "cursive", - this.defaultFixedFontSize = 16, - this.defaultFontSize = 16, - this.defaultTextEncodingName = "UTF-8", - this.disabledActionModeMenuItems, - this.fantasyFontFamily = "fantasy", - this.fixedFontFamily = "monospace", - this.forceDark = ForceDark.FORCE_DARK_OFF, - this.geolocationEnabled = true, - this.layoutAlgorithm, - this.loadWithOverviewMode = true, - this.loadsImagesAutomatically = true, - this.minimumLogicalFontSize = 8, - this.needInitialFocus = true, - this.offscreenPreRaster = false, - this.sansSerifFontFamily = "sans-serif", - this.serifFontFamily = "sans-serif", - this.standardFontFamily = "sans-serif", - this.saveFormData = true, - this.thirdPartyCookiesEnabled = true, - this.hardwareAcceleration = true, - this.initialScale = 0, - this.supportMultipleWindows = false, - this.regexToCancelSubFramesLoading, - this.useHybridComposition = false, - this.useShouldInterceptRequest = false, - this.useOnRenderProcessGone = false, - this.overScrollMode = OverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS, - this.networkAvailable, - this.scrollBarStyle = ScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY, - this.verticalScrollbarPosition = - VerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT, - this.scrollBarDefaultDelayBeforeFade, - this.scrollbarFadingEnabled = true, - this.scrollBarFadeDuration, - this.rendererPriorityPolicy, - this.disableDefaultErrorPage = false, - this.verticalScrollbarThumbColor, - this.verticalScrollbarTrackColor, - this.horizontalScrollbarThumbColor, - this.horizontalScrollbarTrackColor, - this.disallowOverScroll = false, - this.enableViewportScale = false, - this.suppressesIncrementalRendering = false, - this.allowsAirPlayForMediaPlayback = true, - this.allowsBackForwardNavigationGestures = true, - this.allowsLinkPreview = true, - this.ignoresViewportScaleLimits = false, - this.allowsInlineMediaPlayback = false, - this.allowsPictureInPictureMediaPlayback = true, - this.isFraudulentWebsiteWarningEnabled = true, - this.selectionGranularity = SelectionGranularity.DYNAMIC, - this.dataDetectorTypes = const [DataDetectorTypes.NONE], - this.sharedCookiesEnabled = false, - this.automaticallyAdjustsScrollIndicatorInsets = false, - this.accessibilityIgnoresInvertColors = false, - this.decelerationRate = ScrollViewDecelerationRate.NORMAL, - this.alwaysBounceVertical = false, - this.alwaysBounceHorizontal = false, - this.scrollsToTop = true, - this.isPagingEnabled = false, - this.maximumZoomScale = 1.0, - this.minimumZoomScale = 1.0, - this.contentInsetAdjustmentBehavior = - ScrollViewContentInsetAdjustmentBehavior.NEVER, - this.isDirectionalLockEnabled = false, - this.mediaType, - this.pageZoom = 1.0, - this.limitsNavigationsToAppBoundDomains = false, - this.useOnNavigationResponse = false, - this.applePayAPIEnabled = false, - this.allowingReadAccessTo, - this.disableLongPressContextMenuOnLinks = false, - this.disableInputAccessoryView = false, - this.underPageBackgroundColor, - this.isTextInteractionEnabled = true, - this.isSiteSpecificQuirksModeEnabled = true, - this.upgradeKnownHostsToHTTPS = true, - this.iframeAllow, - this.iframeAllowFullscreen, - this.iframeSandbox, - this.iframeReferrerPolicy, - this.iframeName, - this.iframeCsp,}) { + InAppWebViewSettings({ + this.useShouldOverrideUrlLoading = false, + this.useOnLoadResource = false, + this.useOnDownloadStart = false, + this.clearCache = false, + this.userAgent = "", + this.applicationNameForUserAgent = "", + this.javaScriptEnabled = true, + this.javaScriptCanOpenWindowsAutomatically = false, + this.mediaPlaybackRequiresUserGesture = true, + this.minimumFontSize, + this.verticalScrollBarEnabled = true, + this.horizontalScrollBarEnabled = true, + this.resourceCustomSchemes = const [], + this.contentBlockers = const [], + this.preferredContentMode = UserPreferredContentMode.RECOMMENDED, + this.useShouldInterceptAjaxRequest = false, + this.useShouldInterceptFetchRequest = false, + this.incognito = false, + this.cacheEnabled = true, + this.transparentBackground = false, + this.disableVerticalScroll = false, + this.disableHorizontalScroll = false, + this.disableContextMenu = false, + this.supportZoom = true, + this.allowFileAccessFromFileURLs = false, + this.allowUniversalAccessFromFileURLs = false, + this.textZoom = 100, + this.clearSessionCache = false, + this.builtInZoomControls = true, + this.displayZoomControls = false, + this.databaseEnabled = true, + this.domStorageEnabled = true, + this.useWideViewPort = true, + this.safeBrowsingEnabled = true, + this.mixedContentMode, + this.allowContentAccess = true, + this.allowFileAccess = true, + this.appCachePath, + this.blockNetworkImage = false, + this.blockNetworkLoads = false, + this.cacheMode = CacheMode.LOAD_DEFAULT, + this.cursiveFontFamily = "cursive", + this.defaultFixedFontSize = 16, + this.defaultFontSize = 16, + this.defaultTextEncodingName = "UTF-8", + this.disabledActionModeMenuItems, + this.fantasyFontFamily = "fantasy", + this.fixedFontFamily = "monospace", + this.forceDark = ForceDark.FORCE_DARK_OFF, + this.geolocationEnabled = true, + this.layoutAlgorithm, + this.loadWithOverviewMode = true, + this.loadsImagesAutomatically = true, + this.minimumLogicalFontSize = 8, + this.needInitialFocus = true, + this.offscreenPreRaster = false, + this.sansSerifFontFamily = "sans-serif", + this.serifFontFamily = "sans-serif", + this.standardFontFamily = "sans-serif", + this.saveFormData = true, + this.thirdPartyCookiesEnabled = true, + this.hardwareAcceleration = true, + this.initialScale = 0, + this.supportMultipleWindows = false, + this.regexToCancelSubFramesLoading, + this.useHybridComposition = false, + this.useShouldInterceptRequest = false, + this.useOnRenderProcessGone = false, + this.overScrollMode = OverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS, + this.networkAvailable, + this.scrollBarStyle = ScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY, + this.verticalScrollbarPosition = + VerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT, + this.scrollBarDefaultDelayBeforeFade, + this.scrollbarFadingEnabled = true, + this.scrollBarFadeDuration, + this.rendererPriorityPolicy, + this.disableDefaultErrorPage = false, + this.verticalScrollbarThumbColor, + this.verticalScrollbarTrackColor, + this.horizontalScrollbarThumbColor, + this.horizontalScrollbarTrackColor, + this.disallowOverScroll = false, + this.enableViewportScale = false, + this.suppressesIncrementalRendering = false, + this.allowsAirPlayForMediaPlayback = true, + this.allowsBackForwardNavigationGestures = true, + this.allowsLinkPreview = true, + this.ignoresViewportScaleLimits = false, + this.allowsInlineMediaPlayback = false, + this.allowsPictureInPictureMediaPlayback = true, + this.isFraudulentWebsiteWarningEnabled = true, + this.selectionGranularity = SelectionGranularity.DYNAMIC, + this.dataDetectorTypes = const [DataDetectorTypes.NONE], + this.sharedCookiesEnabled = false, + this.automaticallyAdjustsScrollIndicatorInsets = false, + this.accessibilityIgnoresInvertColors = false, + this.decelerationRate = ScrollViewDecelerationRate.NORMAL, + this.alwaysBounceVertical = false, + this.alwaysBounceHorizontal = false, + this.scrollsToTop = true, + this.isPagingEnabled = false, + this.maximumZoomScale = 1.0, + this.minimumZoomScale = 1.0, + this.contentInsetAdjustmentBehavior = + ScrollViewContentInsetAdjustmentBehavior.NEVER, + this.isDirectionalLockEnabled = false, + this.mediaType, + this.pageZoom = 1.0, + this.limitsNavigationsToAppBoundDomains = false, + this.useOnNavigationResponse = false, + this.applePayAPIEnabled = false, + this.allowingReadAccessTo, + this.disableLongPressContextMenuOnLinks = false, + this.disableInputAccessoryView = false, + this.underPageBackgroundColor, + this.isTextInteractionEnabled = true, + this.isSiteSpecificQuirksModeEnabled = true, + this.upgradeKnownHostsToHTTPS = true, + this.iframeAllow, + this.iframeAllowFullscreen, + this.iframeSandbox, + this.iframeReferrerPolicy, + this.iframeName, + this.iframeCsp, + }) { if (this.minimumFontSize == null) this.minimumFontSize = defaultTargetPlatform == TargetPlatform.android ? 8 : 0; @@ -1388,7 +1389,8 @@ class InAppWebViewSettings settings.iframeAllowFullscreen = map["iframeAllowFullscreen"]; settings.iframeSandbox = (map["iframeSandbox"] as List?) ?.map((e) => Sandbox.fromValue(e)) as List?; - settings.iframeReferrerPolicy = ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]); + settings.iframeReferrerPolicy = + ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]); settings.iframeName = map["iframeName"]; settings.iframeCsp = map["iframeCsp"]; } @@ -1460,7 +1462,8 @@ class InAppWebViewSettings settings.horizontalScrollbarTrackColor = UtilColor.fromHex(map["horizontalScrollbarTrackColor"]); } - if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { settings.disallowOverScroll = map["disallowOverScroll"]; settings.enableViewportScale = map["enableViewportScale"]; settings.suppressesIncrementalRendering = diff --git a/lib/src/in_app_webview/webview.dart b/lib/src/in_app_webview/webview.dart index be2e64e0..4028fa72 100644 --- a/lib/src/in_app_webview/webview.dart +++ b/lib/src/in_app_webview/webview.dart @@ -27,6 +27,8 @@ abstract class WebView { /// ///**NOTE for Web**: it will be dispatched at the same time of [onLoadStop] event ///because there isn't any way to capture the real load start event from an iframe. + ///If `window.location.href` isn't accessible inside the iframe, + ///the [url] parameter will have the current value of the `iframe.src` attribute. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap))) @@ -36,6 +38,9 @@ abstract class WebView { ///Event fired when the [WebView] finishes loading an [url]. /// + ///**NOTE for Web**: If `window.location.href` isn't accessible inside the iframe, + ///the [url] parameter will have the current value of the `iframe.src` attribute. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview)) diff --git a/lib/src/platform_util.dart b/lib/src/platform_util.dart index cccaee40..b64da391 100644 --- a/lib/src/platform_util.dart +++ b/lib/src/platform_util.dart @@ -47,8 +47,7 @@ class PlatformUtil { } ///Get cookie expiration date used by Web platform. - Future getWebCookieExpirationDate( - {required DateTime date}) async { + Future getWebCookieExpirationDate({required DateTime date}) async { Map args = {}; args.putIfAbsent('date', () => date.millisecondsSinceEpoch); return await _channel.invokeMethod('getWebCookieExpirationDate', args); diff --git a/lib/src/types.dart b/lib/src/types.dart index 63297d13..8b0665a3 100755 --- a/lib/src/types.dart +++ b/lib/src/types.dart @@ -4795,14 +4795,15 @@ class PermissionResourceType { PermissionResourceType.DEVICE_ORIENTATION_AND_MOTION, ].toSet(); - static PermissionResourceType? fromValue(dynamic? value) { + static PermissionResourceType? fromValue(dynamic value) { if (value != null) { try { Set valueList = [].toSet(); if (defaultTargetPlatform == TargetPlatform.android) { valueList = PermissionResourceType._androidValues; - } else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { valueList = PermissionResourceType._appleValues; } return valueList.firstWhere((element) => element.toValue() == value); @@ -7395,7 +7396,8 @@ class SslErrorType { Set valueList = [].toSet(); if (defaultTargetPlatform == TargetPlatform.android) { valueList = SslErrorType._androidValues; - } else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { valueList = SslErrorType._appleValues; } return valueList.firstWhere((element) => element.toValue() == value); @@ -7426,7 +7428,8 @@ class SslErrorType { default: return "SSL_NOTYETVALID"; } - } else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { switch (_value) { case 3: return "DENY"; @@ -10768,8 +10771,7 @@ class Sandbox { return _NONE; } try { - return Sandbox.values - .firstWhere((element) => element.toValue() == value); + return Sandbox.values.firstWhere((element) => element.toValue() == value); } catch (e) { return null; } @@ -10778,7 +10780,8 @@ class Sandbox { String? toValue() => _value; @override - String toString() => _value == null ? "allow-all" : (_value == "" ? "allow-none" : ""); + String toString() => + _value == null ? "allow-all" : (_value == "" ? "allow-none" : ""); static const _ALL = const Sandbox._internal(null); static const _NONE = const Sandbox._internal(""); @@ -10799,10 +10802,12 @@ class Sandbox { static const ALLOW_MODALS = const Sandbox._internal("allow-modals"); ///Lets the resource lock the screen orientation. - static const ALLOW_ORIENTATION_LOCK = const Sandbox._internal("allow-orientation-lock"); + static const ALLOW_ORIENTATION_LOCK = + const Sandbox._internal("allow-orientation-lock"); ///Lets the resource use the Pointer Lock API. - static const ALLOW_POINTER_LOCK = const Sandbox._internal("allow-pointer-lock"); + static const ALLOW_POINTER_LOCK = + const Sandbox._internal("allow-pointer-lock"); ///Allows popups (such as `window.open()`, `target="_blank"`, or `showModalDialog()`). ///If this keyword is not used, the popup will silently fail to open. @@ -10810,10 +10815,12 @@ class Sandbox { ///Lets the sandboxed document open new windows without those windows inheriting the sandboxing. ///For example, this can safely sandbox an advertisement without forcing the same restrictions upon the page the ad links to. - static const ALLOW_POPUPS_TO_ESCAPE_SANDBOX = const Sandbox._internal("allow-popups-to-escape-sandbox"); + static const ALLOW_POPUPS_TO_ESCAPE_SANDBOX = + const Sandbox._internal("allow-popups-to-escape-sandbox"); ///Lets the resource start a presentation session. - static const ALLOW_PRESENTATION = const Sandbox._internal("allow-presentation"); + static const ALLOW_PRESENTATION = + const Sandbox._internal("allow-presentation"); ///If this token is not used, the resource is treated as being from a special origin that always fails the ///same-origin policy (potentially preventing access to data storage/cookies and some JavaScript APIs). @@ -10823,13 +10830,15 @@ class Sandbox { static const ALLOW_SCRIPTS = const Sandbox._internal("allow-scripts"); ///Lets the resource navigate the top-level browsing context (the one named `_top`). - static const ALLOW_TOP_NAVIGATION = const Sandbox._internal("allow-top-navigation"); + static const ALLOW_TOP_NAVIGATION = + const Sandbox._internal("allow-top-navigation"); ///Lets the resource navigate the top-level browsing context, but only if initiated by a user gesture. - static const ALLOW_TOP_NAVIGATION_BY_USER_ACTIVATION = const Sandbox._internal("allow-top-navigation-by-user-activation"); + static const ALLOW_TOP_NAVIGATION_BY_USER_ACTIVATION = + const Sandbox._internal("allow-top-navigation-by-user-activation"); bool operator ==(value) => value == _value; @override int get hashCode => _value.hashCode; -} \ No newline at end of file +} diff --git a/lib/src/web/headless_in_app_web_view_web_element.dart b/lib/src/web/headless_in_app_web_view_web_element.dart index 076967ac..5e9c7716 100644 --- a/lib/src/web/headless_in_app_web_view_web_element.dart +++ b/lib/src/web/headless_in_app_web_view_web_element.dart @@ -11,10 +11,12 @@ class HeadlessInAppWebViewWebElement { InAppWebViewWebElement? webView; late MethodChannel? _channel; - HeadlessInAppWebViewWebElement({required this.id, required BinaryMessenger messenger, - required this.webView}) { + HeadlessInAppWebViewWebElement( + {required this.id, + required BinaryMessenger messenger, + required this.webView}) { this._messenger = messenger; - + _channel = MethodChannel( 'com.pichillilorenzo/flutter_headless_inappwebview_${this.id}', const StandardMethodCodec(), @@ -38,7 +40,8 @@ class HeadlessInAppWebViewWebElement { default: throw PlatformException( code: 'Unimplemented', - details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', + details: + 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', ); } } @@ -54,7 +57,8 @@ class HeadlessInAppWebViewWebElement { Size getSize() { var width = webView?.iframe.getBoundingClientRect().width.toDouble() ?? 0.0; - var height = webView?.iframe.getBoundingClientRect().height.toDouble() ?? 0.0; + var height = + webView?.iframe.getBoundingClientRect().height.toDouble() ?? 0.0; return Size(width, height); } @@ -64,4 +68,4 @@ class HeadlessInAppWebViewWebElement { webView?.dispose(); webView = null; } -} \ No newline at end of file +} diff --git a/lib/src/web/headless_inappwebview_manager.dart b/lib/src/web/headless_inappwebview_manager.dart index 7a269588..dd02122d 100644 --- a/lib/src/web/headless_inappwebview_manager.dart +++ b/lib/src/web/headless_inappwebview_manager.dart @@ -20,14 +20,16 @@ class HeadlessInAppWebViewManager { const StandardMethodCodec(), _messenger, ); - HeadlessInAppWebViewManager._sharedChannel.setMethodCallHandler(handleMethod); + HeadlessInAppWebViewManager._sharedChannel + .setMethodCallHandler(handleMethod); } Future handleMethod(MethodCall call) async { switch (call.method) { case "run": String id = call.arguments["id"]; - Map params = call.arguments["params"].cast(); + Map params = + call.arguments["params"].cast(); run(id, params); break; default: @@ -39,24 +41,24 @@ class HeadlessInAppWebViewManager { void run(String id, Map params) { var webView = InAppWebViewWebElement(viewId: id, messenger: _messenger); var headlessWebView = HeadlessInAppWebViewWebElement( - id: id, - messenger: _messenger, - webView: webView - ); + id: id, messenger: _messenger, webView: webView); WebPlatformManager.webViews.putIfAbsent(id, () => webView); webView.iframe.style.display = 'none'; - Map initialSettings = params["initialSettings"].cast(); + Map initialSettings = + params["initialSettings"].cast(); if (initialSettings.isEmpty) { webView.initialSettings = InAppWebViewSettings(); } else { webView.initialSettings = InAppWebViewSettings.fromMap(initialSettings); } - webView.initialUrlRequest = URLRequest.fromMap(params["initialUrlRequest"]?.cast()); + webView.initialUrlRequest = URLRequest.fromMap( + params["initialUrlRequest"]?.cast()); webView.initialFile = params["initialFile"]; - webView.initialData = InAppWebViewInitialData.fromMap(params["initialData"]?.cast()); + webView.initialData = InAppWebViewInitialData.fromMap( + params["initialData"]?.cast()); document.body?.append(webView.iframe); webView.prepare(); headlessWebView.onWebViewCreated(); webView.makeInitialLoad(); } -} \ No newline at end of file +} 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 d0ac6bd1..d4da9cb6 100644 --- a/lib/src/web/in_app_web_view_web_element.dart +++ b/lib/src/web/in_app_web_view_web_element.dart @@ -21,7 +21,8 @@ class InAppWebViewWebElement { late js.JsObject bridgeJsObject; bool isLoading = false; - InAppWebViewWebElement({required dynamic viewId, required BinaryMessenger messenger}) { + InAppWebViewWebElement( + {required dynamic viewId, required BinaryMessenger messenger}) { this._viewId = viewId; this._messenger = messenger; iframe = IFrameElement() @@ -38,8 +39,10 @@ class InAppWebViewWebElement { this._channel?.setMethodCallHandler(handleMethodCall); - bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); - bridgeJsObject['webViews'][_viewId] = bridgeJsObject.callMethod("createFlutterInAppWebView", [_viewId, iframe.id]); + bridgeJsObject = js.JsObject.fromBrowserObject( + js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); + bridgeJsObject['webViews'][_viewId] = bridgeJsObject + .callMethod("createFlutterInAppWebView", [_viewId, iframe.id]); } /// Handles method calls over the MethodChannel of this plugin. @@ -48,7 +51,8 @@ class InAppWebViewWebElement { case "getIFrameId": return iframe.id; case "loadUrl": - URLRequest urlRequest = URLRequest.fromMap(call.arguments["urlRequest"].cast())!; + URLRequest urlRequest = URLRequest.fromMap( + call.arguments["urlRequest"].cast())!; await loadUrl(urlRequest: urlRequest); break; case "loadData": @@ -84,7 +88,8 @@ class InAppWebViewWebElement { case "getSettings": return await settings.toMap(); case "setSettings": - InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap(call.arguments["settings"].cast()); + InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap( + call.arguments["settings"].cast()); setSettings(newSettings); break; case "dispose": @@ -93,7 +98,8 @@ class InAppWebViewWebElement { default: throw PlatformException( code: 'Unimplemented', - details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', + details: + 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', ); } } @@ -108,13 +114,17 @@ class InAppWebViewWebElement { } iframe.allow = settings.iframeAllow ?? iframe.allow; - iframe.allowFullscreen = settings.iframeAllowFullscreen ?? iframe.allowFullscreen; - iframe.referrerPolicy = settings.iframeReferrerPolicy?.toValue() ?? iframe.referrerPolicy; + iframe.allowFullscreen = + settings.iframeAllowFullscreen ?? iframe.allowFullscreen; + iframe.referrerPolicy = + settings.iframeReferrerPolicy?.toValue() ?? iframe.referrerPolicy; iframe.name = settings.iframeName ?? iframe.name; iframe.csp = settings.iframeCsp ?? iframe.csp; - if (settings.iframeSandbox != null && settings.iframeSandbox != Sandbox.ALLOW_ALL) { - iframe.setAttribute("sandbox", settings.iframeSandbox!.map((e) => e.toValue()).join(" ")); + if (settings.iframeSandbox != null && + settings.iframeSandbox != Sandbox.ALLOW_ALL) { + iframe.setAttribute( + "sandbox", settings.iframeSandbox!.map((e) => e.toValue()).join(" ")); } else if (settings.iframeSandbox == Sandbox.ALLOW_ALL) { iframe.removeAttribute("sandbox"); } else if (sandbox != Sandbox.values) { @@ -143,23 +153,26 @@ class InAppWebViewWebElement { } } - Future _makeRequest(URLRequest urlRequest, {bool? withCredentials, String? responseType, String? mimeType, void onProgress(ProgressEvent e)?}) { - return HttpRequest.request( - urlRequest.url?.toString() ?? 'about:blank', + Future _makeRequest(URLRequest urlRequest, + {bool? withCredentials, + String? responseType, + String? mimeType, + void onProgress(ProgressEvent e)?}) { + return HttpRequest.request(urlRequest.url?.toString() ?? 'about:blank', method: urlRequest.method, requestHeaders: urlRequest.headers, sendData: urlRequest.body, withCredentials: withCredentials, responseType: responseType, mimeType: mimeType, - onProgress: onProgress - ); + onProgress: onProgress); } String _convertHttpResponseToData(HttpRequest httpRequest) { final String contentType = httpRequest.getResponseHeader('content-type') ?? 'text/html'; - return 'data:$contentType,' + Uri.encodeFull(httpRequest.responseText ?? ''); + return 'data:$contentType,' + + Uri.encodeFull(httpRequest.responseText ?? ''); } Future loadUrl({required URLRequest urlRequest}) async { @@ -171,7 +184,8 @@ class InAppWebViewWebElement { } } - Future loadData({required String data, String mimeType = "text/html"}) async { + Future loadData( + {required String data, String mimeType = "text/html"}) async { iframe.src = 'data:$mimeType,' + Uri.encodeFull(data); } @@ -247,7 +261,8 @@ class InAppWebViewWebElement { if (settings.iframeSandbox != newSettings.iframeSandbox) { var sandbox = newSettings.iframeSandbox; if (sandbox != null && sandbox != Sandbox.ALLOW_ALL) { - iframe.setAttribute("sandbox", sandbox.map((e) => e.toValue()).join(" ")); + iframe.setAttribute( + "sandbox", sandbox.map((e) => e.toValue()).join(" ")); } else if (sandbox == Sandbox.ALLOW_ALL) { iframe.removeAttribute("sandbox"); } @@ -263,33 +278,24 @@ class InAppWebViewWebElement { void onLoadStart(String url) async { isLoading = true; - var obj = { - "url": url - }; + var obj = {"url": url}; await _channel?.invokeMethod("onLoadStart", obj); } void onLoadStop(String url) async { isLoading = false; - var obj = { - "url": url - }; + var obj = {"url": url}; await _channel?.invokeMethod("onLoadStop", obj); } void onUpdateVisitedHistory(String url) async { - var obj = { - "url": url - }; + var obj = {"url": url}; await _channel?.invokeMethod("onUpdateVisitedHistory", obj); } void onScrollChanged(int x, int y) async { - var obj = { - "x": x, - "y": y - }; + var obj = {"x": x, "y": y}; await _channel?.invokeMethod("onScrollChanged", obj); } @@ -310,14 +316,12 @@ class InAppWebViewWebElement { default: messageLevel = 1; } - var obj = { - "messageLevel": messageLevel, - "message": message - }; + var obj = {"messageLevel": messageLevel, "message": message}; await _channel?.invokeMethod("onConsoleMessage", obj); } - Future onCreateWindow(int windowId, String url, String? target, String? windowFeatures) async { + Future onCreateWindow( + int windowId, String url, String? target, String? windowFeatures) async { Map windowFeaturesMap = {}; List features = windowFeatures?.split(",") ?? []; for (var feature in features) { @@ -336,10 +340,7 @@ class InAppWebViewWebElement { var obj = { "windowId": windowId, "isForMainFrame": true, - "request": { - "url": url, - "method": "GET" - }, + "request": {"url": url, "method": "GET"}, "windowFeatures": windowFeaturesMap }; return await _channel?.invokeMethod("onCreateWindow", obj); @@ -354,9 +355,7 @@ class InAppWebViewWebElement { } void onPrint(String? url) async { - var obj = { - "url": url - }; + var obj = {"url": url}; await _channel?.invokeMethod("onPrint", obj); } @@ -370,18 +369,13 @@ class InAppWebViewWebElement { } void onTitleChanged(String? title) async { - var obj = { - "title": title - }; + var obj = {"title": title}; await _channel?.invokeMethod("onTitleChanged", obj); } void onZoomScaleChanged(double oldScale, double newScale) async { - var obj = { - "oldScale": oldScale, - "newScale": newScale - }; + var obj = {"oldScale": oldScale, "newScale": newScale}; await _channel?.invokeMethod("onZoomScaleChanged", obj); } @@ -393,10 +387,11 @@ class InAppWebViewWebElement { if (WebPlatformManager.webViews.containsKey(_viewId)) { WebPlatformManager.webViews.remove(_viewId); } - bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); + bridgeJsObject = js.JsObject.fromBrowserObject( + js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); var webViews = bridgeJsObject['webViews'] as js.JsObject; if (webViews.hasProperty(_viewId)) { webViews.deleteProperty(_viewId); } } -} \ No newline at end of file +} diff --git a/lib/src/web/main.dart b/lib/src/web/main.dart index 739ef7d9..d7f7922d 100644 --- a/lib/src/web/main.dart +++ b/lib/src/web/main.dart @@ -1 +1 @@ -export 'web_platform.dart'; \ No newline at end of file +export 'web_platform.dart'; diff --git a/lib/src/web/platform_util.dart b/lib/src/web/platform_util.dart index 5028d605..bc16ed62 100644 --- a/lib/src/web/platform_util.dart +++ b/lib/src/web/platform_util.dart @@ -11,7 +11,7 @@ class PlatformUtil { PlatformUtil({required BinaryMessenger messenger}) { this._messenger = messenger; - + _channel = MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_platformutil', const StandardMethodCodec(), @@ -29,13 +29,15 @@ class PlatformUtil { default: throw PlatformException( code: 'Unimplemented', - details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', + details: + 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'', ); } } String getWebCookieExpirationDate(int timestamp) { - var bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); + var bridgeJsObject = js.JsObject.fromBrowserObject( + js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]); return bridgeJsObject.callMethod("getCookieExpirationDate", [timestamp]); } @@ -43,4 +45,4 @@ class PlatformUtil { _channel?.setMethodCallHandler(null); _channel = null; } -} \ No newline at end of file +} diff --git a/lib/src/web/shims/dart_ui.dart b/lib/src/web/shims/dart_ui.dart index 51b0d9c4..4361b399 100644 --- a/lib/src/web/shims/dart_ui.dart +++ b/lib/src/web/shims/dart_ui.dart @@ -1 +1 @@ -export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart'; \ No newline at end of file +export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart'; diff --git a/lib/src/web/shims/dart_ui_fake.dart b/lib/src/web/shims/dart_ui_fake.dart index 46a4ac82..2e5834ce 100644 --- a/lib/src/web/shims/dart_ui_fake.dart +++ b/lib/src/web/shims/dart_ui_fake.dart @@ -26,4 +26,4 @@ class webOnlyAssetManager { } /// Signature of callbacks that have no arguments and return no data. -typedef VoidCallback = void Function(); \ No newline at end of file +typedef VoidCallback = void Function(); diff --git a/lib/src/web/shims/dart_ui_real.dart b/lib/src/web/shims/dart_ui_real.dart index b0e3b648..69c06ee2 100644 --- a/lib/src/web/shims/dart_ui_real.dart +++ b/lib/src/web/shims/dart_ui_real.dart @@ -1 +1 @@ -export 'dart:ui'; \ No newline at end of file +export 'dart:ui'; diff --git a/lib/src/web/web_platform.dart b/lib/src/web/web_platform.dart index a66c01a1..0a7bf8b0 100644 --- a/lib/src/web/web_platform.dart +++ b/lib/src/web/web_platform.dart @@ -12,16 +12,15 @@ import 'package:js/js.dart'; /// /// This is used as the default implementation for [WebView] on web. class FlutterInAppWebViewWebPlatform { - /// Constructs a new instance of [FlutterInAppWebViewWebPlatform]. FlutterInAppWebViewWebPlatform(Registrar registrar) { ui.platformViewRegistry.registerViewFactory( - 'com.pichillilorenzo/flutter_inappwebview', - (int viewId) { - var webView = InAppWebViewWebElement(viewId: viewId, messenger: registrar); - WebPlatformManager.webViews.putIfAbsent(viewId, () => webView); - return webView.iframe; - }); + 'com.pichillilorenzo/flutter_inappwebview', (int viewId) { + var webView = + InAppWebViewWebElement(viewId: viewId, messenger: registrar); + WebPlatformManager.webViews.putIfAbsent(viewId, () => webView); + return webView.iframe; + }); } static void registerWith(Registrar registrar) { @@ -34,15 +33,19 @@ class FlutterInAppWebViewWebPlatform { /// Allows assigning a function to be callable from `window.flutter_inappwebview.nativeCommunication()` @JS('flutter_inappwebview.nativeCommunication') -external set _nativeCommunication(Future Function(String method, dynamic viewId, [List? args]) f); +external set _nativeCommunication( + Future Function(String method, dynamic viewId, [List? args]) f); /// Allows calling the assigned function from Dart as well. @JS() -external Future nativeCommunication(String method, dynamic viewId, [List? args]); +external Future nativeCommunication(String method, dynamic viewId, + [List? args]); -Future _dartNativeCommunication(String method, dynamic viewId, [List? args]) async { +Future _dartNativeCommunication(String method, dynamic viewId, + [List? args]) async { if (WebPlatformManager.webViews.containsKey(viewId)) { - var webViewHtmlElement = WebPlatformManager.webViews[viewId] as InAppWebViewWebElement; + var webViewHtmlElement = + WebPlatformManager.webViews[viewId] as InAppWebViewWebElement; switch (method) { case 'onLoadStart': var url = args![0] as String; @@ -71,7 +74,8 @@ Future _dartNativeCommunication(String method, dynamic viewId, [List? a var url = args[1] as String? ?? 'about:blank'; var target = args[2] as String?; var windowFeatures = args[3] as String?; - return await webViewHtmlElement.onCreateWindow(windowId, url, target, windowFeatures); + return await webViewHtmlElement.onCreateWindow( + windowId, url, target, windowFeatures); case 'onWindowFocus': webViewHtmlElement.onWindowFocus(); break; @@ -79,7 +83,7 @@ Future _dartNativeCommunication(String method, dynamic viewId, [List? a webViewHtmlElement.onWindowBlur(); break; case 'onPrint': - var url = args![0] as String?; + var url = args![0] as String?; webViewHtmlElement.onPrint(url); break; case 'onEnterFullscreen': @@ -99,4 +103,4 @@ Future _dartNativeCommunication(String method, dynamic viewId, [List? a break; } } -} \ No newline at end of file +} diff --git a/lib/src/web/web_platform_manager.dart b/lib/src/web/web_platform_manager.dart index 74a73c24..5f08e528 100644 --- a/lib/src/web/web_platform_manager.dart +++ b/lib/src/web/web_platform_manager.dart @@ -1,4 +1,4 @@ abstract class WebPlatformManager { static final String BRIDGE_JS_OBJECT_NAME = "flutter_inappwebview"; static final Map webViews = {}; -} \ No newline at end of file +}