diff --git a/CHANGELOG.md b/CHANGELOG.md index 23742fac3..7a3d758ff 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ ## 5.0.0-nullsafety.0 - Added support for Dart null-safety feature -- Updated integration tests - Added Android Hybrid Composition support "Use PlatformViewLink widget for Android WebView" [#462](https://github.com/pichillilorenzo/flutter_inappwebview/pull/462) (thanks to [plateaukao](https://github.com/plateaukao) and [tneotia](https://github.com/tneotia)) +- Added `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options also for iOS (also thanks to [liranhao](https://github.com/liranhao)) +- Updated integration tests - Merge "Upgraded appcompat to 1.2.0-rc-02" [#465](https://github.com/pichillilorenzo/flutter_inappwebview/pull/465) (thanks to [andreidiaconu](https://github.com/andreidiaconu)) - Merge "Added missing field 'headers' which returned by WebResourceResponse.toMap()" [#490](https://github.com/pichillilorenzo/flutter_inappwebview/pull/490) (thanks to [Doflatango](https://github.com/Doflatango)) - Merge "Fix: added iOS fallback module import" [#466](https://github.com/pichillilorenzo/flutter_inappwebview/pull/466) (thanks to [Eddayy](https://github.com/Eddayy)) @@ -16,11 +17,13 @@ - Fixed "Android CookieManager throws error caused by websites that are sending back illegal/invalid cookies." [#476](https://github.com/pichillilorenzo/flutter_inappwebview/issues/476) - Fixed missing `clearHistory` webview method implementation on Android - Fixed iOS crash when using CookieManager getCookies for an URL and the host URL is `null` +- Fixed "IOS does not support allowUniversalAccessFromFileURLs" [#654](https://github.com/pichillilorenzo/flutter_inappwebview/issues/654) ### BREAKING CHANGES - Minimum Flutter version required is `1.22.0` and Dart SDK `>=2.12.0-0 <3.0.0` - Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled +- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options. ## 4.0.0+4 diff --git a/README.md b/README.md index 0e5df6205..95759c91e 100755 --- a/README.md +++ b/README.md @@ -535,111 +535,111 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly: ##### `InAppWebView` Cross-platform options -* `useShouldOverrideUrlLoading`: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`. -* `useOnLoadResource`: Set to `true` to be able to listen at the `onLoadResource` event. The default value is `false`. -* `useOnDownloadStart`: Set to `true` to be able to listen at the `onDownloadStart` event. The default value is `false`. -* `useShouldInterceptAjaxRequest`: Set to `true` to be able to listen at the `shouldInterceptAjaxRequest` event. The default value is `false`. -* `useShouldInterceptFetchRequest`: Set to `true` to be able to listen at the `shouldInterceptFetchRequest` event. The default value is `false`. -* `clearCache`: Set to `true` to have all the browser's cache cleared before the new WebView is opened. The default value is `false`. -* `userAgent`: Sets the user-agent for the WebView. +* `allowFileAccessFromFileURLs`: Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`. +* `allowUniversalAccessFromFileURLs`: Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. The default value is `false`. * `applicationNameForUserAgent`: Append to the existing user-agent. Setting userAgent will override this. -* `javaScriptEnabled`: Set to `true` to enable JavaScript. The default value is `true`. +* `cacheEnabled`: Sets whether WebView should use browser caching. The default value is `true`. +* `clearCache`: Set to `true` to have all the browser's cache cleared before the new WebView is opened. The default value is `false`. +* `contentBlockers`: List of `ContentBlocker` that are a set of rules used to block content in the browser window. +* `disableContextMenu`: Set to `true` to disable context menu. The default value is `false`. +* `disableHorizontalScroll`: Set to `true` to disable horizontal scroll. The default value is `false`. +* `disableVerticalScroll`: Set to `true` to disable vertical scroll. The default value is `false`. +* `horizontalScrollBarEnabled`: Define whether the horizontal scrollbar should be drawn or not. The default value is `true`. +* `incognito`: Set to `true` to open a browser window with incognito mode. The default value is `false`. * `javaScriptCanOpenWindowsAutomatically`: Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`. +* `javaScriptEnabled`: Set to `true` to enable JavaScript. The default value is `true`. * `mediaPlaybackRequiresUserGesture`: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`. * `minimumFontSize`: Sets the minimum font size. The default value is `8` for Android, `0` for iOS. -* `verticalScrollBarEnabled`: Define whether the vertical scrollbar should be drawn or not. The default value is `true`. -* `horizontalScrollBarEnabled`: Define whether the horizontal scrollbar should be drawn or not. The default value is `true`. -* `resourceCustomSchemes`: List of custom schemes that the WebView must handle. Use the `onLoadResourceCustomScheme` event to intercept resource requests with custom scheme. -* `contentBlockers`: List of `ContentBlocker` that are a set of rules used to block content in the browser window. * `preferredContentMode`: Sets the content mode that the WebView needs to use when loading and rendering a webpage. The default value is `InAppWebViewUserPreferredContentMode.RECOMMENDED`. -* `incognito`: Set to `true` to open a browser window with incognito mode. The default value is `false`. -* `cacheEnabled`: Sets whether WebView should use browser caching. The default value is `true`. -* `transparentBackground`: Set to `true` to make the background of the WebView transparent. If your app has a dark theme, this can prevent a white flash on initialization. The default value is `false`. -* `disableVerticalScroll`: Set to `true` to disable vertical scroll. The default value is `false`. -* `disableHorizontalScroll`: Set to `true` to disable horizontal scroll. The default value is `false`. -* `disableContextMenu`: Set to `true` to disable context menu. The default value is `false`. +* `resourceCustomSchemes`: List of custom schemes that the WebView must handle. Use the `onLoadResourceCustomScheme` event to intercept resource requests with custom scheme. * `supportZoom`: Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`. +* `transparentBackground`: Set to `true` to make the background of the WebView transparent. If your app has a dark theme, this can prevent a white flash on initialization. The default value is `false`. +* `useOnDownloadStart`: Set to `true` to be able to listen at the `onDownloadStart` event. The default value is `false`. +* `useOnLoadResource`: Set to `true` to be able to listen at the `onLoadResource` event. The default value is `false`. +* `useShouldInterceptAjaxRequest`: Set to `true` to be able to listen at the `shouldInterceptAjaxRequest` event. The default value is `false`. +* `useShouldInterceptFetchRequest`: Set to `true` to be able to listen at the `shouldInterceptFetchRequest` event. The default value is `false`. +* `useShouldOverrideUrlLoading`: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`. +* `userAgent`: Sets the user-agent for the WebView. +* `verticalScrollBarEnabled`: Define whether the vertical scrollbar should be drawn or not. The default value is `true`. ##### `InAppWebView` Android-specific options -* `useHybridComposition`: Set to `true` to use Flutter's new Hybrid Composition rendering method, which fixes all issues [here](https://github.com/flutter/flutter/issues/61133). The default value is `false`. Note that this option requires Flutter v1.20+ and should only be used on Android 10+ for release apps, as animations will drop frames on < Android 10 (see [Hybrid-Composition#performance](https://github.com/flutter/flutter/wiki/Hybrid-Composition#performance)). -* `useShouldInterceptRequest`: Set to `true` to be able to listen at the `androidShouldInterceptRequest` event. The default value is `false`. -* `useOnRenderProcessGone`: Set to `true` to be able to listen at the `androidOnRenderProcessGone` event. The default value is `false`. -* `textZoom`: Sets the text zoom of the page in percent. The default value is `100`. -* `clearSessionCache`: Set to `true` to have the session cookie cache cleared before the new window is opened. -* `builtInZoomControls`: Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `true`. -* `displayZoomControls`: Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`. -* `databaseEnabled`: Set to `true` if you want the database storage API is enabled. The default value is `true`. -* `domStorageEnabled`: Set to `true` if you want the DOM storage API is enabled. The default value is `true`. -* `useWideViewPort`: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. -* `safeBrowsingEnabled`: Sets whether Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. -* `mixedContentMode`: Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. * `allowContentAccess`: Enables or disables content URL access within WebView. Content URL access allows WebView to load content from a content provider installed in the system. The default value is `true`. * `allowFileAccess`: Enables or disables file access within WebView. Note that this enables or disables file system access only. -* `allowFileAccessFromFileURLs`: Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. -* `allowUniversalAccessFromFileURLs`: Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. * `appCachePath`: Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this option must be set a path to which the application can write. * `blockNetworkImage`: Sets whether the WebView should not load image resources from the network (resources accessed via http and https URI schemes). The default value is `false`. * `blockNetworkLoads`: Sets whether the WebView should not load resources from the network. The default value is `false`. +* `builtInZoomControls`: Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `true`. * `cacheMode`: Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. +* `clearSessionCache`: Set to `true` to have the session cookie cache cleared before the new window is opened. * `cursiveFontFamily`: Sets the cursive font family name. The default value is `"cursive"`. +* `databaseEnabled`: Set to `true` if you want the database storage API is enabled. The default value is `true`. * `defaultFixedFontSize`: Sets the default fixed font size. The default value is `16`. * `defaultFontSize`: Sets the default font size. The default value is `16`. * `defaultTextEncodingName`: Sets the default text encoding name to use when decoding html pages. The default value is `"UTF-8"`. +* `disableDefaultErrorPage`: Sets whether the default Android error page should be disabled. The default value is `false`. * `disabledActionModeMenuItems`: Disables the action mode menu items according to menuItems flag. +* `displayZoomControls`: Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`. +* `domStorageEnabled`: Set to `true` if you want the DOM storage API is enabled. The default value is `true`. * `fantasyFontFamily`: Sets the fantasy font family name. The default value is `"fantasy"`. * `fixedFontFamily`: Sets the fixed font family name. The default value is `"monospace"`. * `forceDark`: Set the force dark mode for this WebView. The default value is `AndroidInAppWebViewForceDark.FORCE_DARK_OFF`. * `geolocationEnabled`: Sets whether Geolocation API is enabled. The default value is `true`. +* `hardwareAcceleration`: Boolean value to enable Hardware Acceleration in the WebView. +* `initialScale`: Sets the initial scale for this WebView. 0 means default. The behavior for the default scale depends on the state of `useWideViewPort` and `loadWithOverviewMode`. * `layoutAlgorithm`: Sets the underlying layout algorithm. This will cause a re-layout of the WebView. * `loadWithOverviewMode`: Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width. * `loadsImagesAutomatically`: Sets whether the WebView should load image resources. Note that this method controls loading of all images, including those embedded using the data URI scheme. * `minimumLogicalFontSize`: Sets the minimum logical font size. The default is `8`. -* `initialScale`: Sets the initial scale for this WebView. 0 means default. The behavior for the default scale depends on the state of `useWideViewPort` and `loadWithOverviewMode`. +* `mixedContentMode`: Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. * `needInitialFocus`: Tells the WebView whether it needs to set a node. The default value is `true`. * `offscreenPreRaster`: Sets whether this WebView should raster tiles when it is offscreen but attached to a window. +* `overScrollMode`: Sets the WebView's over-scroll mode. The default value is `AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS`. +* `regexToCancelSubFramesLoading`: Regular expression used by `shouldOverrideUrlLoading` event to cancel navigation for frames that are not the main frame. If the url request of a subframe matches the regular expression, then the request of that subframe is canceled. +* `rendererPriorityPolicy`: Set the renderer priority policy for this WebView. +* `safeBrowsingEnabled`: Sets whether Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. * `sansSerifFontFamily`: Sets the sans-serif font family name. The default value is `"sans-serif"`. +* `saveFormData`: Sets whether the WebView should save form data. In Android O, the platform has implemented a fully functional Autofill feature to store form data. +* `scrollBarDefaultDelayBeforeFade`: Defines the delay in milliseconds that a scrollbar waits before fade out. +* `scrollBarFadeDuration`: Define the scrollbar fade duration in milliseconds. +* `scrollBarStyle`: Specify the style of the scrollbars. The scrollbars can be overlaid or inset. The default value is `AndroidScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY`. +* `scrollbarFadingEnabled`: Define whether scrollbars will fade when the view is not scrolling. The default value is `true`. * `serifFontFamily`: Sets the serif font family name. The default value is `"sans-serif"`. * `standardFontFamily`: Sets the standard font family name. The default value is `"sans-serif"`. -* `saveFormData`: Sets whether the WebView should save form data. In Android O, the platform has implemented a fully functional Autofill feature to store form data. -* `thirdPartyCookiesEnabled`: Boolean value to enable third party cookies in the WebView. -* `hardwareAcceleration`: Boolean value to enable Hardware Acceleration in the WebView. * `supportMultipleWindows`: Sets whether the WebView whether supports multiple windows. -* `regexToCancelSubFramesLoading`: Regular expression used by `shouldOverrideUrlLoading` event to cancel navigation for frames that are not the main frame. If the url request of a subframe matches the regular expression, then the request of that subframe is canceled. -* `overScrollMode`: Sets the WebView's over-scroll mode. The default value is `AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS`. -* `scrollBarStyle`: Specify the style of the scrollbars. The scrollbars can be overlaid or inset. The default value is `AndroidScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY`. +* `textZoom`: Sets the text zoom of the page in percent. The default value is `100`. +* `thirdPartyCookiesEnabled`: Boolean value to enable third party cookies in the WebView. +* `useHybridComposition`: Set to `true` to use Flutter's new Hybrid Composition rendering method, which fixes all issues [here](https://github.com/flutter/flutter/issues/61133). The default value is `false`. Note that this option requires Flutter v1.20+ and should only be used on Android 10+ for release apps, as animations will drop frames on < Android 10 (see [Hybrid-Composition#performance](https://github.com/flutter/flutter/wiki/Hybrid-Composition#performance)). +* `useOnRenderProcessGone`: Set to `true` to be able to listen at the `androidOnRenderProcessGone` event. The default value is `false`. +* `useShouldInterceptRequest`: Set to `true` to be able to listen at the `androidShouldInterceptRequest` event. The default value is `false`. +* `useWideViewPort`: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. * `verticalScrollbarPosition`: Set the position of the vertical scroll bar. The default value is `AndroidVerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT`. -* `scrollBarDefaultDelayBeforeFade`: Defines the delay in milliseconds that a scrollbar waits before fade out. -* `scrollbarFadingEnabled`: Define whether scrollbars will fade when the view is not scrolling. The default value is `true`. -* `scrollBarFadeDuration`: Define the scrollbar fade duration in milliseconds. -* `rendererPriorityPolicy`: Set the renderer priority policy for this WebView. -* `disableDefaultErrorPage`: Sets whether the default Android error page should be disabled. The default value is `false`. ##### `InAppWebView` iOS-specific options -* `disallowOverScroll`: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`. -* `enableViewportScale`: Set to `true` to allow a viewport meta tag to either disable or restrict the range of user scaling. The default value is `false`. -* `suppressesIncrementalRendering`: Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory. The default value is `false`. +* `accessibilityIgnoresInvertColors`: A Boolean value indicating whether the view ignores an accessibility request to invert its colors. The default value is `false`. * `allowsAirPlayForMediaPlayback`: Set to `true` to allow AirPlay. The default value is `true`. * `allowsBackForwardNavigationGestures`: Set to `true` to allow the horizontal swipe gestures trigger back-forward list navigations. The default value is `true`. -* `allowsLinkPreview`: Set to `true` to allow that pressing on a link displays a preview of the destination for the link. The default value is `true`. -* `ignoresViewportScaleLimits`: Set to `true` if you want that the WebView should always allow scaling of the webpage, regardless of the author's intent. * `allowsInlineMediaPlayback`: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. +* `allowsLinkPreview`: Set to `true` to allow that pressing on a link displays a preview of the destination for the link. The default value is `true`. * `allowsPictureInPictureMediaPlayback`: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`. -* `isFraudulentWebsiteWarningEnabled`: A Boolean value indicating whether warnings should be shown for suspected fraudulent content such as phishing or malware. -* `selectionGranularity`: The level of granularity with which the user can interactively select content in the web view. -* `dataDetectorTypes`: Specifying a dataDetectoryTypes value adds interactivity to web content that matches the value. -* `sharedCookiesEnabled`: Set `true` if shared cookies from `HTTPCookieStorage.shared` should used for every load request in the WebView. +* `alwaysBounceHorizontal`: A Boolean value that determines whether bouncing always occurs when horizontal scrolling reaches the end of the content view. The default value is `false`. +* `alwaysBounceVertical`: A Boolean value that determines whether bouncing always occurs when vertical scrolling reaches the end of the content. The default value is `false`. * `automaticallyAdjustsScrollIndicatorInsets`: Configures whether the scroll indicator insets are automatically adjusted by the system. The default value is `false`. -* `accessibilityIgnoresInvertColors`: A Boolean value indicating whether the view ignores an accessibility request to invert its colors. The default value is `false`. +* `contentInsetAdjustmentBehavior`: Configures how safe area insets are added to the adjusted content inset. The default value is `IOSUIScrollViewContentInsetAdjustmentBehavior.NEVER`. +* `dataDetectorTypes`: Specifying a dataDetectoryTypes value adds interactivity to web content that matches the value. * `decelerationRate`: A `IOSUIScrollViewDecelerationRate` value that determines the rate of deceleration after the user lifts their finger. The default value is `IOSUIScrollViewDecelerationRate.NORMAL`. -* `alwaysBounceVertical`: A Boolean value that determines whether bouncing always occurs when vertical scrolling reaches the end of the content. The default value is `false`. -* `alwaysBounceHorizontal`: A Boolean value that determines whether bouncing always occurs when horizontal scrolling reaches the end of the content view. The default value is `false`. -* `scrollsToTop`: A Boolean value that controls whether the scroll-to-top gesture is enabled. The default value is `true`. +* `disallowOverScroll`: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`. +* `enableViewportScale`: Set to `true` to allow a viewport meta tag to either disable or restrict the range of user scaling. The default value is `false`. +* `ignoresViewportScaleLimits`: Set to `true` if you want that the WebView should always allow scaling of the webpage, regardless of the author's intent. +* `isFraudulentWebsiteWarningEnabled`: A Boolean value indicating whether warnings should be shown for suspected fraudulent content such as phishing or malware. * `isPagingEnabled`: A Boolean value that determines whether paging is enabled for the scroll view. The default value is `false`. * `maximumZoomScale`: A floating-point value that specifies the maximum scale factor that can be applied to the scroll view's content. The default value is `1.0`. * `minimumZoomScale`: A floating-point value that specifies the minimum scale factor that can be applied to the scroll view's content. The default value is `1.0`. -* `contentInsetAdjustmentBehavior`: Configures how safe area insets are added to the adjusted content inset. The default value is `IOSUIScrollViewContentInsetAdjustmentBehavior.NEVER`. +* `scrollsToTop`: A Boolean value that controls whether the scroll-to-top gesture is enabled. The default value is `true`. +* `selectionGranularity`: The level of granularity with which the user can interactively select content in the web view. +* `sharedCookiesEnabled`: Set `true` if shared cookies from `HTTPCookieStorage.shared` should used for every load request in the WebView. +* `suppressesIncrementalRendering`: Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory. The default value is `false`. #### `InAppWebView` Events @@ -1130,27 +1130,27 @@ Specific options of the `InAppBrowser` class are: ##### `InAppBrowser` Cross-platform options * `hidden`: Set to `true` to create the browser and load the page, but not show it. Omit or set to `false` to have the browser open and load normally. The default value is `false`. -* `toolbarTop`: Set to `false` to hide the toolbar at the top of the WebView. The default value is `true`. -* `toolbarTopBackgroundColor`: Set the custom background color of the toolbar at the top. * `hideUrlBar`: Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`. +* `toolbarTopBackgroundColor`: Set the custom background color of the toolbar at the top. +* `toolbarTop`: Set to `false` to hide the toolbar at the top of the WebView. The default value is `true`. ##### `InAppBrowser` Android-specific options -* `hideTitleBar`: Set to `true` if you want the title should be displayed. The default value is `false`. -* `toolbarTopFixedTitle`: Set the action bar's title. * `closeOnCannotGoBack`: Set to `false` to not close the InAppBrowser when the user click on the back button and the WebView cannot go back to the history. The default value is `true`. +* `hideTitleBar`: Set to `true` if you want the title should be displayed. The default value is `false`. * `progressBar`: Set to `false` to hide the progress bar at the bottom of the toolbar at the top. The default value is `true`. +* `toolbarTopFixedTitle`: Set the action bar's title. ##### `InAppBrowser` iOS-specific options -* `toolbarBottom`: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`. -* `toolbarBottomBackgroundColor`: Set the custom background color of the toolbar at the bottom. -* `toolbarBottomTranslucent`: Set to `true` to set the toolbar at the bottom translucent. The default value is `true`. * `closeButtonCaption`: Set the custom text for the close button. * `closeButtonColor`: Set the custom color for the close button. * `presentationStyle`: Set the custom modal presentation style when presenting the WebView. The default value is `IOSUIModalPresentationStyle.FULL_SCREEN`. -* `transitionStyle`: Set to the custom transition style when presenting the WebView. The default value is `IOSUIModalTransitionStyle.COVER_VERTICAL`. * `spinner`: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`. +* `toolbarBottomBackgroundColor`: Set the custom background color of the toolbar at the bottom. +* `toolbarBottomTranslucent`: Set to `true` to set the toolbar at the bottom translucent. The default value is `true`. +* `toolbarBottom`: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`. +* `transitionStyle`: Set to the custom transition style when presenting the WebView. The default value is `IOSUIModalTransitionStyle.COVER_VERTICAL`. #### `InAppBrowser` Events @@ -1284,11 +1284,11 @@ Screenshots: #### `ChromeSafariBrowser` Methods -* `open({@required String url, ChromeSafariBrowserClassOptions options, Map headersFallback = const {}, InAppBrowserClassOptions optionsFallback})`: Opens an `url` in a new `ChromeSafariBrowser` instance. -* `isOpened`: Returns `true` if the `ChromeSafariBrowser` instance is opened, otherwise `false`. -* `close`: Closes the `ChromeSafariBrowser` instance. * `addMenuItem`: Adds a `ChromeSafariBrowserMenuItem` to the menu. * `addMenuItems`: Adds a list of `ChromeSafariBrowserMenuItem` to the menu. +* `close`: Closes the `ChromeSafariBrowser` instance. +* `isOpened`: Returns `true` if the `ChromeSafariBrowser` instance is opened, otherwise `false`. +* `open({@required String url, ChromeSafariBrowserClassOptions options, Map headersFallback = const {}, InAppBrowserClassOptions optionsFallback})`: Opens an `url` in a new `ChromeSafariBrowser` instance. * `static isAvailable`: On Android, returns `true` if Chrome Custom Tabs is available. On iOS, returns `true` if SFSafariViewController is available. Otherwise returns `false`. #### `ChromeSafariBrowser` options @@ -1296,18 +1296,18 @@ Screenshots: ##### `ChromeSafariBrowser` Android-specific options * `addDefaultShareMenuItem`: Set to `false` if you don't want the default share item to the menu. The default value is `true`. -* `showTitle`: Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`. -* `toolbarBackgroundColor`: Set the custom background color of the toolbar. * `enableUrlBarHiding`: Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`. * `instantAppsEnabled`: Set to `true` to enable Instant Apps. The default value is `false`. -* `packageName`: Set the name of the application package to handle the intent (for example `com.android.chrome`), or null to allow any application package. * `keepAliveEnabled`: Set to `true` to enable Keep Alive. The default value is `false`. +* `packageName`: Set the name of the application package to handle the intent (for example `com.android.chrome`), or null to allow any application package. +* `showTitle`: Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`. +* `toolbarBackgroundColor`: Set the custom background color of the toolbar. ##### `ChromeSafariBrowser` iOS-specific options -* `entersReaderIfAvailable`: Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`. * `barCollapsingEnabled`: Set to `true` to enable bar collapsing. The default value is `false`. * `dismissButtonStyle`: Set the custom style for the dismiss button. The default value is `IOSSafariDismissButtonStyle.DONE`. +* `entersReaderIfAvailable`: Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`. * `preferredBarTintColor`: Set the custom background color of the navigation bar and the toolbar. * `preferredControlTintColor`: Set the custom color of the control buttons on the navigation bar and the toolbar. * `presentationStyle`: Set the custom modal presentation style when presenting the WebView. The default value is `IOSUIModalPresentationStyle.FULL_SCREEN`. diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java index e3bb4fde4..96ad6ffc0 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java @@ -43,6 +43,8 @@ public class InAppWebViewOptions implements Options { public Boolean disableHorizontalScroll = false; public Boolean disableContextMenu = false; public Boolean supportZoom = true; + public Boolean allowFileAccessFromFileURLs = false; + public Boolean allowUniversalAccessFromFileURLs = false; public Integer textZoom = 100; public Boolean clearSessionCache = false; @@ -55,8 +57,6 @@ public class InAppWebViewOptions implements Options { public Integer mixedContentMode; public Boolean allowContentAccess = true; public Boolean allowFileAccess = true; - public Boolean allowFileAccessFromFileURLs = true; - public Boolean allowUniversalAccessFromFileURLs = true; public String appCachePath; public Boolean blockNetworkImage = false; public Boolean blockNetworkLoads = false; diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 9cebde9e3..5bf438dd3 100644 --- a/example/.flutter-plugins-dependencies +++ b/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-01-28 16:30:24.941683","version":"1.26.0-13.0.pre.194"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-01-28 18:33:22.830881","version":"1.26.0-13.0.pre.194"} \ No newline at end of file diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index 1d1cd30c8..787afaf66 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -2,13 +2,12 @@ # 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 "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" -export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue,FLUTTER_WEB_AUTO_DETECT%3Dtrue" export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=true" -export "TREE_SHAKE_ICONS=false" +export "TRACK_WIDGET_CREATION=false" +export "TREE_SHAKE_ICONS=true" export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json" diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 2f4349b06..138493f9c 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -85,7 +85,7 @@ class _InAppWebViewExampleScreenState extends State { initialHeaders: {}, initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( - useShouldOverrideUrlLoading: false + useShouldOverrideUrlLoading: false, ), android: AndroidInAppWebViewOptions( useHybridComposition: true @@ -125,6 +125,7 @@ class _InAppWebViewExampleScreenState extends State { setState(() { this.url = url ?? ''; }); + print(await controller.getOptions()); }, onProgressChanged: (controller, progress) { setState(() { diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift index 1240aa22d..74729bd22 100755 --- a/ios/Classes/InAppWebView.swift +++ b/ios/Classes/InAppWebView.swift @@ -1352,6 +1352,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi configuration.suppressesIncrementalRendering = options.suppressesIncrementalRendering configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: options.selectionGranularity)! + if options.allowUniversalAccessFromFileURLs { + configuration.setValue(options.allowUniversalAccessFromFileURLs, forKey: "allowUniversalAccessFromFileURLs") + } + + if options.allowFileAccessFromFileURLs { + configuration.preferences.setValue(options.allowFileAccessFromFileURLs, forKey: "allowFileAccessFromFileURLs") + } + if #available(iOS 9.0, *) { if options.incognito { configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent() @@ -1748,6 +1756,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi } } + if newOptionsMap["allowUniversalAccessFromFileURLs"] != nil && options?.allowUniversalAccessFromFileURLs != newOptions.allowUniversalAccessFromFileURLs { + configuration.setValue(newOptions.allowUniversalAccessFromFileURLs, forKey: "allowUniversalAccessFromFileURLs") + } + + if newOptionsMap["allowFileAccessFromFileURLs"] != nil && options?.allowFileAccessFromFileURLs != newOptions.allowFileAccessFromFileURLs { + configuration.preferences.setValue(newOptions.allowFileAccessFromFileURLs, forKey: "allowFileAccessFromFileURLs") + } + if newOptionsMap["clearCache"] != nil && newOptions.clearCache { clearCache() } diff --git a/ios/Classes/InAppWebViewOptions.swift b/ios/Classes/InAppWebViewOptions.swift index 0e33e74a5..772e00780 100755 --- a/ios/Classes/InAppWebViewOptions.swift +++ b/ios/Classes/InAppWebViewOptions.swift @@ -34,6 +34,8 @@ public class InAppWebViewOptions: Options { var disableHorizontalScroll = false var disableContextMenu = false var supportZoom = true + var allowUniversalAccessFromFileURLs = false + var allowFileAccessFromFileURLs = false var disallowOverScroll = false var enableViewportScale = false @@ -105,6 +107,8 @@ public class InAppWebViewOptions: Options { realOptions["isPagingEnabled"] = webView.scrollView.isPagingEnabled realOptions["maximumZoomScale"] = webView.scrollView.maximumZoomScale realOptions["minimumZoomScale"] = webView.scrollView.minimumZoomScale + realOptions["allowUniversalAccessFromFileURLs"] = configuration.value(forKey: "allowUniversalAccessFromFileURLs") + realOptions["allowFileAccessFromFileURLs"] = configuration.preferences.value(forKey: "allowFileAccessFromFileURLs") } return realOptions } diff --git a/lib/src/webview_options.dart b/lib/src/webview_options.dart index 3a6160f47..b2596920b 100755 --- a/lib/src/webview_options.dart +++ b/lib/src/webview_options.dart @@ -170,6 +170,28 @@ class InAppWebViewOptions ///Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`. bool supportZoom; + ///Sets whether cross-origin requests in the context of a file scheme URL should be allowed to access content from other file scheme URLs. + ///Note that some accesses such as image HTML elements don't follow same-origin rules and aren't affected by this setting. + /// + ///Don't enable this setting if you open files that may be created or altered by external sources. + ///Enabling this setting allows malicious scripts loaded in a `file://` context to access arbitrary local files including WebView cookies and app private data. + /// + ///Note that the value of this setting is ignored if the value of [allowUniversalAccessFromFileURLs] is `true`. + /// + ///The default value is `false`. + bool allowFileAccessFromFileURLs; + + ///Sets whether cross-origin requests in the context of a file scheme URL should be allowed to access content from any origin. + ///This includes access to content from other file scheme URLs or web contexts. + ///Note that some access such as image HTML elements doesn't follow same-origin rules and isn't affected by this setting. + /// + ///Don't enable this setting if you open files that may be created or altered by external sources. + ///Enabling this setting allows malicious scripts loaded in a `file://` context to launch cross-site scripting attacks, + ///either accessing arbitrary local files including WebView cookies, app private data or even credentials used on arbitrary web sites. + /// + ///The default value is `false`. + bool allowUniversalAccessFromFileURLs; + InAppWebViewOptions( {this.useShouldOverrideUrlLoading = false, this.useOnLoadResource = false, @@ -194,7 +216,9 @@ class InAppWebViewOptions this.disableVerticalScroll = false, this.disableHorizontalScroll = false, this.disableContextMenu = false, - this.supportZoom = true}) { + this.supportZoom = true, + this.allowFileAccessFromFileURLs = false, + this.allowUniversalAccessFromFileURLs = false}) { if (this.minimumFontSize == null) this.minimumFontSize = defaultTargetPlatform == TargetPlatform.android ? 8 : 0; assert(!this.resourceCustomSchemes.contains("http") && @@ -232,7 +256,9 @@ class InAppWebViewOptions "disableVerticalScroll": disableVerticalScroll, "disableHorizontalScroll": disableHorizontalScroll, "disableContextMenu": disableContextMenu, - "supportZoom": supportZoom + "supportZoom": supportZoom, + "allowFileAccessFromFileURLs": allowFileAccessFromFileURLs, + "allowUniversalAccessFromFileURLs": allowUniversalAccessFromFileURLs }; } @@ -277,6 +303,8 @@ class InAppWebViewOptions options.disableHorizontalScroll = map["disableHorizontalScroll"]; options.disableContextMenu = map["disableContextMenu"]; options.supportZoom = map["supportZoom"]; + options.allowFileAccessFromFileURLs = map["allowFileAccessFromFileURLs"]; + options.allowUniversalAccessFromFileURLs = map["allowUniversalAccessFromFileURLs"]; return options; } @@ -338,19 +366,9 @@ class AndroidInAppWebViewOptions bool allowContentAccess; ///Enables or disables file access within WebView. Note that this enables or disables file system access only. - ///Assets and resources are still accessible using \file:///android_asset` and `file:///android_res`. The default value is `true`. + ///Assets and resources are still accessible using `file:///android_asset` and `file:///android_res`. The default value is `true`. bool allowFileAccess; - ///Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. - ///Note that the value of this setting is ignored if the value of [allowFileAccessFromFileURLs] is `true`. - ///Note too, that this setting affects only JavaScript access to file scheme resources. The default value is `false`. - bool allowFileAccessFromFileURLs; - - ///Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. - ///Note that this setting affects only JavaScript access to file scheme resources. - ///This includes access to content from other file scheme URLs. The default value is `false`. - bool allowUniversalAccessFromFileURLs; - ///Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this option must be set a path to which the application can write. ///This option is used one time: repeated calls are ignored. String? appCachePath; @@ -526,8 +544,6 @@ class AndroidInAppWebViewOptions this.mixedContentMode, this.allowContentAccess = true, this.allowFileAccess = true, - this.allowFileAccessFromFileURLs = false, - this.allowUniversalAccessFromFileURLs = false, this.appCachePath, this.blockNetworkImage = false, this.blockNetworkLoads = false, @@ -585,8 +601,6 @@ class AndroidInAppWebViewOptions "mixedContentMode": mixedContentMode?.toValue(), "allowContentAccess": allowContentAccess, "allowFileAccess": allowFileAccess, - "allowFileAccessFromFileURLs": allowFileAccessFromFileURLs, - "allowUniversalAccessFromFileURLs": allowUniversalAccessFromFileURLs, "appCachePath": appCachePath, "blockNetworkImage": blockNetworkImage, "blockNetworkLoads": blockNetworkLoads, @@ -644,9 +658,6 @@ class AndroidInAppWebViewOptions AndroidMixedContentMode.fromValue(map["mixedContentMode"]); options.allowContentAccess = map["allowContentAccess"]; options.allowFileAccess = map["allowFileAccess"]; - options.allowFileAccessFromFileURLs = map["allowFileAccessFromFileURLs"]; - options.allowUniversalAccessFromFileURLs = - map["allowUniversalAccessFromFileURLs"]; options.appCachePath = map["appCachePath"]; options.blockNetworkImage = map["blockNetworkImage"]; options.blockNetworkLoads = map["blockNetworkLoads"];