Commit 55242a35 authored by Lorenzo Pichilli's avatar Lorenzo Pichilli

updated management of Content Worlds, updated evaluateJavascript API

parent 54e027be
...@@ -166,7 +166,7 @@ public class ContentBlockerHandler { ...@@ -166,7 +166,7 @@ public class ContentBlockerHandler {
@Override @Override
public void run() { public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript(jsScript, (MethodChannel.Result) null); webView.evaluateJavascript(jsScript, null);
} else { } else {
webView.loadUrl("javascript:" + jsScript); webView.loadUrl("javascript:" + jsScript);
} }
......
...@@ -26,12 +26,8 @@ import androidx.annotation.RequiresApi; ...@@ -26,12 +26,8 @@ import androidx.annotation.RequiresApi;
import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.Credential; import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.Credential;
import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.CredentialDatabase; import com.pichillilorenzo.flutter_inappwebview.CredentialDatabase.CredentialDatabase;
import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity; import com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappwebview.Util; import com.pichillilorenzo.flutter_inappwebview.Util;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
...@@ -166,10 +162,10 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -166,10 +162,10 @@ public class InAppWebViewClient extends WebViewClient {
private void loadCustomJavaScriptOnPageStarted(WebView view) { private void loadCustomJavaScriptOnPageStarted(WebView view) {
InAppWebView webView = (InAppWebView) view; InAppWebView webView = (InAppWebView) view;
String jsPluginScripts = preparePluginUserScripts(webView); String jsPluginScriptsWrapped = webView.prepareAndWrapPluginUserScripts();
String jsUserScriptsAtDocumentStart = prepareUserScriptsAtDocumentStart(webView); String jsUserScriptsAtDocumentStart = prepareUserScriptsAtDocumentStart(webView);
String js = wrapPluginAndUserScripts(jsPluginScripts, jsUserScriptsAtDocumentStart, null); String js = wrapPluginAndUserScripts(jsPluginScriptsWrapped, jsUserScriptsAtDocumentStart, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript(js, (ValueCallback<String>) null); webView.evaluateJavascript(js, (ValueCallback<String>) null);
...@@ -182,11 +178,11 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -182,11 +178,11 @@ public class InAppWebViewClient extends WebViewClient {
InAppWebView webView = (InAppWebView) view; InAppWebView webView = (InAppWebView) view;
// try to reload also custom scripts if they were not loaded during the onPageStarted event // try to reload also custom scripts if they were not loaded during the onPageStarted event
String jsPluginScripts = preparePluginUserScripts(webView); String jsPluginScriptsWrapped = webView.prepareAndWrapPluginUserScripts();
String jsUserScriptsAtDocumentStart = prepareUserScriptsAtDocumentStart(webView); String jsUserScriptsAtDocumentStart = prepareUserScriptsAtDocumentStart(webView);
String jsUserScriptsAtDocumentEnd = prepareUserScriptsAtDocumentEnd(webView); String jsUserScriptsAtDocumentEnd = prepareUserScriptsAtDocumentEnd(webView);
String js = wrapPluginAndUserScripts(jsPluginScripts, jsUserScriptsAtDocumentStart, jsUserScriptsAtDocumentEnd); String js = wrapPluginAndUserScripts(jsPluginScriptsWrapped, jsUserScriptsAtDocumentStart, jsUserScriptsAtDocumentEnd);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript(js, (ValueCallback<String>) null); webView.evaluateJavascript(js, (ValueCallback<String>) null);
...@@ -194,57 +190,25 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -194,57 +190,25 @@ public class InAppWebViewClient extends WebViewClient {
webView.loadUrl("javascript:" + js.replaceAll("[\r\n]+", "")); webView.loadUrl("javascript:" + js.replaceAll("[\r\n]+", ""));
} }
} }
private String preparePluginUserScripts(InAppWebView webView) { private String prepareUserScripts(InAppWebView webView, int atDocumentInjectionTime) {
String js = InAppWebView.consoleLogJS;
js += JavaScriptBridgeInterface.callHandlerScriptJS;
if (webView.options.useShouldInterceptAjaxRequest) {
js += InAppWebView.interceptAjaxRequestsJS;
}
if (webView.options.useShouldInterceptFetchRequest) {
js += InAppWebView.interceptFetchRequestsJS;
}
if (webView.options.useOnLoadResource) {
js += InAppWebView.resourceObserverJS;
}
if (!webView.options.useHybridComposition) {
js += InAppWebView.checkGlobalKeyDownEventToHideContextMenuJS;
}
js += InAppWebView.onWindowFocusEventJS;
js += InAppWebView.onWindowBlurEventJS;
js += InAppWebView.printJS;
return js;
}
private String prepareUserScriptsAtDocumentStart(InAppWebView webView) {
StringBuilder js = new StringBuilder(); StringBuilder js = new StringBuilder();
for (Map<String, Object> userScript : webView.userScripts) { for (Map<String, Object> userScript : webView.userScripts) {
Integer injectionTime = (Integer) userScript.get("injectionTime"); Integer injectionTime = (Integer) userScript.get("injectionTime");
if (injectionTime == null || injectionTime == 0) { if ((injectionTime == null && atDocumentInjectionTime == 0) || (injectionTime != null && injectionTime == atDocumentInjectionTime)) {
String source = (String) userScript.get("source"); String source = (String) userScript.get("source");
String contentWorldName = (String) userScript.get("contentWorld"); String contentWorldName = (String) userScript.get("contentWorld");
if (source != null) { if (source != null) {
if (contentWorldName != null && !contentWorldName.equals("page")) { if (contentWorldName != null && !contentWorldName.equals("page")) {
String jsPluginScripts = preparePluginUserScripts(webView); String jsPluginScripts = webView.prepareAndWrapPluginUserScripts();
source = jsPluginScripts + "\n" + source; source = jsPluginScripts + "\n" + source;
} }
if (contentWorldName != null && !webView.userScriptsContentWorlds.contains(contentWorldName)) {
JSONObject sourceEncoded = new JSONObject(); webView.userScriptsContentWorlds.add(contentWorldName);
try {
// encode the javascript source in order to escape special chars and quotes
sourceEncoded.put("source", source);
} catch (JSONException e) {
e.printStackTrace();
} }
String sourceWrapped = webView.wrapSourceCodeInContentWorld(contentWorldName, source);
String sourceWrapped = contentWorldName == null || contentWorldName.equals("page") ? source : if (atDocumentInjectionTime == 0 && contentWorldName != null && !contentWorldName.equals("page")) {
InAppWebView.contentWorldWrapperJS.replace("$CONTENT_WORLD_NAME", contentWorldName)
.replace("$CONTENT_WORLD_NAME", contentWorldName)
.replace("$JSON_SOURCE_ENCODED", sourceEncoded.toString());
if (contentWorldName != null && !contentWorldName.equals("page")) {
// adds another wrapper because sometimes document.body is not ready and it is undefined, causing an error and not adding the iframe element. // adds another wrapper because sometimes document.body is not ready and it is undefined, causing an error and not adding the iframe element.
sourceWrapped = InAppWebView.documentReadyWrapperJS.replace("$PLACEHOLDER_VALUE", sourceWrapped) sourceWrapped = InAppWebView.documentReadyWrapperJS.replace("$PLACEHOLDER_VALUE", sourceWrapped)
.replace("$PLACEHOLDER_VALUE", sourceWrapped); .replace("$PLACEHOLDER_VALUE", sourceWrapped);
...@@ -258,43 +222,15 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -258,43 +222,15 @@ public class InAppWebViewClient extends WebViewClient {
return js.toString(); return js.toString();
} }
private String prepareUserScriptsAtDocumentEnd(InAppWebView webView) { private String prepareUserScriptsAtDocumentStart(InAppWebView webView) {
StringBuilder js = new StringBuilder(); return prepareUserScripts(webView, 0);
}
for (Map<String, Object> userScript : webView.userScripts) {
Integer injectionTime = (Integer) userScript.get("injectionTime");
if (injectionTime != null && injectionTime == 1) {
String source = (String) userScript.get("source");
String contentWorldName = (String) userScript.get("contentWorld");
if (source != null) {
if (contentWorldName != null && !contentWorldName.equals("page")) {
String jsPluginScripts = preparePluginUserScripts(webView);
source = jsPluginScripts + "\n" + source;
}
JSONObject sourceEncoded = new JSONObject();
try {
// encode the javascript source in order to escape special chars and quotes
sourceEncoded.put("source", source);
} catch (JSONException e) {
e.printStackTrace();
}
String sourceWrapped = contentWorldName == null || contentWorldName.equals("page") ? source :
InAppWebView.contentWorldWrapperJS.replace("$CONTENT_WORLD_NAME", contentWorldName)
.replace("$CONTENT_WORLD_NAME", contentWorldName)
.replace("$JSON_SOURCE_ENCODED", sourceEncoded.toString());
js.append(sourceWrapped);
}
}
}
return js.toString(); private String prepareUserScriptsAtDocumentEnd(InAppWebView webView) {
return prepareUserScripts(webView, 1);
} }
private String wrapPluginAndUserScripts(String jsPluginScripts, @Nullable String jsUserScriptsAtDocumentStart, @Nullable String jsUserScriptsAtDocumentEnd) { private String wrapPluginAndUserScripts(String jsPluginScriptsWrapped, @Nullable String jsUserScriptsAtDocumentStart, @Nullable String jsUserScriptsAtDocumentEnd) {
String jsPluginScriptsWrapped = InAppWebView.pluginScriptsWrapperJS
.replace("$PLACEHOLDER_VALUE", jsPluginScripts);
String jsUserScriptsAtDocumentStartWrapped = jsUserScriptsAtDocumentStart == null || jsUserScriptsAtDocumentStart.isEmpty() ? "" : String jsUserScriptsAtDocumentStartWrapped = jsUserScriptsAtDocumentStart == null || jsUserScriptsAtDocumentStart.isEmpty() ? "" :
InAppWebView.userScriptsAtDocumentStartWrapperJS.replace("$PLACEHOLDER_VALUE", jsUserScriptsAtDocumentStart); InAppWebView.userScriptsAtDocumentStartWrapperJS.replace("$PLACEHOLDER_VALUE", jsUserScriptsAtDocumentStart);
String jsUserScriptsAtDocumentEndWrapped = jsUserScriptsAtDocumentEnd == null || jsUserScriptsAtDocumentEnd.isEmpty() ? "" : String jsUserScriptsAtDocumentEndWrapped = jsUserScriptsAtDocumentEnd == null || jsUserScriptsAtDocumentEnd.isEmpty() ? "" :
...@@ -305,6 +241,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -305,6 +241,7 @@ public class InAppWebViewClient extends WebViewClient {
@Override @Override
public void onPageStarted(WebView view, String url, Bitmap favicon) { public void onPageStarted(WebView view, String url, Bitmap favicon) {
final InAppWebView webView = (InAppWebView) view; final InAppWebView webView = (InAppWebView) view;
webView.resetUserScriptsContentWorlds();
loadCustomJavaScriptOnPageStarted(webView); loadCustomJavaScriptOnPageStarted(webView);
......
...@@ -74,7 +74,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle ...@@ -74,7 +74,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
case "evaluateJavascript": case "evaluateJavascript":
if (webView != null) { if (webView != null) {
String source = (String) call.argument("source"); String source = (String) call.argument("source");
webView.evaluateJavascript(source, result); String contentWorldName = (String) call.argument("contentWorld");
webView.evaluateJavascript(source, contentWorldName, result);
} }
else { else {
result.success(null); result.success(null);
......
{"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-04 22:05:52.361400","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-06 02:03:14.260971","version":"1.26.0-18.0.pre.90"}
\ No newline at end of file \ No newline at end of file
This diff is collapsed.
...@@ -30,15 +30,15 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate { ...@@ -30,15 +30,15 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
result( (webView != nil) ? Int(webView!.estimatedProgress * 100) : nil ) result( (webView != nil) ? Int(webView!.estimatedProgress * 100) : nil )
break break
case "loadUrl": case "loadUrl":
let url = (arguments!["url"] as? String)! let url = arguments!["url"] as! String
let headers = (arguments!["headers"] as? [String: String])! let headers = arguments!["headers"] as! [String: String]
webView?.loadUrl(url: URL(string: url)!, headers: headers) webView?.loadUrl(url: URL(string: url)!, headers: headers)
result(true) result(true)
break break
case "postUrl": case "postUrl":
if webView != nil { if webView != nil {
let url = (arguments!["url"] as? String)! let url = arguments!["url"] as! String
let postData = (arguments!["postData"] as? FlutterStandardTypedData)! let postData = arguments!["postData"] as! FlutterStandardTypedData
webView!.postUrl(url: URL(string: url)!, postData: postData.data, completionHandler: { () -> Void in webView!.postUrl(url: URL(string: url)!, postData: postData.data, completionHandler: { () -> Void in
result(true) result(true)
}) })
...@@ -48,16 +48,16 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate { ...@@ -48,16 +48,16 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
} }
break break
case "loadData": case "loadData":
let data = (arguments!["data"] as? String)! let data = arguments!["data"] as! String
let mimeType = (arguments!["mimeType"] as? String)! let mimeType = arguments!["mimeType"] as! String
let encoding = (arguments!["encoding"] as? String)! let encoding = arguments!["encoding"] as! String
let baseUrl = (arguments!["baseUrl"] as? String)! let baseUrl = arguments!["baseUrl"] as! String
webView?.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl) webView?.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
result(true) result(true)
break break
case "loadFile": case "loadFile":
let url = (arguments!["url"] as? String)! let url = arguments!["url"] as! String
let headers = (arguments!["headers"] as? [String: String])! let headers = arguments!["headers"] as! [String: String]
do { do {
try webView?.loadFile(url: url, headers: headers) try webView?.loadFile(url: url, headers: headers)
...@@ -70,25 +70,26 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate { ...@@ -70,25 +70,26 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
break break
case "evaluateJavascript": case "evaluateJavascript":
if webView != nil { if webView != nil {
let source = (arguments!["source"] as? String)! let source = arguments!["source"] as! String
webView!.evaluateJavascript(source: source, result: result) let contentWorldName = arguments!["contentWorld"] as? String
webView!.evaluateJavascript(source: source, contentWorldName: contentWorldName, result: result)
} }
else { else {
result(nil) result(nil)
} }
break break
case "injectJavascriptFileFromUrl": case "injectJavascriptFileFromUrl":
let urlFile = (arguments!["urlFile"] as? String)! let urlFile = arguments!["urlFile"] as! String
webView?.injectJavascriptFileFromUrl(urlFile: urlFile) webView?.injectJavascriptFileFromUrl(urlFile: urlFile)
result(true) result(true)
break break
case "injectCSSCode": case "injectCSSCode":
let source = (arguments!["source"] as? String)! let source = arguments!["source"] as! String
webView?.injectCSSCode(source: source) webView?.injectCSSCode(source: source)
result(true) result(true)
break break
case "injectCSSFileFromUrl": case "injectCSSFileFromUrl":
let urlFile = (arguments!["urlFile"] as? String)! let urlFile = arguments!["urlFile"] as! String
webView?.injectCSSFileFromUrl(urlFile: urlFile) webView?.injectCSSFileFromUrl(urlFile: urlFile)
result(true) result(true)
break break
...@@ -111,12 +112,12 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate { ...@@ -111,12 +112,12 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
result(webView?.canGoForward ?? false) result(webView?.canGoForward ?? false)
break break
case "goBackOrForward": case "goBackOrForward":
let steps = (arguments!["steps"] as? Int)! let steps = arguments!["steps"] as! Int
webView?.goBackOrForward(steps: steps) webView?.goBackOrForward(steps: steps)
result(true) result(true)
break break
case "canGoBackOrForward": case "canGoBackOrForward":
let steps = (arguments!["steps"] as? Int)! let steps = arguments!["steps"] as! Int
result(webView?.canGoBackOrForward(steps: steps) ?? false) result(webView?.canGoBackOrForward(steps: steps) ?? false)
break break
case "stopLoading": case "stopLoading":
......
...@@ -1351,7 +1351,14 @@ class InAppWebViewController { ...@@ -1351,7 +1351,14 @@ class InAppWebViewController {
await _channel.invokeMethod('stopLoading', args); await _channel.invokeMethod('stopLoading', args);
} }
///Evaluates JavaScript code into the WebView and returns the result of the evaluation. ///Evaluates JavaScript [source] code into the WebView and returns the result of the evaluation.
///
///[contentWorld], on iOS, it represents the namespace in which to evaluate the JavaScript [source] code.
///Instead, on Android, it will run the [source] code into an iframe.
///This parameter doesn’t apply to changes you make to the underlying web content, such as the document’s DOM structure.
///Those changes remain visible to all scripts, regardless of which content world you specify.
///For more information about content worlds, see [ContentWorld].
///Available on iOS 14.0+.
/// ///
///**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.
...@@ -1360,10 +1367,13 @@ class InAppWebViewController { ...@@ -1360,10 +1367,13 @@ class InAppWebViewController {
/// ///
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E) ///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
/// ///
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript ///**Official iOS API**:
Future<dynamic> evaluateJavascript({required String source}) async { ///- https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript
///- https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript
Future<dynamic> evaluateJavascript({required String source, ContentWorld? contentWorld}) async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('source', () => source); args.putIfAbsent('source', () => source);
args.putIfAbsent('contentWorld', () => contentWorld?.name);
var data = await _channel.invokeMethod('evaluateJavascript', args); var data = await _channel.invokeMethod('evaluateJavascript', args);
if (data != null && defaultTargetPlatform == TargetPlatform.android) data = json.decode(data); if (data != null && defaultTargetPlatform == TargetPlatform.android) data = json.decode(data);
return data; return data;
......
...@@ -4599,12 +4599,15 @@ class UserScript { ...@@ -4599,12 +4599,15 @@ class UserScript {
///Class that represents an object that defines a scope of execution for JavaScript code, and which you use to prevent conflicts between different scripts. ///Class that represents an object that defines a scope of execution for JavaScript code, and which you use to prevent conflicts between different scripts.
/// ///
///**NOTE for iOS 14.0+**: this class represents the native [WKContentWorld](https://developer.apple.com/documentation/webkit/wkcontentworld) class. ///**NOTE for iOS**: available on iOS 14.0+. This class represents the native [WKContentWorld](https://developer.apple.com/documentation/webkit/wkcontentworld) class.
/// ///
///**NOTE for Android**: it will create and append an `<iframe>` HTML element with `id` equals to `flutter_inappwebview_[name]` to the webpage's content that contains only the scripts ///**NOTE for Android**: it will create and append an `<iframe>` HTML element with `id` equals to `flutter_inappwebview_[name]`
///in order to define a new scope of execution for JavaScript code. Unfortunately, there isn't any other way to do it. ///to the webpage's content that contains only the inline `<script>` HTML elements in order to define a new scope of execution for JavaScript code.
///For any [ContentWorld], except [ContentWorld.page], if you need to access to the `window` or `document` global Object, ///Unfortunately, there isn't any other way to do it.
///you need to use `window.top` and `window.top.document` because the code runs inside an `<iframe>`. ///There are some limitations:
///- for any [ContentWorld], except [ContentWorld.page] (that is the webpage itself), if you need to access to the `window` or `document` global Object,
///you need to use `window.top` and `window.top.document` because the code runs inside an `<iframe>`;
///- also, the execution of the inline `<script>` could be blocked by the `Content-Security-Policy` header.
class ContentWorld { class ContentWorld {
///The name of a custom content world. ///The name of a custom content world.
final String name; final String name;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment