-

Inline WebView

flutter logo flutter logo diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index fb55de39..4882a9e9 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -2,11 +2,10 @@ # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" -export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build/ios" export "OTHER_LDFLAGS=$(inherited) -framework Flutter" export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" -export "TRACK_WIDGET_CREATION=true" diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 61893af3..9ec9e6b5 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -26,25 +26,25 @@ class _InAppWebViewExampleScreenState extends State { contextMenu = ContextMenu( menuItems: [ ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async { - print("Menu item Special clicked!"); + //print("Menu item Special clicked!"); print(await webView.getSelectedText()); await webView.clearFocus(); }) ], options: ContextMenuOptions( - hideDefaultSystemContextMenuItems: true + hideDefaultSystemContextMenuItems: false ), onCreateContextMenu: (hitTestResult) async { - print("onCreateContextMenu"); + //print("onCreateContextMenu"); print(hitTestResult.extra); print(await webView.getSelectedText()); }, onHideContextMenu: () { - print("onHideContextMenu"); + //print("onHideContextMenu"); }, onContextMenuActionItemClicked: (contextMenuItemClicked) async { var id = (Platform.isAndroid) ? contextMenuItemClicked.androidId : contextMenuItemClicked.iosId; - print("onContextMenuActionItemClicked: " + id.toString() + " " + contextMenuItemClicked.title); + // print("onContextMenuActionItemClicked: " + id.toString() + " " + contextMenuItemClicked.title); } ); } @@ -80,8 +80,8 @@ class _InAppWebViewExampleScreenState extends State { BoxDecoration(border: Border.all(color: Colors.blueAccent)), child: InAppWebView( contextMenu: contextMenu, - initialUrl: "https://github.com/flutter", - // initialFile: "assets/index.html", + // initialUrl: "https://github.com/flutter", + initialFile: "assets/index.html", initialHeaders: {}, initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( diff --git a/flutter_inappwebview.iml b/flutter_inappwebview.iml index e6d1884c..c8905c93 100755 --- a/flutter_inappwebview.iml +++ b/flutter_inappwebview.iml @@ -27,6 +27,7 @@ + diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift index addda0d1..ca10c3bb 100755 --- a/ios/Classes/InAppWebView.swift +++ b/ios/Classes/InAppWebView.swift @@ -320,7 +320,7 @@ let interceptAjaxRequestsJS = """ }; function handleEvent(e) { var self = this; - if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) { + if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) { var headers = this.getAllResponseHeaders(); var responseHeaders = {}; if (headers != null) { @@ -371,12 +371,12 @@ let interceptAjaxRequestsJS = """ }; ajax.prototype.send = function(data) { var self = this; - if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) { + if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) { if (!this._flutter_inappwebview_already_onreadystatechange_wrapped) { this._flutter_inappwebview_already_onreadystatechange_wrapped = true; var onreadystatechange = this.onreadystatechange; this.onreadystatechange = function() { - if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) { + if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) { var headers = this.getAllResponseHeaders(); var responseHeaders = {}; if (headers != null) { @@ -1029,143 +1029,130 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi configuration.userContentController = WKUserContentController() configuration.preferences = WKPreferences() - if (options?.transparentBackground)! { - isOpaque = false - backgroundColor = UIColor.clear - scrollView.backgroundColor = UIColor.clear - } - - // prevent webView from bouncing - if (options?.disallowOverScroll)! { - if responds(to: #selector(getter: scrollView)) { - scrollView.bounces = false + if let options = options { + if options.transparentBackground { + isOpaque = false + backgroundColor = UIColor.clear + scrollView.backgroundColor = UIColor.clear } - else { - for subview: UIView in subviews { - if subview is UIScrollView { - (subview as! UIScrollView).bounces = false + + // prevent webView from bouncing + if options.disallowOverScroll { + if responds(to: #selector(getter: scrollView)) { + scrollView.bounces = false + } + else { + for subview: UIView in subviews { + if subview is UIScrollView { + (subview as! UIScrollView).bounces = false + } } } } - } - - let originalViewPortMetaTagContentJSScript = WKUserScript(source: originalViewPortMetaTagContentJS, injectionTime: .atDocumentEnd, forMainFrameOnly: true) - configuration.userContentController.addUserScript(originalViewPortMetaTagContentJSScript) - - if !(options?.supportZoom)! { - let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta);" - let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) - configuration.userContentController.addUserScript(userScript) - } else if (options?.enableViewportScale)! { - let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);" - let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) - configuration.userContentController.addUserScript(userScript) - } - - let promisePolyfillJSScript = WKUserScript(source: promisePolyfillJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(promisePolyfillJSScript) - - let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(javaScriptBridgeJSScript) - configuration.userContentController.add(self, name: "callHandler") - - let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(consoleLogJSScript) - configuration.userContentController.add(self, name: "consoleLog") - configuration.userContentController.add(self, name: "consoleDebug") - configuration.userContentController.add(self, name: "consoleError") - configuration.userContentController.add(self, name: "consoleInfo") - configuration.userContentController.add(self, name: "consoleWarn") - - let findElementsAtPointJSScript = WKUserScript(source: findElementsAtPointJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(findElementsAtPointJSScript) - - let printJSScript = WKUserScript(source: printJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(printJSScript) - - let lastTouchedAnchorOrImageJSScript = WKUserScript(source: lastTouchedAnchorOrImageJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(lastTouchedAnchorOrImageJSScript) - - if (options?.useOnLoadResource)! { - let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(resourceObserverJSScript) - } - - let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(findTextHighlightJSScript) - configuration.userContentController.add(self, name: "onFindResultReceived") - - if (options?.useShouldInterceptAjaxRequest)! { - let interceptAjaxRequestsJSScript = WKUserScript(source: interceptAjaxRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(interceptAjaxRequestsJSScript) - } - - if (options?.useShouldInterceptFetchRequest)! { - let interceptFetchRequestsJSScript = WKUserScript(source: interceptFetchRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) - configuration.userContentController.addUserScript(interceptFetchRequestsJSScript) - } - - if #available(iOS 11.0, *) { - accessibilityIgnoresInvertColors = (options?.accessibilityIgnoresInvertColors)! - scrollView.contentInsetAdjustmentBehavior = - UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: (options?.contentInsetAdjustmentBehavior)!)! - } - - configuration.suppressesIncrementalRendering = (options?.suppressesIncrementalRendering)! - allowsBackForwardNavigationGestures = (options?.allowsBackForwardNavigationGestures)! - if #available(iOS 9.0, *) { - allowsLinkPreview = (options?.allowsLinkPreview)! - configuration.allowsAirPlayForMediaPlayback = (options?.allowsAirPlayForMediaPlayback)! - configuration.allowsPictureInPictureMediaPlayback = (options?.allowsPictureInPictureMediaPlayback)! - if (options?.applicationNameForUserAgent != nil && (options?.applicationNameForUserAgent)! != "") { - configuration.applicationNameForUserAgent = (options?.applicationNameForUserAgent)! - } - if (options?.userAgent != nil && (options?.userAgent)! != "") { - customUserAgent = (options?.userAgent)! - } - } - - configuration.preferences.javaScriptCanOpenWindowsAutomatically = (options?.javaScriptCanOpenWindowsAutomatically)! - configuration.preferences.javaScriptEnabled = (options?.javaScriptEnabled)! - configuration.preferences.minimumFontSize = CGFloat((options?.minimumFontSize)!) - configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: (options?.selectionGranularity)!)! - - if #available(iOS 10.0, *) { - configuration.ignoresViewportScaleLimits = (options?.ignoresViewportScaleLimits)! - var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0) - for type in options?.dataDetectorTypes ?? [] { - let dataDetectorType = InAppWebView.getDataDetectorType(type: type) - dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue) + let originalViewPortMetaTagContentJSScript = WKUserScript(source: originalViewPortMetaTagContentJS, injectionTime: .atDocumentEnd, forMainFrameOnly: true) + configuration.userContentController.addUserScript(originalViewPortMetaTagContentJSScript) + + if !options.supportZoom { + let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta);" + let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) + configuration.userContentController.addUserScript(userScript) + } else if options.enableViewportScale { + let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);" + let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) + configuration.userContentController.addUserScript(userScript) } - configuration.dataDetectorTypes = dataDetectorTypes - } - - if #available(iOS 13.0, *) { - configuration.preferences.isFraudulentWebsiteWarningEnabled = (options?.isFraudulentWebsiteWarningEnabled)! - if options?.preferredContentMode != nil { - configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: (options?.preferredContentMode)!)! + + let promisePolyfillJSScript = WKUserScript(source: promisePolyfillJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(promisePolyfillJSScript) + + let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(javaScriptBridgeJSScript) + configuration.userContentController.add(self, name: "callHandler") + + let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(consoleLogJSScript) + configuration.userContentController.add(self, name: "consoleLog") + configuration.userContentController.add(self, name: "consoleDebug") + configuration.userContentController.add(self, name: "consoleError") + configuration.userContentController.add(self, name: "consoleInfo") + configuration.userContentController.add(self, name: "consoleWarn") + + let findElementsAtPointJSScript = WKUserScript(source: findElementsAtPointJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(findElementsAtPointJSScript) + + let printJSScript = WKUserScript(source: printJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(printJSScript) + + let lastTouchedAnchorOrImageJSScript = WKUserScript(source: lastTouchedAnchorOrImageJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(lastTouchedAnchorOrImageJSScript) + + if options.useOnLoadResource { + let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(resourceObserverJSScript) } - scrollView.automaticallyAdjustsScrollIndicatorInsets = (options?.automaticallyAdjustsScrollIndicatorInsets)! - } - - scrollView.showsVerticalScrollIndicator = !(options?.disableVerticalScroll)! - scrollView.showsHorizontalScrollIndicator = !(options?.disableHorizontalScroll)! - scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)! - scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)! + + let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(findTextHighlightJSScript) + configuration.userContentController.add(self, name: "onFindResultReceived") + + if options.useShouldInterceptAjaxRequest { + let interceptAjaxRequestsJSScript = WKUserScript(source: interceptAjaxRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(interceptAjaxRequestsJSScript) + } + + if options.useShouldInterceptFetchRequest { + let interceptFetchRequestsJSScript = WKUserScript(source: interceptFetchRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false) + configuration.userContentController.addUserScript(interceptFetchRequestsJSScript) + } + + if #available(iOS 11.0, *) { + accessibilityIgnoresInvertColors = options.accessibilityIgnoresInvertColors + scrollView.contentInsetAdjustmentBehavior = + UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: options.contentInsetAdjustmentBehavior)! + } + + allowsBackForwardNavigationGestures = options.allowsBackForwardNavigationGestures + if #available(iOS 9.0, *) { + allowsLinkPreview = options.allowsLinkPreview + configuration.allowsAirPlayForMediaPlayback = options.allowsAirPlayForMediaPlayback + configuration.allowsPictureInPictureMediaPlayback = options.allowsPictureInPictureMediaPlayback + if !options.applicationNameForUserAgent.isEmpty { + configuration.applicationNameForUserAgent = options.applicationNameForUserAgent + } + if !options.userAgent.isEmpty { + customUserAgent = options.userAgent + } + } + + configuration.preferences.javaScriptCanOpenWindowsAutomatically = options.javaScriptCanOpenWindowsAutomatically + configuration.preferences.javaScriptEnabled = options.javaScriptEnabled + configuration.preferences.minimumFontSize = CGFloat(options.minimumFontSize) + + if #available(iOS 13.0, *) { + configuration.preferences.isFraudulentWebsiteWarningEnabled = options.isFraudulentWebsiteWarningEnabled + configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: options.preferredContentMode)! + scrollView.automaticallyAdjustsScrollIndicatorInsets = options.automaticallyAdjustsScrollIndicatorInsets + } + + scrollView.showsVerticalScrollIndicator = !options.disableVerticalScroll + scrollView.showsHorizontalScrollIndicator = !options.disableHorizontalScroll + scrollView.showsVerticalScrollIndicator = options.verticalScrollBarEnabled + scrollView.showsHorizontalScrollIndicator = options.horizontalScrollBarEnabled - scrollView.decelerationRate = InAppWebView.getDecelerationRate(type: (options?.decelerationRate)!) - scrollView.alwaysBounceVertical = (options?.alwaysBounceVertical)! - scrollView.alwaysBounceHorizontal = (options?.alwaysBounceHorizontal)! - scrollView.scrollsToTop = (options?.scrollsToTop)! - scrollView.isPagingEnabled = (options?.isPagingEnabled)! - scrollView.maximumZoomScale = CGFloat((options?.maximumZoomScale)!) - scrollView.minimumZoomScale = CGFloat((options?.minimumZoomScale)!) - - // options.debuggingEnabled is always enabled for iOS. - - if (options?.clearCache)! { - clearCache() + scrollView.decelerationRate = InAppWebView.getDecelerationRate(type: options.decelerationRate) + scrollView.alwaysBounceVertical = options.alwaysBounceVertical + scrollView.alwaysBounceHorizontal = options.alwaysBounceHorizontal + scrollView.scrollsToTop = options.scrollsToTop + scrollView.isPagingEnabled = options.isPagingEnabled + scrollView.maximumZoomScale = CGFloat(options.maximumZoomScale) + scrollView.minimumZoomScale = CGFloat(options.minimumZoomScale) + + // options.debuggingEnabled is always enabled for iOS. + + if options.clearCache { + clearCache() + } } } @@ -1261,43 +1248,51 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi configuration.processPool = WKProcessPoolManager.sharedProcessPool - if #available(iOS 10.0, *) { - configuration.mediaTypesRequiringUserActionForPlayback = ((options?.mediaPlaybackRequiresUserGesture)!) ? .all : [] - } else { - // Fallback on earlier versions - configuration.mediaPlaybackRequiresUserAction = (options?.mediaPlaybackRequiresUserGesture)! - } - - configuration.allowsInlineMediaPlayback = (options?.allowsInlineMediaPlayback)! - - if #available(iOS 11.0, *) { - if let schemes = options?.resourceCustomSchemes { - for scheme in schemes { + if let options = options { + configuration.allowsInlineMediaPlayback = options.allowsInlineMediaPlayback + configuration.suppressesIncrementalRendering = options.suppressesIncrementalRendering + configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: options.selectionGranularity)! + + if #available(iOS 9.0, *) { + if options.incognito { + configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() + } else if options.cacheEnabled { + configuration.websiteDataStore = WKWebsiteDataStore.default() + } + } + + if #available(iOS 10.0, *) { + configuration.ignoresViewportScaleLimits = options.ignoresViewportScaleLimits + + var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0) + for type in options.dataDetectorTypes { + let dataDetectorType = InAppWebView.getDataDetectorType(type: type) + dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue) + } + configuration.dataDetectorTypes = dataDetectorTypes + + configuration.mediaTypesRequiringUserActionForPlayback = options.mediaPlaybackRequiresUserGesture ? .all : [] + } else { + // Fallback on earlier versions + configuration.mediaPlaybackRequiresUserAction = options.mediaPlaybackRequiresUserGesture + } + + if #available(iOS 11.0, *) { + for scheme in options.resourceCustomSchemes { configuration.setURLSchemeHandler(CustomeSchemeHandler(), forURLScheme: scheme) } - } - } - - if #available(iOS 9.0, *) { - if ((options?.incognito)!) { - configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() - } else if ((options?.cacheEnabled)!) { - configuration.websiteDataStore = WKWebsiteDataStore.default() - } - } - - if #available(iOS 11.0, *) { - if((options?.sharedCookiesEnabled)!) { - // More info to sending cookies with WKWebView - // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303 - // Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies - // See also https://forums.developer.apple.com/thread/97194 - // check if websiteDataStore has not been initialized before - if(!(options?.incognito)! && !(options?.cacheEnabled)!) { - configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() - } - for cookie in HTTPCookieStorage.shared.cookies ?? [] { - configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil) + if options.sharedCookiesEnabled { + // More info to sending cookies with WKWebView + // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303 + // Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies + // See also https://forums.developer.apple.com/thread/97194 + // check if websiteDataStore has not been initialized before + if(!options.incognito && options.cacheEnabled) { + configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() + } + for cookie in HTTPCookieStorage.shared.cookies ?? [] { + configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil) + } } } } @@ -2804,17 +2799,21 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi public func pauseTimers() { - isPausedTimers = true - let script = "alert();"; - self.evaluateJavaScript(script, completionHandler: nil) + if !isPausedTimers { + isPausedTimers = true + let script = "alert();"; + self.evaluateJavaScript(script, completionHandler: nil) + } } public func resumeTimers() { - if let completionHandler = isPausedTimersCompletionHandler { - completionHandler() - isPausedTimersCompletionHandler = nil + if isPausedTimers { + if let completionHandler = isPausedTimersCompletionHandler { + self.isPausedTimersCompletionHandler = nil + completionHandler() + } + isPausedTimers = false } - isPausedTimers = false } public func printCurrentPage(printCompletionHandler: ((_ completed: Bool, _ error: Error?) -> Void)?) { @@ -2925,6 +2924,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi } public func dispose() { + if isPausedTimers, let completionHandler = isPausedTimersCompletionHandler { + isPausedTimersCompletionHandler = nil + completionHandler() + } stopLoading() configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog") configuration.userContentController.removeScriptMessageHandler(forName: "consoleDebug") diff --git a/lib/src/X509Certificate/asn1_distinguished_names.dart b/lib/src/X509Certificate/asn1_distinguished_names.dart index 2f8798b0..085f893d 100644 --- a/lib/src/X509Certificate/asn1_distinguished_names.dart +++ b/lib/src/X509Certificate/asn1_distinguished_names.dart @@ -4,7 +4,7 @@ class ASN1DistinguishedNames { const ASN1DistinguishedNames._internal(this._oid, this._representation); - static List values = [ + static final Set values = [ ASN1DistinguishedNames.COMMON_NAME, ASN1DistinguishedNames.DN_QUALIFIER, ASN1DistinguishedNames.SERIAL_NUMBER, @@ -17,10 +17,12 @@ class ASN1DistinguishedNames { ASN1DistinguishedNames.STATE_OR_PROVINCE_NAME, ASN1DistinguishedNames.COUNTRY_NAME, ASN1DistinguishedNames.EMAIL, - ]; + ].toSet(); static ASN1DistinguishedNames fromValue(String oid) { - return ASN1DistinguishedNames.values.firstWhere((element) => element.oid() == oid, orElse: () => null); + if (oid != null) + return ASN1DistinguishedNames.values.firstWhere((element) => element.oid() == oid, orElse: () => null); + return null; } String oid() => _oid; diff --git a/lib/src/X509Certificate/asn1_identifier.dart b/lib/src/X509Certificate/asn1_identifier.dart index f255c5aa..9bc51882 100644 --- a/lib/src/X509Certificate/asn1_identifier.dart +++ b/lib/src/X509Certificate/asn1_identifier.dart @@ -3,12 +3,12 @@ class ASN1IdentifierClass { const ASN1IdentifierClass._internal(this._value); - static List values = [ + static final Set values = [ ASN1IdentifierClass.UNIVERSAL, ASN1IdentifierClass.APPLICATION, ASN1IdentifierClass.CONTEXT_SPECIFIC, ASN1IdentifierClass.PRIVATE, - ]; + ].toSet(); static ASN1IdentifierClass fromValue(int value) { if (value != null) @@ -47,7 +47,7 @@ class ASN1IdentifierTagNumber { const ASN1IdentifierTagNumber._internal(this._value); - static List values = [ + static final Set values = [ ASN1IdentifierTagNumber.END_OF_CONTENT, ASN1IdentifierTagNumber.BOOLEAN, ASN1IdentifierTagNumber.INTEGER, @@ -77,7 +77,7 @@ class ASN1IdentifierTagNumber { ASN1IdentifierTagNumber.UNIVERSAL_STRING, ASN1IdentifierTagNumber.CHARACTER_STRING, ASN1IdentifierTagNumber.BMP_STRING, - ]; + ].toSet(); static ASN1IdentifierTagNumber fromValue(int value) { if (value != null) diff --git a/lib/src/X509Certificate/key_usage.dart b/lib/src/X509Certificate/key_usage.dart index d756db3a..7d2ae149 100644 --- a/lib/src/X509Certificate/key_usage.dart +++ b/lib/src/X509Certificate/key_usage.dart @@ -3,7 +3,7 @@ class KeyUsage { const KeyUsage._internal(this._value); - static List values = [ + static final Set values = [ KeyUsage.digitalSignature, KeyUsage.nonRepudiation, KeyUsage.keyEncipherment, @@ -13,7 +13,7 @@ class KeyUsage { KeyUsage.cRLSign, KeyUsage.encipherOnly, KeyUsage.decipherOnly, - ]; + ].toSet(); static KeyUsage fromIndex(int value) { return KeyUsage.values.firstWhere((element) => element.toValue() == value, orElse: () => null); diff --git a/lib/src/X509Certificate/oid.dart b/lib/src/X509Certificate/oid.dart index 1f4164f6..d682fe01 100644 --- a/lib/src/X509Certificate/oid.dart +++ b/lib/src/X509Certificate/oid.dart @@ -3,7 +3,7 @@ class OID { const OID._internal(this._value); - static List values = [ + static final Set values = [ OID.etsiQcsCompliance, OID.etsiQcsRetentionPeriod, OID.etsiQcsQcSSCD, @@ -100,7 +100,7 @@ class OID { OID.codeSigning, OID.emailProtection, OID.timeStamping, - ]; + ].toSet(); static OID fromValue(String value) { return OID.values.firstWhere((element) => element.toValue() == value, orElse: () => null); diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart index abe69210..f3d5a1c0 100755 --- a/lib/src/in_app_webview.dart +++ b/lib/src/in_app_webview.dart @@ -287,10 +287,18 @@ class _InAppWebViewState extends State { @override Widget build(BuildContext context) { if (defaultTargetPlatform == TargetPlatform.android) { + var gestureRecognizers = widget.gestureRecognizers; + if (gestureRecognizers == null) { + gestureRecognizers = >[ + Factory( + () => EagerGestureRecognizer(), + ), + ].toSet(); + } return AndroidView( viewType: 'com.pichillilorenzo/flutter_inappwebview', onPlatformViewCreated: _onPlatformViewCreated, - gestureRecognizers: widget.gestureRecognizers, + gestureRecognizers: gestureRecognizers, layoutDirection: TextDirection.rtl, creationParams: { 'initialUrl': '${Uri.parse(widget.initialUrl)}', diff --git a/lib/src/in_app_webview_controller.dart b/lib/src/in_app_webview_controller.dart index a0d5e76c..32ed2508 100644 --- a/lib/src/in_app_webview_controller.dart +++ b/lib/src/in_app_webview_controller.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'dart:io'; import 'dart:async'; import 'dart:collection'; @@ -13,8 +12,6 @@ import 'package:flutter/widgets.dart'; import 'X509Certificate/asn1_distinguished_names.dart'; import 'X509Certificate/x509_certificate.dart'; -import 'package:html/parser.dart' show parse; - import 'context_menu.dart'; import 'types.dart'; import 'in_app_browser.dart'; @@ -586,11 +583,6 @@ class InAppWebViewController { List args = jsonDecode(call.arguments["args"]); switch (handlerName) { - case "androidKeyboardWorkaroundFocusoutEvent": - // android Workaround to hide the Keyboard when the user click outside - // on something not focusable such as input or a textarea. - SystemChannels.textInput.invokeMethod("TextInput.hide"); - break; case "onLoadResource": Map argMap = args[0]; String initiatorType = argMap["initiatorType"]; @@ -883,7 +875,6 @@ class InAppWebViewController { if (html == null || (html != null && html.isEmpty)) { return favicons; } - var assetPathBase; if (webviewUrl.startsWith("file:///")) { @@ -891,29 +882,53 @@ class InAppWebViewController { assetPathBase = assetPathSplitted[0] + "/flutter_assets/"; } - // get all link html elements - var document = parse(html); - var links = document.getElementsByTagName('link'); - for (var link in links) { - var attributes = link.attributes; - if (attributes["rel"] == "manifest") { - manifestUrl = attributes["href"]; - if (!_isUrlAbsolute(manifestUrl)) { - if (manifestUrl.startsWith("/")) { - manifestUrl = manifestUrl.substring(1); - } - manifestUrl = ((assetPathBase == null) - ? url.scheme + "://" + url.host + "/" - : assetPathBase) + - manifestUrl; + InAppWebViewGroupOptions options = await getOptions(); + if (options != null && options.crossPlatform.javaScriptEnabled == true) { + List> links = (await evaluateJavascript( + source: """ +(function() { + var linkNodes = document.head.getElementsByTagName("link"); + var links = []; + for (var i = 0; i < linkNodes.length; i++) { + var linkNode = linkNodes[i]; + if (linkNode.rel === 'manifest') { + links.push( + { + rel: linkNode.rel, + href: linkNode.href, + sizes: null } - continue; + ); + } else if (linkNode.rel != null && linkNode.rel.indexOf('icon') >= 0) { + links.push( + { + rel: linkNode.rel, + href: linkNode.href, + sizes: linkNode.sizes != null && linkNode.sizes.value != "" ? linkNode.sizes.value : null + } + ); + } + } + return links; +})(); +"""))?.cast>() ?? []; + for (var link in links) { + if (link["rel"] == "manifest") { + manifestUrl = link["href"]; + if (!_isUrlAbsolute(manifestUrl)) { + if (manifestUrl.startsWith("/")) { + manifestUrl = manifestUrl.substring(1); + } + manifestUrl = ((assetPathBase == null) + ? url.scheme + "://" + url.host + "/" + : assetPathBase) + + manifestUrl; + } + continue; + } + favicons.addAll(_createFavicons(url, assetPathBase, link["href"], + link["rel"], link["sizes"], false)); } - if (!attributes["rel"].contains("icon")) { - continue; - } - favicons.addAll(_createFavicons(url, assetPathBase, attributes["href"], - attributes["rel"], attributes["sizes"], false)); } // try to get /favicon.ico @@ -923,7 +938,7 @@ class InAppWebViewController { favicons.add(Favicon(url: faviconUrl, rel: "shortcut icon")); } catch (e, stacktrace) { print("/favicon.ico file not found: " + e.toString()); - print(stacktrace); + // print(stacktrace); } // try to get the manifest file @@ -940,7 +955,7 @@ class InAppWebViewController { manifestResponse.headers.contentType?.mimeType == "application/json"; } catch (e, stacktrace) { print("Manifest file not found: " + e.toString()); - print(stacktrace); + // print(stacktrace); } if (manifestFound) { @@ -1181,6 +1196,11 @@ class InAppWebViewController { ///Evaluates JavaScript code into the WebView and returns the result of the evaluation. /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". + /// ///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E) ///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript Future evaluateJavascript({@required String source}) async { @@ -1192,6 +1212,11 @@ class InAppWebViewController { } ///Injects an external JavaScript file into the WebView from a defined url. + /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". Future injectJavascriptFileFromUrl({@required String urlFile}) async { Map args = {}; args.putIfAbsent('urlFile', () => urlFile); @@ -1199,6 +1224,11 @@ class InAppWebViewController { } ///Injects a JavaScript file into the WebView from the flutter assets directory. + /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". Future injectJavascriptFileFromAsset( {@required String assetFilePath}) async { String source = await rootBundle.loadString(assetFilePath); @@ -1206,6 +1236,11 @@ class InAppWebViewController { } ///Injects CSS into the WebView. + /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". Future injectCSSCode({@required String source}) async { Map args = {}; args.putIfAbsent('source', () => source); @@ -1213,6 +1248,11 @@ class InAppWebViewController { } ///Injects an external CSS file into the WebView from a defined url. + /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". Future injectCSSFileFromUrl({@required String urlFile}) async { Map args = {}; args.putIfAbsent('urlFile', () => urlFile); @@ -1220,6 +1260,11 @@ class InAppWebViewController { } ///Injects a CSS file into the WebView from the flutter assets directory. + /// + ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, + ///because, in these events, the [WebView] is not ready to handle it yet. + ///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events + ///where you know the page is ready "enough". Future injectCSSFileFromAsset({@required String assetFilePath}) async { String source = await rootBundle.loadString(assetFilePath); await injectCSSCode(source: source); @@ -1271,6 +1316,10 @@ class InAppWebViewController { ///``` /// ///Forbidden names for JavaScript handlers are defined in [javaScriptHandlerForbiddenNames]. + /// + ///**NOTE**: This method should be called, for example, in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events or, at least, + ///before you know that your JavaScript code will call the `window.flutter_inappwebview.callHandler` method, + ///otherwise you won't be able to intercept the JavaScript message. void addJavaScriptHandler( {@required String handlerName, @required JavaScriptHandlerCallback callback}) { diff --git a/lib/src/types.dart b/lib/src/types.dart index cc050fb1..b4c228d8 100755 --- a/lib/src/types.dart +++ b/lib/src/types.dart @@ -36,9 +36,17 @@ class ConsoleMessageLevel { const ConsoleMessageLevel._internal(this._value); + static final Set values = [ + ConsoleMessageLevel.TIP, + ConsoleMessageLevel.LOG, + ConsoleMessageLevel.WARNING, + ConsoleMessageLevel.ERROR, + ConsoleMessageLevel.DEBUG, + ].toSet(); + static ConsoleMessageLevel fromValue(int value) { - if (value != null && value >= 0 && value <= 4) - return ConsoleMessageLevel._internal(value); + if (value != null) + return ConsoleMessageLevel.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -126,12 +134,11 @@ class InAppWebViewInitialData { ///The URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL. This parameter is used only on Android. String historyUrl; - InAppWebViewInitialData( - {@required this.data, - this.mimeType = "text/html", - this.encoding = "utf8", - this.baseUrl = "about:blank", - this.historyUrl = "about:blank"}); + InAppWebViewInitialData({@required this.data, + this.mimeType = "text/html", + this.encoding = "utf8", + this.baseUrl = "about:blank", + this.historyUrl = "about:blank"}); Map toMap() { return { @@ -189,13 +196,12 @@ class WebResourceRequest { ///**NOTE**: Available on Android 21+. For Android < 21 it will be always `false`. bool isRedirect; - WebResourceRequest( - {@required this.url, - this.headers, - this.method, - this.hasGesture, - this.isForMainFrame, - this.isRedirect}); + WebResourceRequest({@required this.url, + this.headers, + this.method, + this.hasGesture, + this.isForMainFrame, + this.isRedirect}); Map toMap() { return { @@ -249,13 +255,12 @@ class WebResourceResponse { ///**NOTE**: Available on Android 21+. For Android < 21 it won't be used. String reasonPhrase; - WebResourceResponse( - {this.contentType = "", - this.contentEncoding = "utf-8", - this.data = null, - this.headers, - this.statusCode, - this.reasonPhrase}); + WebResourceResponse({this.contentType = "", + this.contentEncoding = "utf-8", + this.data, + this.headers, + this.statusCode, + this.reasonPhrase}); Map toMap() { return { @@ -289,10 +294,9 @@ class CustomSchemeResponse { ///Content-Enconding of the data, such as `utf-8`. String contentEnconding; - CustomSchemeResponse( - {@required this.data, - @required this.contentType, - this.contentEnconding = 'utf-8'}); + CustomSchemeResponse({@required this.data, + @required this.contentType, + this.contentEnconding = 'utf-8'}); Map toMap() { return { @@ -459,11 +463,10 @@ class JsAlertResponse { ///Action used to confirm that the user hit confirm button. JsAlertResponseAction action; - JsAlertResponse( - {this.message = "", - this.handledByClient = false, - this.confirmButtonTitle = "", - this.action = JsAlertResponseAction.CONFIRM}); + JsAlertResponse({this.message = "", + this.handledByClient = false, + this.confirmButtonTitle = "", + this.action = JsAlertResponseAction.CONFIRM}); Map toMap() { return { @@ -518,12 +521,11 @@ class JsConfirmResponse { ///Action used to confirm that the user hit confirm or cancel button. JsConfirmResponseAction action; - JsConfirmResponse( - {this.message = "", - this.handledByClient = false, - this.confirmButtonTitle = "", - this.cancelButtonTitle = "", - this.action = JsConfirmResponseAction.CANCEL}); + JsConfirmResponse({this.message = "", + this.handledByClient = false, + this.confirmButtonTitle = "", + this.cancelButtonTitle = "", + this.action = JsConfirmResponseAction.CANCEL}); Map toMap() { return { @@ -585,14 +587,13 @@ class JsPromptResponse { ///Action used to confirm that the user hit confirm or cancel button. JsPromptResponseAction action; - JsPromptResponse( - {this.message = "", - this.defaultValue = "", - this.handledByClient = false, - this.confirmButtonTitle = "", - this.cancelButtonTitle = "", - this.value, - this.action = JsPromptResponseAction.CANCEL}); + JsPromptResponse({this.message = "", + this.defaultValue = "", + this.handledByClient = false, + this.confirmButtonTitle = "", + this.cancelButtonTitle = "", + this.value, + this.action = JsPromptResponseAction.CANCEL}); Map toMap() { return { @@ -622,9 +623,17 @@ class SafeBrowsingThreat { const SafeBrowsingThreat._internal(this._value); + static final Set values = [ + SafeBrowsingThreat.SAFE_BROWSING_THREAT_UNKNOWN, + SafeBrowsingThreat.SAFE_BROWSING_THREAT_MALWARE, + SafeBrowsingThreat.SAFE_BROWSING_THREAT_PHISHING, + SafeBrowsingThreat.SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE, + SafeBrowsingThreat.SAFE_BROWSING_THREAT_BILLING, + ].toSet(); + static SafeBrowsingThreat fromValue(int value) { - if (value != null && value >= 0 && value <= 4) - return SafeBrowsingThreat._internal(value); + if (value != null) + return SafeBrowsingThreat.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -647,15 +656,15 @@ class SafeBrowsingThreat { } static const SAFE_BROWSING_THREAT_UNKNOWN = - const SafeBrowsingThreat._internal(0); + const SafeBrowsingThreat._internal(0); static const SAFE_BROWSING_THREAT_MALWARE = - const SafeBrowsingThreat._internal(1); + const SafeBrowsingThreat._internal(1); static const SAFE_BROWSING_THREAT_PHISHING = - const SafeBrowsingThreat._internal(2); + const SafeBrowsingThreat._internal(2); static const SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = - const SafeBrowsingThreat._internal(3); + const SafeBrowsingThreat._internal(3); static const SAFE_BROWSING_THREAT_BILLING = - const SafeBrowsingThreat._internal(4); + const SafeBrowsingThreat._internal(4); bool operator ==(value) => value == _value; @@ -679,7 +688,7 @@ class SafeBrowsingResponseAction { ///Display the default interstitial. static const SHOW_INTERSTITIAL = - const SafeBrowsingResponseAction._internal(2); + const SafeBrowsingResponseAction._internal(2); bool operator ==(value) => value == _value; @@ -696,9 +705,8 @@ class SafeBrowsingResponse { ///Indicate the [SafeBrowsingResponseAction] to take when hitting a malicious URL. SafeBrowsingResponseAction action; - SafeBrowsingResponse( - {this.report = true, - this.action = SafeBrowsingResponseAction.SHOW_INTERSTITIAL}); + SafeBrowsingResponse({this.report = true, + this.action = SafeBrowsingResponseAction.SHOW_INTERSTITIAL}); Map toMap() { return {"report": report, "action": action?.toValue()}; @@ -730,7 +738,7 @@ class HttpAuthResponseAction { ///Uses the credentials stored for the current host. static const USE_SAVED_HTTP_AUTH_CREDENTIALS = - const HttpAuthResponseAction._internal(2); + const HttpAuthResponseAction._internal(2); bool operator ==(value) => value == _value; @@ -752,11 +760,10 @@ class HttpAuthResponse { ///Indicate the [HttpAuthResponseAction] to take in response of the authentication challenge. HttpAuthResponseAction action; - HttpAuthResponse( - {this.username = "", - this.password = "", - this.permanentPersistence = false, - this.action = HttpAuthResponseAction.CANCEL}); + HttpAuthResponse({this.username = "", + this.password = "", + this.permanentPersistence = false, + this.action = HttpAuthResponseAction.CANCEL}); Map toMap() { return { @@ -928,12 +935,11 @@ class ServerTrustChallenge { ///The SSL certificate used for this challenge. SslCertificate sslCertificate; - ServerTrustChallenge( - {@required this.protectionSpace, - this.androidError, - this.iosError, - this.message, - this.sslCertificate}) + ServerTrustChallenge({@required this.protectionSpace, + this.androidError, + this.iosError, + this.message, + this.sslCertificate}) : assert(protectionSpace != null); Map toMap() { @@ -993,11 +999,10 @@ class ClientCertResponse { ///Indicate the [ClientCertResponseAction] to take in response of the client certificate challenge. ClientCertResponseAction action; - ClientCertResponse( - {this.certificatePath, - this.certificatePassword = "", - this.androidKeyStoreType = "PKCS12", - this.action = ClientCertResponseAction.CANCEL}) { + ClientCertResponse({this.certificatePath, + this.certificatePassword = "", + this.androidKeyStoreType = "PKCS12", + this.action = ClientCertResponseAction.CANCEL}) { if (this.action == ClientCertResponseAction.PROCEED) assert(certificatePath != null && certificatePath.isNotEmpty); } @@ -1081,9 +1086,16 @@ class AndroidCacheMode { const AndroidCacheMode._internal(this._value); + static final Set values = [ + AndroidCacheMode.LOAD_DEFAULT, + AndroidCacheMode.LOAD_CACHE_ELSE_NETWORK, + AndroidCacheMode.LOAD_NO_CACHE, + AndroidCacheMode.LOAD_CACHE_ONLY, + ].toSet(); + static AndroidCacheMode fromValue(int value) { - if (value != null && value >= 0 && value <= 3) - return AndroidCacheMode._internal(value); + if (value != null) + return AndroidCacheMode.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1131,9 +1143,16 @@ class AndroidActionModeMenuItem { const AndroidActionModeMenuItem._internal(this._value); + static final Set values = [ + AndroidActionModeMenuItem.MENU_ITEM_NONE, + AndroidActionModeMenuItem.MENU_ITEM_SHARE, + AndroidActionModeMenuItem.MENU_ITEM_WEB_SEARCH, + AndroidActionModeMenuItem.MENU_ITEM_PROCESS_TEXT, + ].toSet(); + static AndroidActionModeMenuItem fromValue(int value) { - if (value != null && value != 3 && value >= 0 && value <= 4) - return AndroidActionModeMenuItem._internal(value); + if (value != null) + return AndroidActionModeMenuItem.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1162,11 +1181,11 @@ class AndroidActionModeMenuItem { ///Disable menu item "Web Search". static const MENU_ITEM_WEB_SEARCH = - const AndroidActionModeMenuItem._internal(2); + const AndroidActionModeMenuItem._internal(2); ///Disable all the action mode menu items for text processing. static const MENU_ITEM_PROCESS_TEXT = - const AndroidActionModeMenuItem._internal(4); + const AndroidActionModeMenuItem._internal(4); bool operator ==(value) => value == _value; @@ -1182,9 +1201,15 @@ class AndroidForceDark { const AndroidForceDark._internal(this._value); + static final Set values = [ + AndroidForceDark.FORCE_DARK_OFF, + AndroidForceDark.FORCE_DARK_AUTO, + AndroidForceDark.FORCE_DARK_ON, + ].toSet(); + static AndroidForceDark fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return AndroidForceDark._internal(value); + if (value != null) + return AndroidForceDark.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1225,10 +1250,16 @@ class AndroidLayoutAlgorithm { const AndroidLayoutAlgorithm._internal(this._value); + static final Set values = [ + AndroidLayoutAlgorithm.NORMAL, + AndroidLayoutAlgorithm.TEXT_AUTOSIZING, + AndroidLayoutAlgorithm.NARROW_COLUMNS, + ].toSet(); + static AndroidLayoutAlgorithm fromValue(String value) { - return (["NORMAL", "TEXT_AUTOSIZING", "NARROW_COLUMNS"].contains(value)) - ? AndroidLayoutAlgorithm._internal(value) - : null; + if (value != null) + return AndroidLayoutAlgorithm.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -1244,11 +1275,11 @@ class AndroidLayoutAlgorithm { /// ///**NOTE**: available on Android 19+. static const TEXT_AUTOSIZING = - const AndroidLayoutAlgorithm._internal("TEXT_AUTOSIZING"); + const AndroidLayoutAlgorithm._internal("TEXT_AUTOSIZING"); ///NARROW_COLUMNS makes all columns no wider than the screen if possible. Only use this for API levels prior to `Build.VERSION_CODES.KITKAT`. static const NARROW_COLUMNS = - const AndroidLayoutAlgorithm._internal("NARROW_COLUMNS"); + const AndroidLayoutAlgorithm._internal("NARROW_COLUMNS"); bool operator ==(value) => value == _value; @@ -1264,9 +1295,15 @@ class AndroidMixedContentMode { const AndroidMixedContentMode._internal(this._value); + static final Set values = [ + AndroidMixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW, + AndroidMixedContentMode.MIXED_CONTENT_NEVER_ALLOW, + AndroidMixedContentMode.MIXED_CONTENT_COMPATIBILITY_MODE, + ].toSet(); + static AndroidMixedContentMode fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return AndroidMixedContentMode._internal(value); + if (value != null) + return AndroidMixedContentMode.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1288,12 +1325,12 @@ class AndroidMixedContentMode { ///In this mode, the WebView will allow a secure origin to load content from any other origin, even if that origin is insecure. ///This is the least secure mode of operation for the WebView, and where possible apps should not set this mode. static const MIXED_CONTENT_ALWAYS_ALLOW = - const AndroidMixedContentMode._internal(0); + const AndroidMixedContentMode._internal(0); ///In this mode, the WebView will not allow a secure origin to load content from an insecure origin. ///This is the preferred and most secure mode of operation for the WebView and apps are strongly advised to use this mode. static const MIXED_CONTENT_NEVER_ALLOW = - const AndroidMixedContentMode._internal(1); + const AndroidMixedContentMode._internal(1); ///In this mode, the WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content. ///Some insecure content may be allowed to be loaded by a secure origin and other types of content will be blocked. @@ -1301,7 +1338,7 @@ class AndroidMixedContentMode { ///This mode is intended to be used by apps that are not in control of the content that they render but desire to operate in a reasonably secure environment. ///For highest security, apps are recommended to use [AndroidMixedContentMode.MIXED_CONTENT_NEVER_ALLOW]. static const MIXED_CONTENT_COMPATIBILITY_MODE = - const AndroidMixedContentMode._internal(2); + const AndroidMixedContentMode._internal(2); bool operator ==(value) => value == _value; @@ -1315,9 +1352,14 @@ class IOSWKSelectionGranularity { const IOSWKSelectionGranularity._internal(this._value); + static final Set values = [ + IOSWKSelectionGranularity.DYNAMIC, + IOSWKSelectionGranularity.CHARACTER, + ].toSet(); + static IOSWKSelectionGranularity fromValue(int value) { - if (value != null && value >= 0 && value <= 1) - return IOSWKSelectionGranularity._internal(value); + if (value != null) + return IOSWKSelectionGranularity.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1354,22 +1396,23 @@ class IOSWKDataDetectorTypes { const IOSWKDataDetectorTypes._internal(this._value); + static final Set values = [ + IOSWKDataDetectorTypes.NONE, + IOSWKDataDetectorTypes.PHONE_NUMBER, + IOSWKDataDetectorTypes.LINK, + IOSWKDataDetectorTypes.ADDRESS, + IOSWKDataDetectorTypes.CALENDAR_EVENT, + IOSWKDataDetectorTypes.TRACKING_NUMBER, + IOSWKDataDetectorTypes.FLIGHT_NUMBER, + IOSWKDataDetectorTypes.LOOKUP_SUGGESTION, + IOSWKDataDetectorTypes.SPOTLIGHT_SUGGESTION, + IOSWKDataDetectorTypes.ALL, + ].toSet(); + static IOSWKDataDetectorTypes fromValue(String value) { - return ([ - "NONE", - "PHONE_NUMBER", - "LINK", - "ADDRESS", - "CALENDAR_EVENT", - "TRACKING_NUMBER", - "TRACKING_NUMBER", - "FLIGHT_NUMBER", - "LOOKUP_SUGGESTION", - "SPOTLIGHT_SUGGESTION", - "ALL" - ].contains(value)) - ? IOSWKDataDetectorTypes._internal(value) - : null; + if (value != null) + return IOSWKDataDetectorTypes.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -1382,7 +1425,7 @@ class IOSWKDataDetectorTypes { ///Phone numbers are detected and turned into links. static const PHONE_NUMBER = - const IOSWKDataDetectorTypes._internal("PHONE_NUMBER"); + const IOSWKDataDetectorTypes._internal("PHONE_NUMBER"); ///URLs in text are detected and turned into links. static const LINK = const IOSWKDataDetectorTypes._internal("LINK"); @@ -1392,23 +1435,23 @@ class IOSWKDataDetectorTypes { ///Dates and times that are in the future are detected and turned into links. static const CALENDAR_EVENT = - const IOSWKDataDetectorTypes._internal("CALENDAR_EVENT"); + const IOSWKDataDetectorTypes._internal("CALENDAR_EVENT"); ///Tracking numbers are detected and turned into links. static const TRACKING_NUMBER = - const IOSWKDataDetectorTypes._internal("TRACKING_NUMBER"); + const IOSWKDataDetectorTypes._internal("TRACKING_NUMBER"); ///Flight numbers are detected and turned into links. static const FLIGHT_NUMBER = - const IOSWKDataDetectorTypes._internal("FLIGHT_NUMBER"); + const IOSWKDataDetectorTypes._internal("FLIGHT_NUMBER"); ///Lookup suggestions are detected and turned into links. static const LOOKUP_SUGGESTION = - const IOSWKDataDetectorTypes._internal("LOOKUP_SUGGESTION"); + const IOSWKDataDetectorTypes._internal("LOOKUP_SUGGESTION"); ///Spotlight suggestions are detected and turned into links. static const SPOTLIGHT_SUGGESTION = - const IOSWKDataDetectorTypes._internal("SPOTLIGHT_SUGGESTION"); + const IOSWKDataDetectorTypes._internal("SPOTLIGHT_SUGGESTION"); ///All of the above data types are turned into links when detected. Choosing this value will automatically include any new detection type that is added. static const ALL = const IOSWKDataDetectorTypes._internal("ALL"); @@ -1425,10 +1468,15 @@ class IOSUIScrollViewDecelerationRate { const IOSUIScrollViewDecelerationRate._internal(this._value); + static final Set values = [ + IOSUIScrollViewDecelerationRate.NORMAL, + IOSUIScrollViewDecelerationRate.FAST, + ].toSet(); + static IOSUIScrollViewDecelerationRate fromValue(String value) { - return (["NORMAL", "FAST"].contains(value)) - ? IOSUIScrollViewDecelerationRate._internal(value) - : null; + if (value != null) + return IOSUIScrollViewDecelerationRate.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -1438,7 +1486,7 @@ class IOSUIScrollViewDecelerationRate { ///The default deceleration rate for a scroll view: `0.998`. static const NORMAL = - const IOSUIScrollViewDecelerationRate._internal("NORMAL"); + const IOSUIScrollViewDecelerationRate._internal("NORMAL"); ///A fast deceleration rate for a scroll view: `0.99`. static const FAST = const IOSUIScrollViewDecelerationRate._internal("FAST"); @@ -1455,9 +1503,15 @@ class UserPreferredContentMode { const UserPreferredContentMode._internal(this._value); + static final Set values = [ + UserPreferredContentMode.RECOMMENDED, + UserPreferredContentMode.MOBILE, + UserPreferredContentMode.DESKTOP, + ].toSet(); + static UserPreferredContentMode fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return UserPreferredContentMode._internal(value); + if (value != null) + return UserPreferredContentMode.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1497,9 +1551,22 @@ class IOSUIModalPresentationStyle { const IOSUIModalPresentationStyle._internal(this._value); + static final Set values = [ + IOSUIModalPresentationStyle.FULL_SCREEN, + IOSUIModalPresentationStyle.PAGE_SHEET, + IOSUIModalPresentationStyle.FORM_SHEET, + IOSUIModalPresentationStyle.CURRENT_CONTEXT, + IOSUIModalPresentationStyle.CUSTOM, + IOSUIModalPresentationStyle.OVER_FULL_SCREEN, + IOSUIModalPresentationStyle.OVER_CURRENT_CONTEXT, + IOSUIModalPresentationStyle.POPOVER, + IOSUIModalPresentationStyle.NONE, + IOSUIModalPresentationStyle.AUTOMATIC, + ].toSet(); + static IOSUIModalPresentationStyle fromValue(int value) { - if (value != null && value >= 0 && value <= 9) - return IOSUIModalPresentationStyle._internal(value); + if (value != null) + return IOSUIModalPresentationStyle.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1549,11 +1616,11 @@ class IOSUIModalPresentationStyle { ///A view presentation style in which the presented view covers the screen. static const OVER_FULL_SCREEN = - const IOSUIModalPresentationStyle._internal(5); + const IOSUIModalPresentationStyle._internal(5); ///A presentation style where the content is displayed over another view controller’s content. static const OVER_CURRENT_CONTEXT = - const IOSUIModalPresentationStyle._internal(6); + const IOSUIModalPresentationStyle._internal(6); ///A presentation style where the content is displayed in a popover view. static const POPOVER = const IOSUIModalPresentationStyle._internal(7); @@ -1578,9 +1645,16 @@ class IOSUIModalTransitionStyle { const IOSUIModalTransitionStyle._internal(this._value); + static final Set values = [ + IOSUIModalTransitionStyle.COVER_VERTICAL, + IOSUIModalTransitionStyle.FLIP_HORIZONTAL, + IOSUIModalTransitionStyle.CROSS_DISSOLVE, + IOSUIModalTransitionStyle.PARTIAL_CURL, + ].toSet(); + static IOSUIModalTransitionStyle fromValue(int value) { - if (value != null && value >= 0 && value <= 3) - return IOSUIModalTransitionStyle._internal(value); + if (value != null) + return IOSUIModalTransitionStyle.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1633,9 +1707,15 @@ class IOSSafariDismissButtonStyle { const IOSSafariDismissButtonStyle._internal(this._value); + static final Set values = [ + IOSSafariDismissButtonStyle.DONE, + IOSSafariDismissButtonStyle.CLOSE, + IOSSafariDismissButtonStyle.CANCEL, + ].toSet(); + static IOSSafariDismissButtonStyle fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return IOSSafariDismissButtonStyle._internal(value); + if (value != null) + return IOSSafariDismissButtonStyle.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -1680,7 +1760,13 @@ class InAppWebViewGroupOptions { ///iOS-specific options. IOSInAppWebViewOptions ios; - InAppWebViewGroupOptions({this.crossPlatform, this.android, this.ios}); + InAppWebViewGroupOptions({this.crossPlatform, + this.android, + this.ios}) { + this.crossPlatform = this.crossPlatform ?? InAppWebViewOptions(); + this.android = this.android ?? AndroidInAppWebViewOptions(); + this.ios = this.ios ?? IOSInAppWebViewOptions(); + } Map toMap() { Map options = {}; @@ -1695,9 +1781,11 @@ class InAppWebViewGroupOptions { static InAppWebViewGroupOptions fromMap(Map options) { InAppWebViewGroupOptions inAppWebViewGroupOptions = InAppWebViewGroupOptions(); - inAppWebViewGroupOptions.crossPlatform = InAppWebViewOptions.fromMap(options); + inAppWebViewGroupOptions.crossPlatform = + InAppWebViewOptions.fromMap(options); if (Platform.isAndroid) - inAppWebViewGroupOptions.android = AndroidInAppWebViewOptions.fromMap(options); + inAppWebViewGroupOptions.android = + AndroidInAppWebViewOptions.fromMap(options); else if (Platform.isIOS) inAppWebViewGroupOptions.ios = IOSInAppWebViewOptions.fromMap(options); @@ -1716,12 +1804,6 @@ class InAppWebViewGroupOptions { InAppWebViewGroupOptions copy() { return InAppWebViewGroupOptions.fromMap(this.toMap()); } - - InAppWebViewGroupOptions copyWithValue(InAppWebViewGroupOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return InAppWebViewGroupOptions.fromMap(mergedMap); - } } ///Class that represents the options that can be used for an [InAppBrowser] WebView. @@ -1738,11 +1820,16 @@ class InAppBrowserClassOptions { ///WebView options. InAppWebViewGroupOptions inAppWebViewGroupOptions; - InAppBrowserClassOptions( - {this.crossPlatform, - this.android, - this.ios, - this.inAppWebViewGroupOptions}); + InAppBrowserClassOptions({this.crossPlatform, + this.android, + this.ios, + this.inAppWebViewGroupOptions}) { + this.crossPlatform = this.crossPlatform ?? InAppBrowserOptions(); + this.android = this.android ?? AndroidInAppBrowserOptions(); + this.ios = this.ios ?? IOSInAppBrowserOptions(); + this.inAppWebViewGroupOptions = + this.inAppWebViewGroupOptions ?? InAppWebViewGroupOptions(); + } Map toMap() { Map options = {}; @@ -1795,12 +1882,6 @@ class InAppBrowserClassOptions { InAppBrowserClassOptions copy() { return InAppBrowserClassOptions.fromMap(this.toMap()); } - - InAppBrowserClassOptions copyWithValue(InAppBrowserClassOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return InAppBrowserClassOptions.fromMap(mergedMap); - } } ///Class that represents the options that can be used for an [ChromeSafariBrowser] window. @@ -1811,7 +1892,13 @@ class ChromeSafariBrowserClassOptions { ///iOS-specific options. IOSSafariOptions ios; - ChromeSafariBrowserClassOptions({this.android, this.ios}); + ChromeSafariBrowserClassOptions({ + this.android, + this.ios + }) { + this.android = this.android ?? AndroidChromeCustomTabsOptions(); + this.ios = this.ios ?? IOSSafariOptions(); + } Map toMap() { Map options = {}; @@ -1873,11 +1960,20 @@ class AjaxRequestEventType { const AjaxRequestEventType._internal(this._value); + static final Set values = [ + AjaxRequestEventType.LOADSTART, + AjaxRequestEventType.LOAD, + AjaxRequestEventType.LOADEND, + AjaxRequestEventType.PROGRESS, + AjaxRequestEventType.ERROR, + AjaxRequestEventType.ABORT, + AjaxRequestEventType.TIMEOUT, + ].toSet(); + static AjaxRequestEventType fromValue(String value) { - return (["loadstart", "load", "loadend", "progress", "error", "abort"] - .contains(value)) - ? AjaxRequestEventType._internal(value) - : null; + if (value != null) + return AjaxRequestEventType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -1939,9 +2035,17 @@ class AjaxRequestReadyState { const AjaxRequestReadyState._internal(this._value); + static final Set values = [ + AjaxRequestReadyState.UNSENT, + AjaxRequestReadyState.OPENED, + AjaxRequestReadyState.HEADERS_RECEIVED, + AjaxRequestReadyState.LOADING, + AjaxRequestReadyState.DONE, + ].toSet(); + static AjaxRequestReadyState fromValue(int value) { - if (value != null && value >= 0 && value <= 4) - return AjaxRequestReadyState._internal(value); + if (value != null) + return AjaxRequestReadyState.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -2079,26 +2183,25 @@ class AjaxRequest { ///Indicates the [AjaxRequestAction] that can be used to control the `XMLHttpRequest` request. AjaxRequestAction action; - AjaxRequest( - {this.data, - this.method, - this.url, - this.isAsync, - this.user, - this.password, - this.withCredentials, - this.headers, - this.readyState, - this.status, - this.responseURL, - this.responseType, - this.response, - this.responseText, - this.responseXML, - this.statusText, - this.responseHeaders, - this.event, - this.action = AjaxRequestAction.PROCEED}); + AjaxRequest({this.data, + this.method, + this.url, + this.isAsync, + this.user, + this.password, + this.withCredentials, + this.headers, + this.readyState, + this.status, + this.responseURL, + this.responseType, + this.response, + this.responseText, + this.responseXML, + this.statusText, + this.responseHeaders, + this.event, + this.action = AjaxRequestAction.PROCEED}); Map toMap() { return { @@ -2319,20 +2422,19 @@ class FetchRequest { ///Indicates the [FetchRequestAction] that can be used to control the request. FetchRequestAction action; - FetchRequest( - {this.url, - this.method, - this.headers, - this.body, - this.mode, - this.credentials, - this.cache, - this.redirect, - this.referrer, - this.referrerPolicy, - this.integrity, - this.keepalive, - this.action = FetchRequestAction.PROCEED}); + FetchRequest({this.url, + this.method, + this.headers, + this.body, + this.mode, + this.credentials, + this.cache, + this.redirect, + this.referrer, + this.referrerPolicy, + this.integrity, + this.keepalive, + this.action = FetchRequestAction.PROCEED}); Map toMap() { return { @@ -2393,19 +2495,21 @@ class ContentBlockerTriggerResourceType { const ContentBlockerTriggerResourceType._internal(this._value); + static final Set values = [ + ContentBlockerTriggerResourceType.DOCUMENT, + ContentBlockerTriggerResourceType.IMAGE, + ContentBlockerTriggerResourceType.STYLE_SHEET, + ContentBlockerTriggerResourceType.SCRIPT, + ContentBlockerTriggerResourceType.FONT, + ContentBlockerTriggerResourceType.MEDIA, + ContentBlockerTriggerResourceType.SVG_DOCUMENT, + ContentBlockerTriggerResourceType.RAW, + ].toSet(); + static ContentBlockerTriggerResourceType fromValue(String value) { - return ([ - "document", - "image", - "style-sheet", - "script", - "font", - "media", - "svg-document", - "raw" - ].contains(value)) - ? ContentBlockerTriggerResourceType._internal(value) - : null; + if (value != null) + return ContentBlockerTriggerResourceType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -2414,18 +2518,18 @@ class ContentBlockerTriggerResourceType { String toString() => _value; static const DOCUMENT = - const ContentBlockerTriggerResourceType._internal('document'); + const ContentBlockerTriggerResourceType._internal('document'); static const IMAGE = - const ContentBlockerTriggerResourceType._internal('image'); + const ContentBlockerTriggerResourceType._internal('image'); static const STYLE_SHEET = - const ContentBlockerTriggerResourceType._internal('style-sheet'); + const ContentBlockerTriggerResourceType._internal('style-sheet'); static const SCRIPT = - const ContentBlockerTriggerResourceType._internal('script'); + const ContentBlockerTriggerResourceType._internal('script'); static const FONT = const ContentBlockerTriggerResourceType._internal('font'); static const MEDIA = - const ContentBlockerTriggerResourceType._internal('media'); + const ContentBlockerTriggerResourceType._internal('media'); static const SVG_DOCUMENT = - const ContentBlockerTriggerResourceType._internal('svg-document'); + const ContentBlockerTriggerResourceType._internal('svg-document'); ///Any untyped load static const RAW = const ContentBlockerTriggerResourceType._internal('raw'); @@ -2442,10 +2546,15 @@ class ContentBlockerTriggerLoadType { const ContentBlockerTriggerLoadType._internal(this._value); + static final Set values = [ + ContentBlockerTriggerLoadType.FIRST_PARTY, + ContentBlockerTriggerLoadType.THIRD_PARTY, + ].toSet(); + static ContentBlockerTriggerLoadType fromValue(String value) { - return (["first-party", "third-party"].contains(value)) - ? ContentBlockerTriggerLoadType._internal(value) - : null; + if (value != null) + return ContentBlockerTriggerLoadType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -2455,11 +2564,11 @@ class ContentBlockerTriggerLoadType { ///FIRST_PARTY is triggered only if the resource has the same scheme, domain, and port as the main page resource. static const FIRST_PARTY = - const ContentBlockerTriggerLoadType._internal('first-party'); + const ContentBlockerTriggerLoadType._internal('first-party'); ///THIRD_PARTY is triggered if the resource is not from the same domain as the main page resource. static const THIRD_PARTY = - const ContentBlockerTriggerLoadType._internal('third-party'); + const ContentBlockerTriggerLoadType._internal('third-party'); bool operator ==(value) => value == _value; @@ -2473,10 +2582,16 @@ class ContentBlockerActionType { const ContentBlockerActionType._internal(this._value); + static final Set values = [ + ContentBlockerActionType.BLOCK, + ContentBlockerActionType.CSS_DISPLAY_NONE, + ContentBlockerActionType.MAKE_HTTPS, + ].toSet(); + static ContentBlockerActionType fromValue(String value) { - return (["block", "css-display-none", "make-https"].contains(value)) - ? ContentBlockerActionType._internal(value) - : null; + if (value != null) + return ContentBlockerActionType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -2491,11 +2606,11 @@ class ContentBlockerActionType { /// ///**NOTE**: on Android, JavaScript must be enabled. static const CSS_DISPLAY_NONE = - const ContentBlockerActionType._internal('css-display-none'); + const ContentBlockerActionType._internal('css-display-none'); ///Changes a URL from http to https. URLs with a specified (nondefault) port and links using other protocols are unaffected. static const MAKE_HTTPS = - const ContentBlockerActionType._internal('make-https'); + const ContentBlockerActionType._internal('make-https'); bool operator ==(value) => value == _value; @@ -2546,16 +2661,15 @@ class Cookie { ///**NOTE**: on Android it will be always `null`. String path; - Cookie( - {@required this.name, - @required this.value, - this.expiresDate, - this.isSessionOnly, - this.domain, - this.sameSite, - this.isSecure, - this.isHttpOnly, - this.path}); + Cookie({@required this.name, + @required this.value, + this.expiresDate, + this.isSessionOnly, + this.domain, + this.sameSite, + this.isSecure, + this.isHttpOnly, + this.path}); Map toMap() { return { @@ -2609,9 +2723,8 @@ class PermissionRequestResponse { ///Indicate the [PermissionRequestResponseAction] to take in response of a permission request. PermissionRequestResponseAction action; - PermissionRequestResponse( - {this.resources = const [], - this.action = PermissionRequestResponseAction.DENY}); + PermissionRequestResponse({this.resources = const [], + this.action = PermissionRequestResponseAction.DENY}); Map toMap() { return {"resources": resources, "action": action?.toValue()}; @@ -2660,14 +2773,23 @@ class IOSWKNavigationType { const IOSWKNavigationType._internal(this._value); - int toValue() => _value; + static final Set values = [ + IOSWKNavigationType.LINK_ACTIVATED, + IOSWKNavigationType.FORM_SUBMITTED, + IOSWKNavigationType.BACK_FORWARD, + IOSWKNavigationType.RELOAD, + IOSWKNavigationType.FORM_RESUBMITTED, + IOSWKNavigationType.OTHER, + ].toSet(); static IOSWKNavigationType fromValue(int value) { - if (value != null && ((value >= 0 && value <= 4) || value == -1)) - return IOSWKNavigationType._internal(value); + if (value != null) + return IOSWKNavigationType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } + int toValue() => _value; + ///A link with an href attribute was activated by the user. static const LINK_ACTIVATED = const IOSWKNavigationType._internal(0); @@ -2720,14 +2842,13 @@ class ShouldOverrideUrlLoadingRequest { ///The type of action triggering the navigation. Available only on iOS. IOSWKNavigationType iosWKNavigationType; - ShouldOverrideUrlLoadingRequest( - {this.url, - this.method, - this.headers, - this.isForMainFrame, - this.androidHasGesture, - this.androidIsRedirect, - this.iosWKNavigationType}); + ShouldOverrideUrlLoadingRequest({this.url, + this.method, + this.headers, + this.isForMainFrame, + this.androidHasGesture, + this.androidIsRedirect, + this.iosWKNavigationType}); Map toMap() { return { @@ -2765,11 +2886,10 @@ class OnCreateWindowRequest { ///The type of action triggering the navigation. Available only on iOS. IOSWKNavigationType iosWKNavigationType; - OnCreateWindowRequest( - {this.url, - this.androidIsDialog, - this.androidIsUserGesture, - this.iosWKNavigationType}); + OnCreateWindowRequest({this.url, + this.androidIsDialog, + this.androidIsUserGesture, + this.iosWKNavigationType}); Map toMap() { return { @@ -2826,21 +2946,23 @@ class IOSWKWebsiteDataType { const IOSWKWebsiteDataType._internal(this._value); + static final Set values = [ + IOSWKWebsiteDataType.WKWebsiteDataTypeFetchCache, + IOSWKWebsiteDataType.WKWebsiteDataTypeDiskCache, + IOSWKWebsiteDataType.WKWebsiteDataTypeMemoryCache, + IOSWKWebsiteDataType.WKWebsiteDataTypeOfflineWebApplicationCache, + IOSWKWebsiteDataType.WKWebsiteDataTypeCookies, + IOSWKWebsiteDataType.WKWebsiteDataTypeSessionStorage, + IOSWKWebsiteDataType.WKWebsiteDataTypeLocalStorage, + IOSWKWebsiteDataType.WKWebsiteDataTypeWebSQLDatabases, + IOSWKWebsiteDataType.WKWebsiteDataTypeIndexedDBDatabases, + IOSWKWebsiteDataType.WKWebsiteDataTypeServiceWorkerRegistrations, + ].toSet(); + static IOSWKWebsiteDataType fromValue(String value) { - return ([ - "WKWebsiteDataTypeFetchCache", - "WKWebsiteDataTypeDiskCache", - "WKWebsiteDataTypeMemoryCache", - "WKWebsiteDataTypeOfflineWebApplicationCache", - "WKWebsiteDataTypeCookies", - "WKWebsiteDataTypeSessionStorage", - "WKWebsiteDataTypeLocalStorage", - "WKWebsiteDataTypeWebSQLDatabases", - "WKWebsiteDataTypeIndexedDBDatabases", - "WKWebsiteDataTypeServiceWorkerRegistrations" - ].contains(value)) - ? IOSWKWebsiteDataType._internal(value) - : null; + if (value != null) + return IOSWKWebsiteDataType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -2852,50 +2974,51 @@ class IOSWKWebsiteDataType { /// ///**NOTE**: available on iOS 11.3+. static const WKWebsiteDataTypeFetchCache = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeFetchCache"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeFetchCache"); ///On-disk caches. static const WKWebsiteDataTypeDiskCache = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeDiskCache"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeDiskCache"); ///In-memory caches. static const WKWebsiteDataTypeMemoryCache = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeMemoryCache"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeMemoryCache"); ///HTML offline web application caches. static const WKWebsiteDataTypeOfflineWebApplicationCache = - const IOSWKWebsiteDataType._internal( - "WKWebsiteDataTypeOfflineWebApplicationCache"); + const IOSWKWebsiteDataType._internal( + "WKWebsiteDataTypeOfflineWebApplicationCache"); ///Cookies. static const WKWebsiteDataTypeCookies = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeCookies"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeCookies"); ///HTML session storage. static const WKWebsiteDataTypeSessionStorage = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeSessionStorage"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeSessionStorage"); ///HTML local storage. static const WKWebsiteDataTypeLocalStorage = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeLocalStorage"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeLocalStorage"); ///WebSQL databases. static const WKWebsiteDataTypeWebSQLDatabases = - const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeWebSQLDatabases"); + const IOSWKWebsiteDataType._internal("WKWebsiteDataTypeWebSQLDatabases"); ///IndexedDB databases. static const WKWebsiteDataTypeIndexedDBDatabases = - const IOSWKWebsiteDataType._internal( - "WKWebsiteDataTypeIndexedDBDatabases"); + const IOSWKWebsiteDataType._internal( + "WKWebsiteDataTypeIndexedDBDatabases"); ///Service worker registrations. /// ///**NOTE**: available on iOS 11.3+. static const WKWebsiteDataTypeServiceWorkerRegistrations = - const IOSWKWebsiteDataType._internal( - "WKWebsiteDataTypeServiceWorkerRegistrations"); + const IOSWKWebsiteDataType._internal( + "WKWebsiteDataTypeServiceWorkerRegistrations"); ///Returns a set of all available website data types. + // ignore: non_constant_identifier_names static final Set ALL = [ IOSWKWebsiteDataType.WKWebsiteDataTypeFetchCache, IOSWKWebsiteDataType.WKWebsiteDataTypeDiskCache, @@ -2952,9 +3075,20 @@ class InAppWebViewHitTestResultType { const InAppWebViewHitTestResultType._internal(this._value); + static final Set values = [ + InAppWebViewHitTestResultType.UNKNOWN_TYPE, + InAppWebViewHitTestResultType.PHONE_TYPE, + InAppWebViewHitTestResultType.GEO_TYPE, + InAppWebViewHitTestResultType.EMAIL_TYPE, + InAppWebViewHitTestResultType.IMAGE_TYPE, + InAppWebViewHitTestResultType.SRC_ANCHOR_TYPE, + InAppWebViewHitTestResultType.SRC_IMAGE_ANCHOR_TYPE, + InAppWebViewHitTestResultType.EDIT_TEXT_TYPE, + ].toSet(); + static InAppWebViewHitTestResultType fromValue(int value) { - if (value != null && [0, 2, 3, 4, 5, 7, 8, 9].contains(value)) - return InAppWebViewHitTestResultType._internal(value); + if (value != null) + return InAppWebViewHitTestResultType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3000,15 +3134,15 @@ class InAppWebViewHitTestResultType { ///[InAppWebViewHitTestResult] for hitting a HTML::a tag with src=http. static const SRC_ANCHOR_TYPE = - const InAppWebViewHitTestResultType._internal(7); + const InAppWebViewHitTestResultType._internal(7); ///[InAppWebViewHitTestResult] for hitting a HTML::a tag with src=http + HTML::img. static const SRC_IMAGE_ANCHOR_TYPE = - const InAppWebViewHitTestResultType._internal(8); + const InAppWebViewHitTestResultType._internal(8); ///[InAppWebViewHitTestResult] for hitting an edit text area. static const EDIT_TEXT_TYPE = - const InAppWebViewHitTestResultType._internal(9); + const InAppWebViewHitTestResultType._internal(9); bool operator ==(value) => value == _value; @@ -3099,9 +3233,15 @@ class RendererPriority { const RendererPriority._internal(this._value); + static final Set values = [ + RendererPriority.RENDERER_PRIORITY_WAIVED, + RendererPriority.RENDERER_PRIORITY_BOUND, + RendererPriority.RENDERER_PRIORITY_IMPORTANT, + ].toSet(); + static RendererPriority fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return RendererPriority._internal(value); + if (value != null) + return RendererPriority.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3129,7 +3269,7 @@ class RendererPriority { ///The renderer associated with this WebView is bound with Android `Context#BIND_IMPORTANT`. static const RENDERER_PRIORITY_IMPORTANT = - const RendererPriority._internal(2); + const RendererPriority._internal(2); bool operator ==(value) => value == _value; @@ -3150,9 +3290,8 @@ class RendererPriorityPolicy { ///If true, this flag specifies that when this WebView is not visible, it will be treated as if it had requested a priority of [RendererPriority.RENDERER_PRIORITY_WAIVED]. bool waivedWhenNotVisible; - RendererPriorityPolicy( - {@required this.rendererRequestedPriority, - @required this.waivedWhenNotVisible}); + RendererPriorityPolicy({@required this.rendererRequestedPriority, + @required this.waivedWhenNotVisible}); Map toMap() { return { @@ -3173,9 +3312,9 @@ class RendererPriorityPolicy { static RendererPriorityPolicy fromMap(Map map) { return map != null ? RendererPriorityPolicy( - rendererRequestedPriority: - RendererPriority.fromValue(map["rendererRequestedPriority"]), - waivedWhenNotVisible: map["waivedWhenNotVisible"]) + rendererRequestedPriority: + RendererPriority.fromValue(map["rendererRequestedPriority"]), + waivedWhenNotVisible: map["waivedWhenNotVisible"]) : null; } } @@ -3220,9 +3359,15 @@ class AndroidOverScrollMode { const AndroidOverScrollMode._internal(this._value); + static final Set values = [ + AndroidOverScrollMode.OVER_SCROLL_ALWAYS, + AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS, + AndroidOverScrollMode.OVER_SCROLL_NEVER, + ].toSet(); + static AndroidOverScrollMode fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return AndroidOverScrollMode._internal(value); + if (value != null) + return AndroidOverScrollMode.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3246,7 +3391,7 @@ class AndroidOverScrollMode { ///Allow a user to over-scroll this view only if the content is large enough to meaningfully scroll, provided it is a view that can scroll. static const OVER_SCROLL_IF_CONTENT_SCROLLS = - const AndroidOverScrollMode._internal(1); + const AndroidOverScrollMode._internal(1); ///Never allow a user to over-scroll this view. static const OVER_SCROLL_NEVER = const AndroidOverScrollMode._internal(2); @@ -3269,9 +3414,16 @@ class AndroidScrollBarStyle { const AndroidScrollBarStyle._internal(this._value); + static final Set values = [ + AndroidScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY, + AndroidScrollBarStyle.SCROLLBARS_INSIDE_INSET, + AndroidScrollBarStyle.SCROLLBARS_OUTSIDE_OVERLAY, + AndroidScrollBarStyle.SCROLLBARS_OUTSIDE_INSET, + ].toSet(); + static AndroidScrollBarStyle fromValue(int value) { - if (value != null && [0, 16777216, 33554432, 50331648].contains(value)) - return AndroidScrollBarStyle._internal(value); + if (value != null) + return AndroidScrollBarStyle.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3295,22 +3447,22 @@ class AndroidScrollBarStyle { ///The scrollbar style to display the scrollbars inside the content area, without increasing the padding. ///The scrollbars will be overlaid with translucency on the view's content. static const SCROLLBARS_INSIDE_OVERLAY = - const AndroidScrollBarStyle._internal(0); + const AndroidScrollBarStyle._internal(0); ///The scrollbar style to display the scrollbars inside the padded area, increasing the padding of the view. ///The scrollbars will not overlap the content area of the view. static const SCROLLBARS_INSIDE_INSET = - const AndroidScrollBarStyle._internal(16777216); + const AndroidScrollBarStyle._internal(16777216); ///The scrollbar style to display the scrollbars at the edge of the view, without increasing the padding. ///The scrollbars will be overlaid with translucency. static const SCROLLBARS_OUTSIDE_OVERLAY = - const AndroidScrollBarStyle._internal(33554432); + const AndroidScrollBarStyle._internal(33554432); ///The scrollbar style to display the scrollbars at the edge of the view, increasing the padding of the view. ///The scrollbars will only overlap the background, if any. static const SCROLLBARS_OUTSIDE_INSET = - const AndroidScrollBarStyle._internal(50331648); + const AndroidScrollBarStyle._internal(50331648); bool operator ==(value) => value == _value; @@ -3324,9 +3476,15 @@ class AndroidVerticalScrollbarPosition { const AndroidVerticalScrollbarPosition._internal(this._value); + static final Set values = [ + AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT, + AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_LEFT, + AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_RIGHT, + ].toSet(); + static AndroidVerticalScrollbarPosition fromValue(int value) { - if (value != null && value >= 0 && value <= 2) - return AndroidVerticalScrollbarPosition._internal(value); + if (value != null) + return AndroidVerticalScrollbarPosition.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3347,15 +3505,15 @@ class AndroidVerticalScrollbarPosition { ///Position the scroll bar at the default position as determined by the system. static const SCROLLBAR_POSITION_DEFAULT = - const AndroidVerticalScrollbarPosition._internal(0); + const AndroidVerticalScrollbarPosition._internal(0); ///Position the scroll bar along the left edge. static const SCROLLBAR_POSITION_LEFT = - const AndroidVerticalScrollbarPosition._internal(1); + const AndroidVerticalScrollbarPosition._internal(1); ///Position the scroll bar along the right edge. static const SCROLLBAR_POSITION_RIGHT = - const AndroidVerticalScrollbarPosition._internal(2); + const AndroidVerticalScrollbarPosition._internal(2); bool operator ==(value) => value == _value; @@ -3376,7 +3534,7 @@ class AndroidWebViewPackageInfo { static AndroidWebViewPackageInfo fromMap(Map map) { return map != null ? AndroidWebViewPackageInfo( - versionName: map["versionName"], packageName: map["packageName"]) + versionName: map["versionName"], packageName: map["packageName"]) : null; } @@ -3505,13 +3663,15 @@ class WebStorageType { const WebStorageType._internal(this._value); + static final Set values = [ + WebStorageType.LOCAL_STORAGE, + WebStorageType.SESSION_STORAGE, + ].toSet(); + static WebStorageType fromValue(String value) { - return ([ - "localStorage", - "sessionStorage", - ].contains(value)) - ? WebStorageType._internal(value) - : null; + if (value != null) + return WebStorageType.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -3525,7 +3685,7 @@ class WebStorageType { ///`window.sessionStorage`: maintains a separate storage area for each given origin that's available for the duration ///of the page session (as long as the browser is open, including page reloads and restores). static const SESSION_STORAGE = - const WebStorageType._internal("sessionStorage"); + const WebStorageType._internal("sessionStorage"); bool operator ==(value) => value == _value; @@ -3539,14 +3699,16 @@ class HTTPCookieSameSitePolicy { const HTTPCookieSameSitePolicy._internal(this._value); + static final Set values = [ + HTTPCookieSameSitePolicy.LAX, + HTTPCookieSameSitePolicy.STRICT, + HTTPCookieSameSitePolicy.NONE, + ].toSet(); + static HTTPCookieSameSitePolicy fromValue(String value) { - return ([ - "Lax", - "Strict", - "None", - ].contains(value)) - ? HTTPCookieSameSitePolicy._internal(value) - : null; + if (value != null) + return HTTPCookieSameSitePolicy.values.firstWhere((element) => element.toValue() == value, orElse: () => null); + return null; } String toValue() => _value; @@ -3584,9 +3746,18 @@ class AndroidSslError { const AndroidSslError._internal(this._value); + static final Set values = [ + AndroidSslError.SSL_NOTYETVALID, + AndroidSslError.SSL_EXPIRED, + AndroidSslError.SSL_IDMISMATCH, + AndroidSslError.SSL_UNTRUSTED, + AndroidSslError.SSL_DATE_INVALID, + AndroidSslError.SSL_INVALID, + ].toSet(); + static AndroidSslError fromValue(int value) { - if (value != null && value >= 0 && value <= 5) - return AndroidSslError._internal(value); + if (value != null) + return AndroidSslError.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3642,9 +3813,18 @@ class IOSSslError { const IOSSslError._internal(this._value); + static final Set values = [ + IOSSslError.INVALID, + IOSSslError.DENY, + IOSSslError.UNSPECIFIED, + IOSSslError.RECOVERABLE_TRUST_FAILURE, + IOSSslError.FATAL_TRUST_FAILURE, + IOSSslError.OTHER_ERROR, + ].toSet(); + static IOSSslError fromValue(int value) { - if (value != null && [0, 3, 4, 5, 6, 7].contains(value)) - return IOSSslError._internal(value); + if (value != null) + return IOSSslError.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3701,9 +3881,16 @@ class IOSUIScrollViewContentInsetAdjustmentBehavior { const IOSUIScrollViewContentInsetAdjustmentBehavior._internal(this._value); + static final Set values = [ + IOSUIScrollViewContentInsetAdjustmentBehavior.AUTOMATIC, + IOSUIScrollViewContentInsetAdjustmentBehavior.SCROLLABLE_AXES, + IOSUIScrollViewContentInsetAdjustmentBehavior.NEVER, + IOSUIScrollViewContentInsetAdjustmentBehavior.ALWAYS, + ].toSet(); + static IOSUIScrollViewContentInsetAdjustmentBehavior fromValue(int value) { - if (value != null && value >= 0 && value <= 3) - return IOSUIScrollViewContentInsetAdjustmentBehavior._internal(value); + if (value != null) + return IOSUIScrollViewContentInsetAdjustmentBehavior.values.firstWhere((element) => element.toValue() == value, orElse: () => null); return null; } @@ -3725,16 +3912,20 @@ class IOSUIScrollViewContentInsetAdjustmentBehavior { } ///Automatically adjust the scroll view insets. - static const AUTOMATIC = const IOSUIScrollViewContentInsetAdjustmentBehavior._internal(0); + static const AUTOMATIC = const IOSUIScrollViewContentInsetAdjustmentBehavior + ._internal(0); ///Adjust the insets only in the scrollable directions. - static const SCROLLABLE_AXES = const IOSUIScrollViewContentInsetAdjustmentBehavior._internal(1); + static const SCROLLABLE_AXES = const IOSUIScrollViewContentInsetAdjustmentBehavior + ._internal(1); ///Do not adjust the scroll view insets. - static const NEVER = const IOSUIScrollViewContentInsetAdjustmentBehavior._internal(2); + static const NEVER = const IOSUIScrollViewContentInsetAdjustmentBehavior + ._internal(2); ///Always include the safe area insets in the content adjustment. - static const ALWAYS = const IOSUIScrollViewContentInsetAdjustmentBehavior._internal(3); + static const ALWAYS = const IOSUIScrollViewContentInsetAdjustmentBehavior + ._internal(3); bool operator ==(value) => value == _value; @@ -3778,10 +3969,14 @@ class SslCertificate { } return map != null ? SslCertificate( - issuedBy: SslCertificateDName.fromMap(map["issuedBy"]?.cast()), - issuedTo: SslCertificateDName.fromMap(map["issuedTo"]?.cast()), - validNotAfterDate: DateTime.fromMillisecondsSinceEpoch(map["validNotAfterDate"]), - validNotBeforeDate: DateTime.fromMillisecondsSinceEpoch(map["validNotBeforeDate"]), + issuedBy: SslCertificateDName.fromMap( + map["issuedBy"]?.cast()), + issuedTo: SslCertificateDName.fromMap( + map["issuedTo"]?.cast()), + validNotAfterDate: DateTime.fromMillisecondsSinceEpoch( + map["validNotAfterDate"]), + validNotBeforeDate: DateTime.fromMillisecondsSinceEpoch( + map["validNotBeforeDate"]), x509Certificate: x509Certificate, ) : null; } @@ -3811,18 +4006,22 @@ class SslCertificateDName { ///Common-name (CN) component of the name // ignore: non_constant_identifier_names String CName; + ///Distinguished name (normally includes CN, O, and OU names) // ignore: non_constant_identifier_names String DName; + ///Organization (O) component of the name // ignore: non_constant_identifier_names String OName; + ///Organizational Unit (OU) component of the name // ignore: non_constant_identifier_names String UName; - // ignore: non_constant_identifier_names - SslCertificateDName({this.CName = "", this.DName = "", this.OName = "", this.UName = ""}); + SslCertificateDName( + // ignore: non_constant_identifier_names + {this.CName = "", this.DName = "", this.OName = "", this.UName = ""}); static SslCertificateDName fromMap(Map map) { return map != null ? SslCertificateDName( diff --git a/lib/src/webview_options.dart b/lib/src/webview_options.dart index 7998f673..e96fdec4 100755 --- a/lib/src/webview_options.dart +++ b/lib/src/webview_options.dart @@ -301,12 +301,6 @@ class InAppWebViewOptions InAppWebViewOptions copy() { return InAppWebViewOptions.fromMap(this.toMap()); } - - InAppWebViewOptions copyWithValue(InAppWebViewOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return InAppWebViewOptions.fromMap(mergedMap); - } } ///This class represents all the Android-only WebView options available. @@ -709,12 +703,6 @@ class AndroidInAppWebViewOptions AndroidInAppWebViewOptions copy() { return AndroidInAppWebViewOptions.fromMap(this.toMap()); } - - AndroidInAppWebViewOptions copyWithValue(AndroidInAppWebViewOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return AndroidInAppWebViewOptions.fromMap(mergedMap); - } } ///This class represents all the iOS-only WebView options available. @@ -783,7 +771,7 @@ class IOSInAppWebViewOptions ///**NOTE**: available on iOS 13.0+. bool automaticallyAdjustsScrollIndicatorInsets; - ///A Boolean value indicating whether the view ignores an accessibility request to invert its colors. + ///A Boolean value indicating whether the WebView ignores an accessibility request to invert its colors. ///The default value is `false`. /// ///**NOTE**: available on iOS 11.0+. @@ -949,12 +937,6 @@ class IOSInAppWebViewOptions IOSInAppWebViewOptions copy() { return IOSInAppWebViewOptions.fromMap(this.toMap()); } - - IOSInAppWebViewOptions copyWithValue(IOSInAppWebViewOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return IOSInAppWebViewOptions.fromMap(mergedMap); - } } ///This class represents all the cross-platform [InAppBrowser] options available. @@ -1012,12 +994,6 @@ class InAppBrowserOptions InAppBrowserOptions copy() { return InAppBrowserOptions.fromMap(this.toMap()); } - - InAppBrowserOptions copyWithValue(InAppBrowserOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return InAppBrowserOptions.fromMap(mergedMap); - } } ///This class represents all the Android-only [InAppBrowser] options available. @@ -1073,12 +1049,6 @@ class AndroidInAppBrowserOptions implements BrowserOptions, AndroidOptions { AndroidInAppBrowserOptions copy() { return AndroidInAppBrowserOptions.fromMap(this.toMap()); } - - AndroidInAppBrowserOptions copyWithValue(AndroidInAppBrowserOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return AndroidInAppBrowserOptions.fromMap(mergedMap); - } } ///This class represents all the iOS-only [InAppBrowser] options available. @@ -1160,12 +1130,6 @@ class IOSInAppBrowserOptions implements BrowserOptions, IosOptions { IOSInAppBrowserOptions copy() { return IOSInAppBrowserOptions.fromMap(this.toMap()); } - - IOSInAppBrowserOptions copyWithValue(IOSInAppBrowserOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return IOSInAppBrowserOptions.fromMap(mergedMap); - } } ///This class represents all the Android-only [ChromeSafariBrowser] options available. @@ -1245,12 +1209,6 @@ class AndroidChromeCustomTabsOptions AndroidChromeCustomTabsOptions copy() { return AndroidChromeCustomTabsOptions.fromMap(this.toMap()); } - - AndroidChromeCustomTabsOptions copyWithValue(AndroidChromeCustomTabsOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return AndroidChromeCustomTabsOptions.fromMap(mergedMap); - } } ///This class represents all the iOS-only [ChromeSafariBrowser] options available. @@ -1333,10 +1291,4 @@ class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions { IOSSafariOptions copy() { return IOSSafariOptions.fromMap(this.toMap()); } - - IOSSafariOptions copyWithValue(IOSSafariOptions webViewOptions) { - var mergedMap = this.toMap(); - mergedMap.addAll(webViewOptions.toMap()); - return IOSSafariOptions.fromMap(mergedMap); - } } diff --git a/pubspec.yaml b/pubspec.yaml index 218af4d1..538b8947 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,6 @@ dependencies: sdk: flutter uuid: ^2.0.0 mime: ^0.9.6+2 - html: ^0.14.0+3 # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec