diff --git a/CHANGELOG.md b/CHANGELOG.md index 79e753bd..457fbd66 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ ## 6.0.0 -- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState` WebView controller methods - Deprecated old classes/properties/methods to make them eventually compatible with other operating systems and WebView engines. +- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState` WebView controller methods +- Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS` WebView settings +- Updated `getMetaThemeColor` on iOS 15.0+ ## 5.4.0+2 diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 4e0ca0ce..0f51ad99 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -25,7 +25,7 @@ class _InAppWebViewExampleScreenState extends State { useShouldOverrideUrlLoading: true, mediaPlaybackRequiresUserGesture: false, useHybridComposition: true, - allowsInlineMediaPlayback: true, + allowsInlineMediaPlayback: true ); late PullToRefreshController pullToRefreshController; @@ -118,7 +118,7 @@ class _InAppWebViewExampleScreenState extends State { key: webViewKey, // contextMenu: contextMenu, initialUrlRequest: - URLRequest(url: Uri.parse("https://www.youtube.com/watch?v=7_v6oMtz7tA")), + URLRequest(url: Uri.parse("http://github.com/flutter/")), // initialFile: "assets/index.html", initialUserScripts: UnmodifiableListView([]), initialSettings: settings, @@ -126,11 +126,12 @@ class _InAppWebViewExampleScreenState extends State { onWebViewCreated: (controller) { webViewController = controller; }, - onLoadStart: (controller, url) { + onLoadStart: (controller, url) async { setState(() { this.url = url.toString(); urlController.text = this.url; }); + print((await controller.getSettings())?.upgradeKnownHostsToHTTPS); }, onPermissionRequest: (controller, origin, resources) async { return PermissionRequestResponse( @@ -167,6 +168,7 @@ class _InAppWebViewExampleScreenState extends State { this.url = url.toString(); urlController.text = this.url; }); + print((await controller.getSettings())?.upgradeKnownHostsToHTTPS); }, onLoadError: (controller, url, code, message) { pullToRefreshController.endRefreshing(); diff --git a/ios/Classes/InAppWebView/InAppWebView.swift b/ios/Classes/InAppWebView/InAppWebView.swift index 78a2dc4b..d0cec70e 100755 --- a/ios/Classes/InAppWebView/InAppWebView.swift +++ b/ios/Classes/InAppWebView/InAppWebView.swift @@ -385,6 +385,12 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi pageZoom = CGFloat(settings.pageZoom) } + if #available(iOS 15.0, *) { + if let underPageBackgroundColor = settings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty { + self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor) + } + } + // debugging is always enabled for iOS, // there isn't any option to set about it such as on Android. @@ -421,6 +427,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi if #available(iOS 14.0, *) { configuration.defaultWebpagePreferences.allowsContentJavaScript = settings.javaScriptEnabled } + + if #available(iOS 14.5, *) { + configuration.preferences.isTextInteractionEnabled = settings.isTextInteractionEnabled + } + + if #available(iOS 15.0, *) { + configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled + } } } @@ -543,6 +557,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi if #available(iOS 14.0, *) { configuration.limitsNavigationsToAppBoundDomains = settings.limitsNavigationsToAppBoundDomains } + + if #available(iOS 14.5, *) { + configuration.upgradeKnownHostsToHTTPS = settings.upgradeKnownHostsToHTTPS + } } return configuration @@ -1098,6 +1116,26 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi } } + if #available(iOS 14.5, *) { + if newSettingsMap["upgradeKnownHostsToHTTPS"] != nil && settings?.upgradeKnownHostsToHTTPS != newSettings.upgradeKnownHostsToHTTPS { + configuration.upgradeKnownHostsToHTTPS = newSettings.upgradeKnownHostsToHTTPS + } + if newSettingsMap["isTextInteractionEnabled"] != nil && settings?.isTextInteractionEnabled != newSettings.isTextInteractionEnabled { + configuration.preferences.isTextInteractionEnabled = newSettings.isTextInteractionEnabled + } + } + + if #available(iOS 15.0, *) { + if newSettingsMap["underPageBackgroundColor"] != nil, settings?.underPageBackgroundColor != newSettings.underPageBackgroundColor, + let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty { + self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor) + } + if newSettingsMap["isSiteSpecificQuirksModeEnabled"] != nil && + settings?.isSiteSpecificQuirksModeEnabled != newSettings.isSiteSpecificQuirksModeEnabled { + configuration.preferences.isSiteSpecificQuirksModeEnabled = newSettings.isSiteSpecificQuirksModeEnabled + } + } + scrollView.isScrollEnabled = !(newSettings.disableVerticalScroll && newSettings.disableHorizontalScroll) self.settings = newSettings diff --git a/ios/Classes/InAppWebView/InAppWebViewSettings.swift b/ios/Classes/InAppWebView/InAppWebViewSettings.swift index 0b56a1ce..d567f984 100755 --- a/ios/Classes/InAppWebView/InAppWebViewSettings.swift +++ b/ios/Classes/InAppWebView/InAppWebViewSettings.swift @@ -70,6 +70,10 @@ public class InAppWebViewSettings: IWebViewSettings { var allowingReadAccessTo: String? = nil var disableLongPressContextMenuOnLinks = false var disableInputAccessoryView = false + var underPageBackgroundColor: String? + var isTextInteractionEnabled = true + var isSiteSpecificQuirksModeEnabled = true + var upgradeKnownHostsToHTTPS = true override init(){ super.init() @@ -133,6 +137,14 @@ public class InAppWebViewSettings: IWebViewSettings { realSettings["limitsNavigationsToAppBoundDomains"] = configuration.limitsNavigationsToAppBoundDomains realSettings["javaScriptEnabled"] = configuration.defaultWebpagePreferences.allowsContentJavaScript } + if #available(iOS 14.5, *) { + realSettings["isTextInteractionEnabled"] = configuration.preferences.isTextInteractionEnabled + realSettings["upgradeKnownHostsToHTTPS"] = configuration.upgradeKnownHostsToHTTPS + } + if #available(iOS 15.0, *) { + realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString + realSettings["isSiteSpecificQuirksModeEnabled"] = configuration.preferences.isSiteSpecificQuirksModeEnabled + } } return realSettings } diff --git a/ios/Classes/InAppWebViewMethodHandler.swift b/ios/Classes/InAppWebViewMethodHandler.swift index 6650e8f9..2a8baeb8 100644 --- a/ios/Classes/InAppWebViewMethodHandler.swift +++ b/ios/Classes/InAppWebViewMethodHandler.swift @@ -567,7 +567,7 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate { } break case "closeAllMediaPresentations": - if let webView = self.webView, #available(iOS 14.5, *) { + if let webView = self.webView, #available(iOS 14.5, *) { // closeAllMediaPresentations with completionHandler v15.0 makes the app crash // with error EXC_BAD_ACCESS, so use closeAllMediaPresentations v14.5 webView.closeAllMediaPresentations() @@ -585,6 +585,13 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate { result(nil) } break + case "getMetaThemeColor": + if let webView = webView, #available(iOS 15.0, *) { + result(webView.themeColor?.hexString) + } else { + result(nil) + } + break default: result(FlutterMethodNotImplemented) break diff --git a/lib/src/ios/main.dart b/lib/src/apple/main.dart similarity index 100% rename from lib/src/ios/main.dart rename to lib/src/apple/main.dart diff --git a/lib/src/chrome_safari_browser/ios/main.dart b/lib/src/chrome_safari_browser/apple/main.dart similarity index 100% rename from lib/src/chrome_safari_browser/ios/main.dart rename to lib/src/chrome_safari_browser/apple/main.dart diff --git a/lib/src/chrome_safari_browser/ios/safari_options.dart b/lib/src/chrome_safari_browser/apple/safari_options.dart similarity index 98% rename from lib/src/chrome_safari_browser/ios/safari_options.dart rename to lib/src/chrome_safari_browser/apple/safari_options.dart index 8385fab4..717984cc 100755 --- a/lib/src/chrome_safari_browser/ios/safari_options.dart +++ b/lib/src/chrome_safari_browser/apple/safari_options.dart @@ -6,7 +6,7 @@ import '../../types.dart'; import '../chrome_safari_browser_settings.dart'; import '../chrome_safari_browser.dart'; -import '../../in_app_webview/ios/in_app_webview_options.dart'; +import '../../in_app_webview/apple/in_app_webview_options.dart'; ///This class represents all the iOS-only [ChromeSafariBrowser] options available. ///Use [ChromeSafariBrowserSettings] instead. 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 9ccc8cbb..a9ccc7ff 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser_settings.dart @@ -5,7 +5,7 @@ import 'package:flutter/foundation.dart'; import '../util.dart'; import 'android/chrome_custom_tabs_options.dart'; -import 'ios/safari_options.dart'; +import 'apple/safari_options.dart'; import '../types.dart'; class ChromeSafariBrowserOptions { diff --git a/lib/src/chrome_safari_browser/main.dart b/lib/src/chrome_safari_browser/main.dart index 0316d2e9..c11753f1 100644 --- a/lib/src/chrome_safari_browser/main.dart +++ b/lib/src/chrome_safari_browser/main.dart @@ -1,4 +1,4 @@ export 'chrome_safari_browser.dart'; export 'chrome_safari_browser_settings.dart'; export 'android/main.dart'; -export 'ios/main.dart'; +export 'apple/main.dart'; diff --git a/lib/src/in_app_browser/ios/in_app_browser_options.dart b/lib/src/in_app_browser/apple/in_app_browser_options.dart similarity index 98% rename from lib/src/in_app_browser/ios/in_app_browser_options.dart rename to lib/src/in_app_browser/apple/in_app_browser_options.dart index 3120b101..bb97f346 100755 --- a/lib/src/in_app_browser/ios/in_app_browser_options.dart +++ b/lib/src/in_app_browser/apple/in_app_browser_options.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import '../../in_app_webview/ios/in_app_webview_options.dart'; +import '../../in_app_webview/apple/in_app_webview_options.dart'; import '../in_app_browser_settings.dart'; import '../in_app_browser.dart'; diff --git a/lib/src/in_app_browser/ios/main.dart b/lib/src/in_app_browser/apple/main.dart similarity index 100% rename from lib/src/in_app_browser/ios/main.dart rename to lib/src/in_app_browser/apple/main.dart 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 3009d192..023829bd 100755 --- a/lib/src/in_app_browser/in_app_browser_settings.dart +++ b/lib/src/in_app_browser/in_app_browser_settings.dart @@ -11,8 +11,8 @@ import '../in_app_webview/in_app_webview_settings.dart'; import 'android/in_app_browser_options.dart'; import '../in_app_webview/android/in_app_webview_options.dart'; -import 'ios/in_app_browser_options.dart'; -import '../in_app_webview/ios/in_app_webview_options.dart'; +import 'apple/in_app_browser_options.dart'; +import '../in_app_webview/apple/in_app_webview_options.dart'; class BrowserOptions { Map toMap() { diff --git a/lib/src/in_app_browser/main.dart b/lib/src/in_app_browser/main.dart index b1c350a0..069ebf66 100644 --- a/lib/src/in_app_browser/main.dart +++ b/lib/src/in_app_browser/main.dart @@ -1,4 +1,4 @@ export 'in_app_browser.dart'; export 'in_app_browser_settings.dart'; export 'android/main.dart'; -export 'ios/main.dart'; +export 'apple/main.dart'; diff --git a/lib/src/in_app_webview/ios/in_app_webview_controller.dart b/lib/src/in_app_webview/apple/in_app_webview_controller.dart similarity index 100% rename from lib/src/in_app_webview/ios/in_app_webview_controller.dart rename to lib/src/in_app_webview/apple/in_app_webview_controller.dart diff --git a/lib/src/in_app_webview/ios/in_app_webview_options.dart b/lib/src/in_app_webview/apple/in_app_webview_options.dart similarity index 100% rename from lib/src/in_app_webview/ios/in_app_webview_options.dart rename to lib/src/in_app_webview/apple/in_app_webview_options.dart diff --git a/lib/src/in_app_webview/ios/main.dart b/lib/src/in_app_webview/apple/main.dart similarity index 100% rename from lib/src/in_app_webview/ios/main.dart rename to lib/src/in_app_webview/apple/main.dart 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 446cd5b4..daebf88c 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -10,7 +10,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'android/in_app_webview_controller.dart'; -import 'ios/in_app_webview_controller.dart'; +import 'apple/in_app_webview_controller.dart'; import '../context_menu.dart'; import '../types.dart'; @@ -2295,12 +2295,27 @@ class InAppWebViewController ///Returns an instance of [Color] representing the `content` value of the ///`` tag of the current WebView, if available, otherwise `null`. /// - ///**NOTE**: It is implemented using JavaScript. + ///**NOTE**: on Android and iOS < 15.0, it is implemented using JavaScript. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - ///- iOS + ///- iOS ([Official API - WKWebView.themeColor](https://developer.apple.com/documentation/webkit/wkwebview/3794258-themecolor)) Future getMetaThemeColor() async { + Color? themeColor; + + try { + Map args = {}; + themeColor = UtilColor.fromStringRepresentation(await _channel.invokeMethod('getMetaThemeColor', args)); + } catch (e) { + // not implemented + } + + if (themeColor != null) { + return themeColor; + } + + // try using javascript + var metaTags = await getMetaTags(); MetaTag? metaTagThemeColor; @@ -2317,9 +2332,11 @@ class InAppWebViewController var colorValue = metaTagThemeColor.content; - return colorValue != null + themeColor = colorValue != null ? UtilColor.fromStringRepresentation(colorValue) : null; + + return themeColor; } ///Returns the scrolled left position of the current WebView. 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 75ca27fb..d5becaca 100755 --- a/lib/src/in_app_webview/in_app_webview_settings.dart +++ b/lib/src/in_app_webview/in_app_webview_settings.dart @@ -4,7 +4,7 @@ import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'android/in_app_webview_options.dart'; -import 'ios/in_app_webview_options.dart'; +import 'apple/in_app_webview_options.dart'; import '../content_blocker.dart'; import '../types.dart'; import '../util.dart'; @@ -956,6 +956,46 @@ class InAppWebViewSettings ///- iOS bool disableInputAccessoryView; + ///The color the web view displays behind the active page, visible when the user scrolls beyond the bounds of the page. + /// + ///The web view derives the default value of this property from the content of the page, + ///using the background colors of the `` and `` elements with the background color of the web view. + ///To override the default color, set this property to a new color. + /// + ///**NOTE**: available on iOS 15.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? underPageBackgroundColor; + + ///A Boolean value indicating whether text interaction is enabled or not. + ///The default value is `true`. + /// + ///**NOTE**: available on iOS 14.5+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool isTextInteractionEnabled; + + ///A Boolean value indicating whether WebKit will apply built-in workarounds (quirks) + ///to improve compatibility with certain known websites. You can disable site-specific quirks + ///to help test your website without these workarounds. The default value is `true`. + /// + ///**NOTE**: available on iOS 15.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool isSiteSpecificQuirksModeEnabled; + + ///A Boolean value indicating whether HTTP requests to servers known to support HTTPS should be automatically upgraded to HTTPS requests. + ///The default value is `true`. + /// + ///**NOTE**: available on iOS 14.5+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool upgradeKnownHostsToHTTPS; + InAppWebViewSettings( {this.useShouldOverrideUrlLoading = false, this.useOnLoadResource = false, @@ -1071,7 +1111,11 @@ class InAppWebViewSettings this.applePayAPIEnabled = false, this.allowingReadAccessTo, this.disableLongPressContextMenuOnLinks = false, - this.disableInputAccessoryView = false}) { + this.disableInputAccessoryView = false, + this.underPageBackgroundColor, + this.isTextInteractionEnabled = true, + this.isSiteSpecificQuirksModeEnabled = true, + this.upgradeKnownHostsToHTTPS = true}) { if (this.minimumFontSize == null) this.minimumFontSize = defaultTargetPlatform == TargetPlatform.android ? 8 : 0; @@ -1210,6 +1254,10 @@ class InAppWebViewSettings "allowingReadAccessTo": allowingReadAccessTo.toString(), "disableLongPressContextMenuOnLinks": disableLongPressContextMenuOnLinks, "disableInputAccessoryView": disableInputAccessoryView, + "underPageBackgroundColor": underPageBackgroundColor?.toHex(), + "isTextInteractionEnabled": isTextInteractionEnabled, + "isSiteSpecificQuirksModeEnabled": isSiteSpecificQuirksModeEnabled, + "upgradeKnownHostsToHTTPS": upgradeKnownHostsToHTTPS }; } @@ -1382,6 +1430,10 @@ class InAppWebViewSettings settings.disableLongPressContextMenuOnLinks = map["disableLongPressContextMenuOnLinks"]; settings.disableInputAccessoryView = map["disableInputAccessoryView"]; + settings.underPageBackgroundColor = UtilColor.fromHex(map["underPageBackgroundColor"]); + settings.isTextInteractionEnabled = map["isTextInteractionEnabled"]; + settings.isSiteSpecificQuirksModeEnabled = map["isSiteSpecificQuirksModeEnabled"]; + settings.upgradeKnownHostsToHTTPS = map["upgradeKnownHostsToHTTPS"]; } return settings; } diff --git a/lib/src/in_app_webview/main.dart b/lib/src/in_app_webview/main.dart index ce27e378..105ca7ef 100644 --- a/lib/src/in_app_webview/main.dart +++ b/lib/src/in_app_webview/main.dart @@ -4,4 +4,4 @@ export 'in_app_webview_controller.dart'; export 'in_app_webview_settings.dart'; export 'headless_in_app_webview.dart'; export 'android/main.dart'; -export 'ios/main.dart'; +export 'apple/main.dart'; diff --git a/lib/src/main.dart b/lib/src/main.dart index 09470a5f..69027c99 100644 --- a/lib/src/main.dart +++ b/lib/src/main.dart @@ -2,7 +2,7 @@ export 'in_app_webview/main.dart'; export 'in_app_browser/main.dart'; export 'chrome_safari_browser/main.dart'; export 'android/main.dart'; -export 'ios/main.dart'; +export 'apple/main.dart'; export 'x509_certificate/main.dart'; export 'web_storage/main.dart'; export 'types.dart';