Added scriptHtmlTagAttributes optional argument to injectJavascriptFileFromUrl WebView method, Added cssLinkHtmlTagAttributes optional argument to injectCSSFileFromUrl WebView method
This commit is contained in:
parent
bbb2af8275
commit
0e4e16562d
|
@ -13,6 +13,8 @@
|
||||||
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
|
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
|
||||||
- Added `iosAnimated` optional argument to `zoomBy` WebView method
|
- Added `iosAnimated` optional argument to `zoomBy` WebView method
|
||||||
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
|
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
|
||||||
|
- Added `scriptHtmlTagAttributes` optional argument to `injectJavascriptFileFromUrl` WebView method
|
||||||
|
- Added `cssLinkHtmlTagAttributes` optional argument to `injectCSSFileFromUrl` WebView method
|
||||||
- Updated integration tests
|
- 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 "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 "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))
|
||||||
|
@ -38,7 +40,7 @@
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
- Minimum Flutter version required is `1.22.0` and Dart SDK `>=2.12.0-0 <3.0.0`
|
- Minimum Flutter version required is `1.22.2` and Dart SDK `>=2.12.0-0 <3.0.0`
|
||||||
- iOS Xcode version `>= 12`
|
- iOS Xcode version `>= 12`
|
||||||
- Removed `debuggingEnabled` WebView option; on Android you should use now the `AndroidInAppWebViewController.setWebContentsDebuggingEnabled(bool debuggingEnabled)` static method; on iOS, debugging is always enabled
|
- 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
|
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
|
||||||
|
|
11
README.md
11
README.md
|
@ -1,7 +1,10 @@
|
||||||
# Flutter InAppWebView Plugin [![Share on Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Flutter%20InAppBrowser%20plugin!&url=https://github.com/pichillilorenzo/flutter_inappwebview&hashtags=flutter,flutterio,dart,dartlang,webview) [![Share on Facebook](https://img.shields.io/badge/share-facebook-blue.svg?longCache=true&style=flat&colorB=%234267b2)](https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/pichillilorenzo/flutter_inappwebview)
|
# Flutter InAppWebView Plugin [![Share on Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Flutter%20InAppBrowser%20plugin!&url=https://github.com/pichillilorenzo/flutter_inappwebview&hashtags=flutter,flutterio,dart,dartlang,webview) [![Share on Facebook](https://img.shields.io/badge/share-facebook-blue.svg?longCache=true&style=flat&colorB=%234267b2)](https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/pichillilorenzo/flutter_inappwebview)
|
||||||
|
|
||||||
[![Pub](https://img.shields.io/pub/v/flutter_inappwebview.svg)](https://pub.dartlang.org/packages/flutter_inappwebview)
|
[![Pub](https://img.shields.io/pub/v/flutter_inappwebview.svg)](https://pub.dartlang.org/packages/flutter_inappwebview)
|
||||||
[![Awesome Flutter](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://stackoverflow.com/questions/tagged/flutter+webview?sort=votes)
|
[![pub points](https://badges.bar/flutter_inappwebview/pub%20points)](https://pub.dev/packages/flutter_inappwebview/score)
|
||||||
|
[![popularity](https://badges.bar/flutter_inappwebview/popularity)](https://pub.dev/packages/flutter_inappwebview/score)
|
||||||
|
[![likes](https://badges.bar/flutter_inappwebview/likes)](https://pub.dev/packages/flutter_inappwebview/score)
|
||||||
|
[![Awesome Flutter](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://stackoverflow.com/questions/tagged/flutter-inappwebview)
|
||||||
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](/LICENSE)
|
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](/LICENSE)
|
||||||
|
|
||||||
[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/LorenzoPichilli)
|
[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/LorenzoPichilli)
|
||||||
|
@ -22,6 +25,8 @@ Note that the API shown in this `README.md` file shows only a **part** of the do
|
||||||
So, here you could have methods, options, and events that **aren't published/released yet**!
|
So, here you could have methods, options, and events that **aren't published/released yet**!
|
||||||
If you need a specific version, please change the **GitHub branch** of this repository to your version or use the **online [API Reference](https://pub.dartlang.org/documentation/flutter_inappwebview/latest/)** (recommended).
|
If you need a specific version, please change the **GitHub branch** of this repository to your version or use the **online [API Reference](https://pub.dartlang.org/documentation/flutter_inappwebview/latest/)** (recommended).
|
||||||
|
|
||||||
|
Also, check the [example/integration_test/webview_flutter_test.dart](https://github.com/pichillilorenzo/flutter_inappwebview/blob/master/example/integration_test/webview_flutter_test.dart) file for code examples.
|
||||||
|
|
||||||
## Articles/Resources
|
## Articles/Resources
|
||||||
|
|
||||||
- [InAppWebView: The Real Power of WebViews in Flutter](https://medium.com/flutter-community/inappwebview-the-real-power-of-webviews-in-flutter-c6d52374209d?source=friends_link&sk=cb74487219bcd85e610a670ee0b447d0)
|
- [InAppWebView: The Real Power of WebViews in Flutter](https://medium.com/flutter-community/inappwebview-the-real-power-of-webviews-in-flutter-c6d52374209d?source=friends_link&sk=cb74487219bcd85e610a670ee0b447d0)
|
||||||
|
@ -426,9 +431,9 @@ Screenshots:
|
||||||
* `goTo({required WebHistoryItem historyItem})`: Navigates to a `WebHistoryItem` from the back-forward `WebHistory.list` and sets it as the current item.
|
* `goTo({required WebHistoryItem historyItem})`: Navigates to a `WebHistoryItem` from the back-forward `WebHistory.list` and sets it as the current item.
|
||||||
* `injectCSSCode({required String source})`: Injects CSS into the WebView.
|
* `injectCSSCode({required String source})`: Injects CSS into the WebView.
|
||||||
* `injectCSSFileFromAsset({required String assetFilePath})`: Injects a CSS file into the WebView from the flutter assets directory.
|
* `injectCSSFileFromAsset({required String assetFilePath})`: Injects a CSS file into the WebView from the flutter assets directory.
|
||||||
* `injectCSSFileFromUrl({required String urlFile})`: Injects an external CSS file into the WebView from a defined url.
|
* `injectCSSFileFromUrl({required String urlFile, CSSLinkHtmlTagAttributes? cssLinkHtmlTagAttributes})`: Injects an external CSS file into the WebView from a defined url.
|
||||||
* `injectJavascriptFileFromAsset({required String assetFilePath})`: Injects a JavaScript file into the WebView from the flutter assets directory.
|
* `injectJavascriptFileFromAsset({required String assetFilePath})`: Injects a JavaScript file into the WebView from the flutter assets directory.
|
||||||
* `injectJavascriptFileFromUrl({required String urlFile})`: Injects an external JavaScript file into the WebView from a defined url.
|
* `injectJavascriptFileFromUrl({required String urlFile, ScriptHtmlTagAttributes? scriptHtmlTagAttributes})`: Injects an external JavaScript file into the WebView from a defined url.
|
||||||
* `isLoading`: Check if the WebView instance is in a loading state.
|
* `isLoading`: Check if the WebView instance is in a loading state.
|
||||||
* `loadData({required String data, String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", String androidHistoryUrl = "about:blank"})`: Loads the given data into this WebView.
|
* `loadData({required String data, String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", String androidHistoryUrl = "about:blank"})`: Loads the given data into this WebView.
|
||||||
* `loadFile({required String assetFilePath, Map<String, String> headers = const {}})`: Loads the given `assetFilePath` with optional headers specified as a map from name to value.
|
* `loadFile({required String assetFilePath, Map<String, String> headers = const {}})`: Loads the given `assetFilePath` with optional headers specified as a map from name to value.
|
||||||
|
|
|
@ -1523,7 +1523,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
return (options != null) ? options.getRealOptions(this) : null;
|
return (options != null) ? options.getRealOptions(this) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectDeferredObject(String source, @Nullable final String contentWorldName, String jsWrapper, final MethodChannel.Result result) {
|
public void injectDeferredObject(String source, @Nullable final String contentWorldName, String jsWrapper, @Nullable final MethodChannel.Result result) {
|
||||||
String scriptToInject = source;
|
String scriptToInject = source;
|
||||||
if (jsWrapper != null) {
|
if (jsWrapper != null) {
|
||||||
org.json.JSONArray jsonEsc = new org.json.JSONArray();
|
org.json.JSONArray jsonEsc = new org.json.JSONArray();
|
||||||
|
@ -1577,18 +1577,95 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
injectDeferredObject(source, contentWorldName, null, result);
|
injectDeferredObject(source, contentWorldName, null, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectJavascriptFileFromUrl(String urlFile) {
|
public void injectJavascriptFileFromUrl(String urlFile, @Nullable Map<String, Object> scriptHtmlTagAttributes) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
|
String scriptAttributes = "";
|
||||||
|
if (scriptHtmlTagAttributes != null) {
|
||||||
|
String typeAttr = (String) scriptHtmlTagAttributes.get("type");
|
||||||
|
if (typeAttr != null) {
|
||||||
|
scriptAttributes += " script.type = '" + typeAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String idAttr = (String) scriptHtmlTagAttributes.get("id");
|
||||||
|
if (idAttr != null) {
|
||||||
|
scriptAttributes += " script.id = '" + idAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
Boolean asyncAttr = (Boolean) scriptHtmlTagAttributes.get("async");
|
||||||
|
if (asyncAttr != null && asyncAttr) {
|
||||||
|
scriptAttributes += " script.async = true; ";
|
||||||
|
}
|
||||||
|
Boolean deferAttr = (Boolean) scriptHtmlTagAttributes.get("defer");
|
||||||
|
if (deferAttr != null && deferAttr) {
|
||||||
|
scriptAttributes += " script.defer = true; ";
|
||||||
|
}
|
||||||
|
String crossOriginAttr = (String) scriptHtmlTagAttributes.get("crossOrigin");
|
||||||
|
if (crossOriginAttr != null) {
|
||||||
|
scriptAttributes += " script.crossOrigin = '" + crossOriginAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String integrityAttr = (String) scriptHtmlTagAttributes.get("integrity");
|
||||||
|
if (integrityAttr != null) {
|
||||||
|
scriptAttributes += " script.integrity = '" + integrityAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
Boolean noModuleAttr = (Boolean) scriptHtmlTagAttributes.get("noModule");
|
||||||
|
if (noModuleAttr != null && noModuleAttr) {
|
||||||
|
scriptAttributes += " script.noModule = true; ";
|
||||||
|
}
|
||||||
|
String nonceAttr = (String) scriptHtmlTagAttributes.get("nonce");
|
||||||
|
if (nonceAttr != null) {
|
||||||
|
scriptAttributes += " script.nonce = '" + nonceAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String referrerPolicyAttr = (String) scriptHtmlTagAttributes.get("referrerPolicy");
|
||||||
|
if (referrerPolicyAttr != null) {
|
||||||
|
scriptAttributes += " script.referrerPolicy = '" + referrerPolicyAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String jsWrapper = "(function(d) { var script = d.createElement('script'); " + scriptAttributes +
|
||||||
|
" script.src = %s; d.body.appendChild(script); })(document);";
|
||||||
injectDeferredObject(urlFile, null, jsWrapper, null);
|
injectDeferredObject(urlFile, null, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectCSSCode(String source) {
|
public void injectCSSCode(String source) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document);";
|
String jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %s; d.body.appendChild(style); })(document);";
|
||||||
injectDeferredObject(source, null, jsWrapper, null);
|
injectDeferredObject(source, null, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectCSSFileFromUrl(String urlFile) {
|
public void injectCSSFileFromUrl(String urlFile, @Nullable Map<String, Object> cssLinkHtmlTagAttributes) {
|
||||||
String jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
|
String cssLinkAttributes = "";
|
||||||
|
String alternateStylesheet = "";
|
||||||
|
if (cssLinkHtmlTagAttributes != null) {
|
||||||
|
String idAttr = (String) cssLinkHtmlTagAttributes.get("id");
|
||||||
|
if (idAttr != null) {
|
||||||
|
cssLinkAttributes += " link.id = '" + idAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String mediaAttr = (String) cssLinkHtmlTagAttributes.get("media");
|
||||||
|
if (mediaAttr != null) {
|
||||||
|
cssLinkAttributes += " link.media = '" + mediaAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String crossOriginAttr = (String) cssLinkHtmlTagAttributes.get("crossOrigin");
|
||||||
|
if (crossOriginAttr != null) {
|
||||||
|
cssLinkAttributes += " link.crossOrigin = '" + crossOriginAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String integrityAttr = (String) cssLinkHtmlTagAttributes.get("integrity");
|
||||||
|
if (integrityAttr != null) {
|
||||||
|
cssLinkAttributes += " link.integrity = '" + integrityAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
String referrerPolicyAttr = (String) cssLinkHtmlTagAttributes.get("referrerPolicy");
|
||||||
|
if (referrerPolicyAttr != null) {
|
||||||
|
cssLinkAttributes += " link.referrerPolicy = '" + referrerPolicyAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
Boolean disabledAttr = (Boolean) cssLinkHtmlTagAttributes.get("disabled");
|
||||||
|
if (disabledAttr != null && disabledAttr) {
|
||||||
|
cssLinkAttributes += " link.disabled = true; ";
|
||||||
|
}
|
||||||
|
Boolean alternateAttr = (Boolean) cssLinkHtmlTagAttributes.get("alternate");
|
||||||
|
if (alternateAttr != null && alternateAttr) {
|
||||||
|
alternateStylesheet = "alternate ";
|
||||||
|
}
|
||||||
|
String titleAttr = (String) cssLinkHtmlTagAttributes.get("title");
|
||||||
|
if (titleAttr != null) {
|
||||||
|
cssLinkAttributes += " link.title = '" + titleAttr.replaceAll("'", "\\\\'") + "'; ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String jsWrapper = "(function(d) { var link = d.createElement('link'); link.rel='" + alternateStylesheet + "stylesheet'; link.type='text/css'; " +
|
||||||
|
cssLinkAttributes + " link.href = %s; d.head.appendChild(link); })(document);";
|
||||||
injectDeferredObject(urlFile, null, jsWrapper, null);
|
injectDeferredObject(urlFile, null, jsWrapper, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||||
case "injectJavascriptFileFromUrl":
|
case "injectJavascriptFileFromUrl":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String urlFile = (String) call.argument("urlFile");
|
String urlFile = (String) call.argument("urlFile");
|
||||||
webView.injectJavascriptFileFromUrl(urlFile);
|
Map<String, Object> scriptHtmlTagAttributes = (Map<String, Object>) call.argument("scriptHtmlTagAttributes");
|
||||||
|
webView.injectJavascriptFileFromUrl(urlFile, scriptHtmlTagAttributes);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
|
@ -98,7 +99,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||||
case "injectCSSFileFromUrl":
|
case "injectCSSFileFromUrl":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String urlFile = (String) call.argument("urlFile");
|
String urlFile = (String) call.argument("urlFile");
|
||||||
webView.injectCSSFileFromUrl(urlFile);
|
Map<String, Object> cssLinkHtmlTagAttributes = (Map<String, Object>) call.argument("cssLinkHtmlTagAttributes");
|
||||||
|
webView.injectCSSFileFromUrl(urlFile, cssLinkHtmlTagAttributes);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"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":["device_info"]},{"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":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"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":["device_info"]},{"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":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"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-02-09 01:23:18.308862","version":"1.26.0-18.0.pre.90"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"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":["device_info"]},{"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":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"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":["device_info"]},{"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":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"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-02-09 21:00:13.907504","version":"1.26.0-18.0.pre.90"}
|
|
@ -115,6 +115,9 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
this.url = url ?? '';
|
this.url = url ?? '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
androidOnPermissionRequest: (InAppWebViewController controller, String origin, List<String> resources) async {
|
||||||
|
return PermissionRequestResponse(resources: resources, action: PermissionRequestResponseAction.GRANT);
|
||||||
|
},
|
||||||
shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
|
shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
|
||||||
var url = shouldOverrideUrlLoadingRequest.url;
|
var url = shouldOverrideUrlLoadingRequest.url;
|
||||||
var uri = Uri.parse(url);
|
var uri = Uri.parse(url);
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/device_info/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_downloader/build" />
|
||||||
|
|
|
@ -2303,18 +2303,76 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectJavascriptFileFromUrl(urlFile: String) {
|
public func injectJavascriptFileFromUrl(urlFile: String, scriptHtmlTagAttributes: [String:Any?]?) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document);"
|
var scriptAttributes = ""
|
||||||
|
if let scriptHtmlTagAttributes = scriptHtmlTagAttributes {
|
||||||
|
if let typeAttr = scriptHtmlTagAttributes["type"] as? String {
|
||||||
|
scriptAttributes += " script.type = '\(typeAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let idAttr = scriptHtmlTagAttributes["id"] as? String {
|
||||||
|
scriptAttributes += " script.id = '\(idAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let asyncAttr = scriptHtmlTagAttributes["async"] as? Bool, asyncAttr {
|
||||||
|
scriptAttributes += " script.async = true; "
|
||||||
|
}
|
||||||
|
if let deferAttr = scriptHtmlTagAttributes["defer"] as? Bool, deferAttr {
|
||||||
|
scriptAttributes += " script.defer = true; "
|
||||||
|
}
|
||||||
|
if let crossOriginAttr = scriptHtmlTagAttributes["crossOrigin"] as? String {
|
||||||
|
scriptAttributes += " script.crossOrigin = '\(crossOriginAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let integrityAttr = scriptHtmlTagAttributes["integrity"] as? String {
|
||||||
|
scriptAttributes += " script.integrity = '\(integrityAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let noModuleAttr = scriptHtmlTagAttributes["noModule"] as? Bool, noModuleAttr {
|
||||||
|
scriptAttributes += " script.noModule = true; "
|
||||||
|
}
|
||||||
|
if let nonceAttr = scriptHtmlTagAttributes["nonce"] as? String {
|
||||||
|
scriptAttributes += " script.nonce = '\(nonceAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let referrerPolicyAttr = scriptHtmlTagAttributes["referrerPolicy"] as? String {
|
||||||
|
scriptAttributes += " script.referrerPolicy = '\(referrerPolicyAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let jsWrapper = "(function(d) { var script = d.createElement('script'); \(scriptAttributes) script.src = %@; d.body.appendChild(script); })(document);"
|
||||||
injectDeferredObject(source: urlFile, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: urlFile, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectCSSCode(source: String) {
|
public func injectCSSCode(source: String) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document);"
|
let jsWrapper = "(function(d) { var style = d.createElement('style'); style.innerHTML = %@; d.body.appendChild(style); })(document);"
|
||||||
injectDeferredObject(source: source, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: source, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func injectCSSFileFromUrl(urlFile: String) {
|
public func injectCSSFileFromUrl(urlFile: String, cssLinkHtmlTagAttributes: [String:Any?]?) {
|
||||||
let jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document);"
|
var cssLinkAttributes = ""
|
||||||
|
var alternateStylesheet = ""
|
||||||
|
if let cssLinkHtmlTagAttributes = cssLinkHtmlTagAttributes {
|
||||||
|
if let idAttr = cssLinkHtmlTagAttributes["id"] as? String {
|
||||||
|
cssLinkAttributes += " link.id = '\(idAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let mediaAttr = cssLinkHtmlTagAttributes["media"] as? String {
|
||||||
|
cssLinkAttributes += " link.media = '\(mediaAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let crossOriginAttr = cssLinkHtmlTagAttributes["crossOrigin"] as? String {
|
||||||
|
cssLinkAttributes += " link.crossOrigin = '\(crossOriginAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let integrityAttr = cssLinkHtmlTagAttributes["integrity"] as? String {
|
||||||
|
cssLinkAttributes += " link.integrity = '\(integrityAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let referrerPolicyAttr = cssLinkHtmlTagAttributes["referrerPolicy"] as? String {
|
||||||
|
cssLinkAttributes += " link.referrerPolicy = '\(referrerPolicyAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
if let disabledAttr = cssLinkHtmlTagAttributes["disabled"] as? Bool, disabledAttr {
|
||||||
|
cssLinkAttributes += " link.disabled = true; "
|
||||||
|
}
|
||||||
|
if let alternateAttr = cssLinkHtmlTagAttributes["alternate"] as? Bool, alternateAttr {
|
||||||
|
alternateStylesheet = "alternate "
|
||||||
|
}
|
||||||
|
if let titleAttr = cssLinkHtmlTagAttributes["title"] as? String {
|
||||||
|
cssLinkAttributes += " link.title = '\(titleAttr.replacingOccurrences(of: "\'", with: "\\'"))'; "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let jsWrapper = "(function(d) { var link = d.createElement('link'); link.rel='\(alternateStylesheet)stylesheet', link.type='text/css'; \(cssLinkAttributes) link.href = %@; d.body.appendChild(link); })(document);"
|
||||||
injectDeferredObject(source: urlFile, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
injectDeferredObject(source: urlFile, contentWorldName: nil, withWrapper: jsWrapper, result: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
break
|
break
|
||||||
case "injectJavascriptFileFromUrl":
|
case "injectJavascriptFileFromUrl":
|
||||||
let urlFile = arguments!["urlFile"] as! String
|
let urlFile = arguments!["urlFile"] as! String
|
||||||
webView?.injectJavascriptFileFromUrl(urlFile: urlFile)
|
let scriptHtmlTagAttributes = arguments!["scriptHtmlTagAttributes"] as? [String:Any?]
|
||||||
|
webView?.injectJavascriptFileFromUrl(urlFile: urlFile, scriptHtmlTagAttributes: scriptHtmlTagAttributes)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "injectCSSCode":
|
case "injectCSSCode":
|
||||||
|
@ -90,7 +91,8 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
break
|
break
|
||||||
case "injectCSSFileFromUrl":
|
case "injectCSSFileFromUrl":
|
||||||
let urlFile = arguments!["urlFile"] as! String
|
let urlFile = arguments!["urlFile"] as! String
|
||||||
webView?.injectCSSFileFromUrl(urlFile: urlFile)
|
let cssLinkHtmlTagAttributes = arguments!["cssLinkHtmlTagAttributes"] as? [String:Any?]
|
||||||
|
webView?.injectCSSFileFromUrl(urlFile: urlFile, cssLinkHtmlTagAttributes: cssLinkHtmlTagAttributes)
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "reload":
|
case "reload":
|
||||||
|
|
|
@ -1382,17 +1382,20 @@ class InAppWebViewController {
|
||||||
|
|
||||||
///Injects an external JavaScript file into the WebView from a defined url.
|
///Injects an external JavaScript file into the WebView from a defined url.
|
||||||
///
|
///
|
||||||
|
///[scriptHtmlTagAttributes] represents the possible the `<script>` HTML attributes to be set.
|
||||||
|
///
|
||||||
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
///**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.
|
///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
|
///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".
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectJavascriptFileFromUrl({required String urlFile}) async {
|
Future<void> injectJavascriptFileFromUrl({required String urlFile, ScriptHtmlTagAttributes? scriptHtmlTagAttributes}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
|
args.putIfAbsent('scriptHtmlTagAttributes', () => scriptHtmlTagAttributes?.toMap());
|
||||||
await _channel.invokeMethod('injectJavascriptFileFromUrl', args);
|
await _channel.invokeMethod('injectJavascriptFileFromUrl', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a JavaScript file into the WebView from the flutter assets directory.
|
///Evaluates the content of 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,
|
///**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.
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
@ -1418,13 +1421,16 @@ class InAppWebViewController {
|
||||||
|
|
||||||
///Injects an external CSS file into the WebView from a defined url.
|
///Injects an external CSS file into the WebView from a defined url.
|
||||||
///
|
///
|
||||||
|
///[cssLinkHtmlTagAttributes] represents the possible CSS stylesheet `<link>` HTML attributes to be set.
|
||||||
|
///
|
||||||
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
///**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.
|
///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
|
///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".
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectCSSFileFromUrl({required String urlFile}) async {
|
Future<void> injectCSSFileFromUrl({required String urlFile, CSSLinkHtmlTagAttributes? cssLinkHtmlTagAttributes}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
|
args.putIfAbsent('cssLinkHtmlTagAttributes', () => cssLinkHtmlTagAttributes?.toMap());
|
||||||
await _channel.invokeMethod('injectCSSFileFromUrl', args);
|
await _channel.invokeMethod('injectCSSFileFromUrl', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4914,3 +4914,251 @@ class WebArchiveFormat {
|
||||||
@override
|
@override
|
||||||
int get hashCode => _value.hashCode;
|
int get hashCode => _value.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Class that represents the `crossorigin` content attribute on media elements is a CORS settings attribute.
|
||||||
|
class CrossOriginHtmlAttribute {
|
||||||
|
final String _value;
|
||||||
|
|
||||||
|
const CrossOriginHtmlAttribute._internal(this._value);
|
||||||
|
|
||||||
|
static final Set<CrossOriginHtmlAttribute> values = [
|
||||||
|
CrossOriginHtmlAttribute.ANONYMOUS,
|
||||||
|
CrossOriginHtmlAttribute.USE_CREDENTIALS,
|
||||||
|
].toSet();
|
||||||
|
|
||||||
|
static CrossOriginHtmlAttribute? fromValue(String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
return CrossOriginHtmlAttribute.values.firstWhere(
|
||||||
|
(element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String toValue() => _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _value;
|
||||||
|
|
||||||
|
///CORS requests for this element will have the credentials flag set to 'same-origin'.
|
||||||
|
static const ANONYMOUS = const CrossOriginHtmlAttribute._internal("anonymous");
|
||||||
|
|
||||||
|
///CORS requests for this element will have the credentials flag set to 'include'.
|
||||||
|
static const USE_CREDENTIALS = const CrossOriginHtmlAttribute._internal("use-credentials");
|
||||||
|
|
||||||
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class that represents which Referrer header to send when fetching a resource `<link>` or a `<script>` (or resources fetched by the `<script>`).
|
||||||
|
///Used by [ScriptHtmlTagAttributes] and [CSSLinkHtmlTagAttributes].
|
||||||
|
class ReferrerPolicyHtmlAttribute {
|
||||||
|
final String _value;
|
||||||
|
|
||||||
|
const ReferrerPolicyHtmlAttribute._internal(this._value);
|
||||||
|
|
||||||
|
static final Set<ReferrerPolicyHtmlAttribute> values = [
|
||||||
|
ReferrerPolicyHtmlAttribute.NO_REFERRER,
|
||||||
|
ReferrerPolicyHtmlAttribute.NO_REFERRER_WHEN_DOWNGRADE,
|
||||||
|
ReferrerPolicyHtmlAttribute.ORIGIN,
|
||||||
|
ReferrerPolicyHtmlAttribute.ORIGIN_WHEN_CROSS_ORIGIN,
|
||||||
|
ReferrerPolicyHtmlAttribute.SAME_ORIGIN,
|
||||||
|
ReferrerPolicyHtmlAttribute.STRICT_ORIGIN,
|
||||||
|
ReferrerPolicyHtmlAttribute.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
|
||||||
|
ReferrerPolicyHtmlAttribute.UNSAFE_URL,
|
||||||
|
].toSet();
|
||||||
|
|
||||||
|
static ReferrerPolicyHtmlAttribute? fromValue(String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
return ReferrerPolicyHtmlAttribute.values.firstWhere(
|
||||||
|
(element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String toValue() => _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _value;
|
||||||
|
|
||||||
|
///The Referer header will not be sent.
|
||||||
|
static const NO_REFERRER = const ReferrerPolicyHtmlAttribute._internal("no-referrer");
|
||||||
|
|
||||||
|
///The Referer header will not be sent to origins without TLS (HTTPS).
|
||||||
|
static const NO_REFERRER_WHEN_DOWNGRADE = const ReferrerPolicyHtmlAttribute._internal("no-referrer-when-downgrade");
|
||||||
|
|
||||||
|
///The sent referrer will be limited to the origin of the referring page: its scheme, host, and port.
|
||||||
|
static const ORIGIN = const ReferrerPolicyHtmlAttribute._internal("origin");
|
||||||
|
|
||||||
|
///The referrer sent to other origins will be limited to the scheme, the host, and the port.
|
||||||
|
///Navigations on the same origin will still include the path.
|
||||||
|
static const ORIGIN_WHEN_CROSS_ORIGIN = const ReferrerPolicyHtmlAttribute._internal("origin-when-cross-origin");
|
||||||
|
|
||||||
|
///A referrer will be sent for same origin, but cross-origin requests will contain no referrer information.
|
||||||
|
static const SAME_ORIGIN = const ReferrerPolicyHtmlAttribute._internal("same-origin");
|
||||||
|
|
||||||
|
///Only send the origin of the document as the referrer when the protocol security level stays the same (e.g. HTTPS -> HTTPS),
|
||||||
|
///but don't send it to a less secure destination (e.g. HTTPS -> HTTP).
|
||||||
|
static const STRICT_ORIGIN = const ReferrerPolicyHtmlAttribute._internal("strict-origin");
|
||||||
|
|
||||||
|
///Send a full URL when performing a same-origin request, but only send the origin when the protocol security level stays the same (e.g.HTTPS -> HTTPS),
|
||||||
|
///and send no header to a less secure destination (e.g. HTTPS -> HTTP).
|
||||||
|
static const STRICT_ORIGIN_WHEN_CROSS_ORIGIN = const ReferrerPolicyHtmlAttribute._internal("strict-origin-when-cross-origin");
|
||||||
|
|
||||||
|
///The referrer will include the origin and the path (but not the fragment, password, or username).
|
||||||
|
///This value is unsafe, because it leaks origins and paths from TLS-protected resources to insecure origins.
|
||||||
|
static const UNSAFE_URL = const ReferrerPolicyHtmlAttribute._internal("unsafe-url");
|
||||||
|
|
||||||
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class that represents the possible the `<script>` HTML attributes to be set used by [InAppWebViewController.injectJavascriptFileFromUrl].
|
||||||
|
class ScriptHtmlTagAttributes {
|
||||||
|
|
||||||
|
///This attribute indicates the type of script represented. The value of this attribute will be in one of the following categories.
|
||||||
|
///The default value is `text/javascript`.
|
||||||
|
String type;
|
||||||
|
|
||||||
|
///The HTML [id] attribute is used to specify a unique id for the `<script>` HTML element.
|
||||||
|
String? id;
|
||||||
|
|
||||||
|
///For classic scripts, if the [async] attribute is present,
|
||||||
|
///then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available.
|
||||||
|
///
|
||||||
|
///For module scripts, if the [async] attribute is present then the scripts and all their dependencies will be executed in the defer queue,
|
||||||
|
///therefore they will get fetched in parallel to parsing and evaluated as soon as they are available.
|
||||||
|
///
|
||||||
|
///This attribute allows the elimination of parser-blocking JavaScript where the browser
|
||||||
|
///would have to load and evaluate scripts before continuing to parse.
|
||||||
|
///[defer] has a similar effect in this case.
|
||||||
|
///
|
||||||
|
///This is a boolean attribute: the presence of a boolean attribute on an element represents the true value,
|
||||||
|
///and the absence of the attribute represents the false value.
|
||||||
|
bool? async;
|
||||||
|
|
||||||
|
///This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing `DOMContentLoaded`.
|
||||||
|
///
|
||||||
|
///Scripts with the [defer] attribute will prevent the `DOMContentLoaded` event from firing until the script has loaded and finished evaluating.
|
||||||
|
///
|
||||||
|
///Scripts with the [defer] attribute will execute in the order in which they appear in the document.
|
||||||
|
///
|
||||||
|
///This attribute allows the elimination of parser-blocking JavaScript where the browser would have to load and evaluate scripts before continuing to parse.
|
||||||
|
///[async] has a similar effect in this case.
|
||||||
|
bool? defer;
|
||||||
|
|
||||||
|
///Normal script elements pass minimal information to the `window.onerror` for scripts which do not pass the standard CORS checks.
|
||||||
|
///To allow error logging for sites which use a separate domain for static media, use this attribute.
|
||||||
|
CrossOriginHtmlAttribute? crossOrigin;
|
||||||
|
|
||||||
|
///This attribute contains inline metadata that a user agent can use to verify that a fetched resource has been delivered free of unexpected manipulation.
|
||||||
|
String? integrity;
|
||||||
|
|
||||||
|
///This Boolean attribute is set to indicate that the script should not be executed in browsers that support ES2015 modules — in effect,
|
||||||
|
///this can be used to serve fallback scripts to older browsers that do not support modular JavaScript code.
|
||||||
|
bool? noModule;
|
||||||
|
|
||||||
|
///A cryptographic nonce (number used once) to whitelist scripts in a script-src Content-Security-Policy.
|
||||||
|
///The server must generate a unique nonce value each time it transmits a policy.
|
||||||
|
///It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial.
|
||||||
|
String? nonce;
|
||||||
|
|
||||||
|
///Indicates which referrer to send when fetching the script, or resources fetched by the script.
|
||||||
|
ReferrerPolicyHtmlAttribute? referrerPolicy;
|
||||||
|
|
||||||
|
ScriptHtmlTagAttributes({this.type = "text/javascript", this.id, this.async, this.defer, this.crossOrigin, this.integrity, this.noModule, this.nonce, this.referrerPolicy});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"type": this.type,
|
||||||
|
"id": this.id,
|
||||||
|
"async": this.async,
|
||||||
|
"defer": this.defer,
|
||||||
|
"crossOrigin": this.crossOrigin?.toValue(),
|
||||||
|
"integrity": this.integrity,
|
||||||
|
"noModule": this.noModule,
|
||||||
|
"nonce": this.nonce,
|
||||||
|
"referrerPolicy": this.referrerPolicy?.toValue(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Class that represents the possible CSS stylesheet `<link>` HTML attributes to be set used by [InAppWebViewController.injectCSSFileFromUrl].
|
||||||
|
class CSSLinkHtmlTagAttributes {
|
||||||
|
|
||||||
|
///The HTML [id] attribute is used to specify a unique id for the `<link>` HTML element.
|
||||||
|
String? id;
|
||||||
|
|
||||||
|
///This attribute specifies the media that the linked resource applies to. Its value must be a media type / media query.
|
||||||
|
///This attribute is mainly useful when linking to external stylesheets — it allows the user agent to pick the best adapted one for the device it runs on.
|
||||||
|
String? media;
|
||||||
|
|
||||||
|
///Normal script elements pass minimal information to the `window.onerror` for scripts which do not pass the standard CORS checks.
|
||||||
|
///To allow error logging for sites which use a separate domain for static media, use this attribute.
|
||||||
|
CrossOriginHtmlAttribute? crossOrigin;
|
||||||
|
|
||||||
|
///This attribute contains inline metadata that a user agent can use to verify that a fetched resource has been delivered free of unexpected manipulation.
|
||||||
|
String? integrity;
|
||||||
|
|
||||||
|
///Indicates which referrer to send when fetching the script, or resources fetched by the script.
|
||||||
|
ReferrerPolicyHtmlAttribute? referrerPolicy;
|
||||||
|
|
||||||
|
///The [disabled] Boolean attribute indicates whether or not the described stylesheet should be loaded and applied to the document.
|
||||||
|
///If [disabled] is specified in the HTML when it is loaded, the stylesheet will not be loaded during page load.
|
||||||
|
///Instead, the stylesheet will be loaded on-demand, if and when the [disabled] attribute is changed to `false` or removed.
|
||||||
|
///
|
||||||
|
///Setting the [disabled] property in the DOM causes the stylesheet to be removed from the document's `DocumentOrShadowRoot.styleSheets` list.
|
||||||
|
bool? disabled;
|
||||||
|
|
||||||
|
///Specify alternative style sheets.
|
||||||
|
bool? alternate;
|
||||||
|
|
||||||
|
///The title attribute has special semantics on the `<link>` element.
|
||||||
|
///When used on a `<link rel="stylesheet">` it defines a preferred or an alternate stylesheet.
|
||||||
|
///Incorrectly using it may cause the stylesheet to be ignored.
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
CSSLinkHtmlTagAttributes({this.id, this.media, this.crossOrigin, this.integrity, this.referrerPolicy, this.disabled, this.alternate, this.title});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"id": this.id,
|
||||||
|
"media": this.media,
|
||||||
|
"crossOrigin": this.crossOrigin?.toValue(),
|
||||||
|
"integrity": this.integrity,
|
||||||
|
"referrerPolicy": this.referrerPolicy?.toValue(),
|
||||||
|
"disabled": this.disabled,
|
||||||
|
"alternate": this.alternate,
|
||||||
|
"title": this.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue