Skip to content

Commit

Permalink
Added scriptHtmlTagAttributes optional argument to injectJavascriptFi…
Browse files Browse the repository at this point in the history
…leFromUrl WebView method, Added cssLinkHtmlTagAttributes optional argument to injectCSSFileFromUrl WebView method
  • Loading branch information
pichillilorenzo committed Feb 9, 2021
1 parent bbb2af8 commit 0e4e165
Show file tree
Hide file tree
Showing 11 changed files with 432 additions and 23 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
- Added `iosAnimated` optional argument to `zoomBy` 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
- 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))
Expand All @@ -38,7 +40,7 @@

### 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`
- 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
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)

[![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)

[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/LorenzoPichilli)
Expand All @@ -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**!
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

- [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)
Expand Down Expand Up @@ -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.
* `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.
* `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.
* `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.
* `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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ public Map<String, Object> getOptions() {
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;
if (jsWrapper != null) {
org.json.JSONArray jsonEsc = new org.json.JSONArray();
Expand Down Expand Up @@ -1577,18 +1577,95 @@ public void evaluateJavascript(String source, @Nullable String contentWorldName,
injectDeferredObject(source, contentWorldName, null, result);
}

public void injectJavascriptFileFromUrl(String urlFile) {
String jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
public void injectJavascriptFileFromUrl(String urlFile, @Nullable Map<String, Object> scriptHtmlTagAttributes) {
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);
}

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);
}

public void injectCSSFileFromUrl(String urlFile) {
String jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
public void injectCSSFileFromUrl(String urlFile, @Nullable Map<String, Object> cssLinkHtmlTagAttributes) {
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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final MethodChannel.
case "injectJavascriptFileFromUrl":
if (webView != null) {
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);
break;
Expand All @@ -98,7 +99,8 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final MethodChannel.
case "injectCSSFileFromUrl":
if (webView != null) {
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);
break;
Expand Down
Loading

0 comments on commit 0e4e165

Please sign in to comment.