fixed android user scripts
This commit is contained in:
parent
bcbb8afaa4
commit
e9c69c7f8b
@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview.types;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -37,10 +36,13 @@ public class UserContentController implements Disposable {
|
|||||||
|
|
||||||
private final Map<UserScript, ScriptHandler> scriptHandlerMap = new HashMap<>();
|
private final Map<UserScript, ScriptHandler> scriptHandlerMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ScriptHandler contentWorldsCreatorScript;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Map<UserScriptInjectionTime, LinkedHashSet<UserScript>> userOnlyScripts = new HashMap<UserScriptInjectionTime, LinkedHashSet<UserScript>>() {{
|
private final Map<UserScriptInjectionTime, LinkedHashSet<UserScript>> userOnlyScripts = new HashMap<UserScriptInjectionTime, LinkedHashSet<UserScript>>() {{
|
||||||
put(UserScriptInjectionTime.AT_DOCUMENT_START, new LinkedHashSet<UserScript>());
|
put(UserScriptInjectionTime.AT_DOCUMENT_START, new LinkedHashSet<UserScript>());
|
||||||
put(UserScriptInjectionTime.AT_DOCUMENT_END, new LinkedHashSet<UserScript>());
|
put(UserScriptInjectionTime.AT_DOCUMENT_END, new LinkedHashSet<UserScript>());
|
||||||
}};
|
}};
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Map<UserScriptInjectionTime, LinkedHashSet<PluginScript>> pluginScripts = new HashMap<UserScriptInjectionTime, LinkedHashSet<PluginScript>>() {{
|
private final Map<UserScriptInjectionTime, LinkedHashSet<PluginScript>> pluginScripts = new HashMap<UserScriptInjectionTime, LinkedHashSet<PluginScript>>() {{
|
||||||
@ -171,15 +173,35 @@ public class UserContentController implements Disposable {
|
|||||||
return new LinkedHashSet<>(this.userOnlyScripts.get(injectionTime));
|
return new LinkedHashSet<>(this.userOnlyScripts.get(injectionTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateContentWorldsCreatorScript() {
|
||||||
|
String source = generateContentWorldsCreatorCode();
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
if (contentWorldsCreatorScript != null) {
|
||||||
|
contentWorldsCreatorScript.remove();
|
||||||
|
}
|
||||||
|
if (!source.isEmpty() && webView != null) {
|
||||||
|
contentWorldsCreatorScript = WebViewCompat.addDocumentStartJavaScript(
|
||||||
|
webView,
|
||||||
|
source,
|
||||||
|
new HashSet<String>() {{
|
||||||
|
add("*");
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean addUserOnlyScript(UserScript userOnlyScript) {
|
public boolean addUserOnlyScript(UserScript userOnlyScript) {
|
||||||
ContentWorld contentWorld = userOnlyScript.getContentWorld();
|
ContentWorld contentWorld = userOnlyScript.getContentWorld();
|
||||||
if (contentWorld != null) {
|
if (contentWorld != null) {
|
||||||
contentWorlds.add(contentWorld);
|
contentWorlds.add(contentWorld);
|
||||||
}
|
}
|
||||||
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
this.updateContentWorldsCreatorScript();
|
||||||
|
if (webView != null && userOnlyScript.getInjectionTime() == UserScriptInjectionTime.AT_DOCUMENT_START
|
||||||
|
&& WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
||||||
webView,
|
webView,
|
||||||
userOnlyScript.getSource(),
|
wrapSourceCodeInContentWorld(userOnlyScript.getContentWorld(), userOnlyScript.getSource()),
|
||||||
userOnlyScript.getAllowedOriginRules()
|
userOnlyScript.getAllowedOriginRules()
|
||||||
);
|
);
|
||||||
this.scriptHandlerMap.put(userOnlyScript, scriptHandler);
|
this.scriptHandlerMap.put(userOnlyScript, scriptHandler);
|
||||||
@ -200,6 +222,7 @@ public class UserContentController implements Disposable {
|
|||||||
scriptHandler.remove();
|
scriptHandler.remove();
|
||||||
this.scriptHandlerMap.remove(userOnlyScript);
|
this.scriptHandlerMap.remove(userOnlyScript);
|
||||||
}
|
}
|
||||||
|
this.updateContentWorldsCreatorScript();
|
||||||
}
|
}
|
||||||
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).remove(userOnlyScript);
|
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).remove(userOnlyScript);
|
||||||
}
|
}
|
||||||
@ -243,10 +266,12 @@ public class UserContentController implements Disposable {
|
|||||||
if (contentWorld != null) {
|
if (contentWorld != null) {
|
||||||
contentWorlds.add(contentWorld);
|
contentWorlds.add(contentWorld);
|
||||||
}
|
}
|
||||||
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
this.updateContentWorldsCreatorScript();
|
||||||
|
if (webView != null && pluginScript.getInjectionTime() == UserScriptInjectionTime.AT_DOCUMENT_START
|
||||||
|
&& WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
||||||
webView,
|
webView,
|
||||||
pluginScript.getSource(),
|
wrapSourceCodeInContentWorld(pluginScript.getContentWorld(), pluginScript.getSource()),
|
||||||
pluginScript.getAllowedOriginRules()
|
pluginScript.getAllowedOriginRules()
|
||||||
);
|
);
|
||||||
this.scriptHandlerMap.put(pluginScript, scriptHandler);
|
this.scriptHandlerMap.put(pluginScript, scriptHandler);
|
||||||
@ -267,6 +292,7 @@ public class UserContentController implements Disposable {
|
|||||||
scriptHandler.remove();
|
scriptHandler.remove();
|
||||||
this.scriptHandlerMap.remove(pluginScript);
|
this.scriptHandlerMap.remove(pluginScript);
|
||||||
}
|
}
|
||||||
|
this.updateContentWorldsCreatorScript();
|
||||||
}
|
}
|
||||||
return this.pluginScripts.get(pluginScript.getInjectionTime()).remove(pluginScript);
|
return this.pluginScripts.get(pluginScript.getInjectionTime()).remove(pluginScript);
|
||||||
}
|
}
|
||||||
@ -383,9 +409,31 @@ public class UserContentController implements Disposable {
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
private static final String CONTENT_WORLDS_GENERATOR_JS_SOURCE = "(function() {" +
|
private static final String CONTENT_WORLDS_GENERATOR_JS_SOURCE = "(function() {" +
|
||||||
" var contentWorldNames = [" + PluginScriptsUtil.VAR_CONTENT_WORLD_NAME_ARRAY + "];" +
|
" var interval = setInterval(function() {" +
|
||||||
" for (var contentWorldName of contentWorldNames) {" +
|
" if (document.body == null) {return;}" +
|
||||||
" var iframeId = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_' + contentWorldName;" +
|
" var contentWorldNames = [" + PluginScriptsUtil.VAR_CONTENT_WORLD_NAME_ARRAY + "];" +
|
||||||
|
" for (var contentWorldName of contentWorldNames) {" +
|
||||||
|
" var iframeId = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_' + contentWorldName;" +
|
||||||
|
" var iframe = document.getElementById(iframeId);" +
|
||||||
|
" if (iframe == null) {" +
|
||||||
|
" iframe = document.createElement('iframe');" +
|
||||||
|
" iframe.id = iframeId;" +
|
||||||
|
" iframe.style = 'display: none; z-index: 0; position: absolute; width: 0px; height: 0px';" +
|
||||||
|
" document.body.append(iframe);" +
|
||||||
|
" }" +
|
||||||
|
" var script = iframe.contentWindow.document.createElement('script');" +
|
||||||
|
" script.id = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_plugin_scripts';" +
|
||||||
|
" script.innerHTML = " + PluginScriptsUtil.VAR_JSON_SOURCE_ENCODED + ";" +
|
||||||
|
" iframe.contentWindow.document.body.append(script);" +
|
||||||
|
" }" +
|
||||||
|
" clearInterval(interval);" +
|
||||||
|
" });" +
|
||||||
|
"})();";
|
||||||
|
|
||||||
|
private static final String CONTENT_WORLD_WRAPPER_JS_SOURCE = "(function() {" +
|
||||||
|
" var interval = setInterval(function() {" +
|
||||||
|
" if (document.body == null) {return;}" +
|
||||||
|
" var iframeId = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_" + PluginScriptsUtil.VAR_CONTENT_WORLD_NAME + "';" +
|
||||||
" var iframe = document.getElementById(iframeId);" +
|
" var iframe = document.getElementById(iframeId);" +
|
||||||
" if (iframe == null) {" +
|
" if (iframe == null) {" +
|
||||||
" iframe = document.createElement('iframe');" +
|
" iframe = document.createElement('iframe');" +
|
||||||
@ -393,24 +441,14 @@ public class UserContentController implements Disposable {
|
|||||||
" iframe.style = 'display: none; z-index: 0; position: absolute; width: 0px; height: 0px';" +
|
" iframe.style = 'display: none; z-index: 0; position: absolute; width: 0px; height: 0px';" +
|
||||||
" document.body.append(iframe);" +
|
" document.body.append(iframe);" +
|
||||||
" }" +
|
" }" +
|
||||||
|
" if (iframe.contentWindow.document.querySelector('#" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_plugin_scripts') == null) {" +
|
||||||
|
" return;" +
|
||||||
|
" }" +
|
||||||
" var script = iframe.contentWindow.document.createElement('script');" +
|
" var script = iframe.contentWindow.document.createElement('script');" +
|
||||||
" script.innerHTML = "+ PluginScriptsUtil.VAR_JSON_SOURCE_ENCODED + ";" +
|
" script.innerHTML = " + PluginScriptsUtil.VAR_JSON_SOURCE_ENCODED + ";" +
|
||||||
" iframe.contentWindow.document.body.append(script);" +
|
" iframe.contentWindow.document.body.append(script);" +
|
||||||
" }" +
|
" clearInterval(interval);" +
|
||||||
"})();";
|
" });" +
|
||||||
|
|
||||||
private static final String CONTENT_WORLD_WRAPPER_JS_SOURCE = "(function() {" +
|
|
||||||
" var iframeId = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "_" + PluginScriptsUtil.VAR_CONTENT_WORLD_NAME + "';" +
|
|
||||||
" var iframe = document.getElementById(iframeId);" +
|
|
||||||
" if (iframe == null) {" +
|
|
||||||
" iframe = document.createElement('iframe');" +
|
|
||||||
" iframe.id = iframeId;" +
|
|
||||||
" iframe.style = 'display: none; z-index: 0; position: absolute; width: 0px; height: 0px';" +
|
|
||||||
" document.body.append(iframe);" +
|
|
||||||
" }" +
|
|
||||||
" var script = iframe.contentWindow.document.createElement('script');" +
|
|
||||||
" script.innerHTML = "+ PluginScriptsUtil.VAR_JSON_SOURCE_ENCODED + ";" +
|
|
||||||
" iframe.contentWindow.document.body.append(script);" +
|
|
||||||
"})();";
|
"})();";
|
||||||
|
|
||||||
private static final String DOCUMENT_READY_WRAPPER_JS_SOURCE = "if (document.readyState === 'interactive' || document.readyState === 'complete') { " +
|
private static final String DOCUMENT_READY_WRAPPER_JS_SOURCE = "if (document.readyState === 'interactive' || document.readyState === 'complete') { " +
|
||||||
@ -419,6 +457,11 @@ public class UserContentController implements Disposable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT) && contentWorldsCreatorScript != null) {
|
||||||
|
contentWorldsCreatorScript.remove();
|
||||||
|
}
|
||||||
|
removeAllUserOnlyScripts();
|
||||||
|
removeAllPluginScripts();
|
||||||
webView = null;
|
webView = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview;
|
package com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview;
|
||||||
|
|
||||||
|
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
|
import static com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType.fromValue;
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.PropertyValuesHolder;
|
import android.animation.PropertyValuesHolder;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
@ -56,18 +59,13 @@ import androidx.webkit.WebViewCompat;
|
|||||||
import androidx.webkit.WebViewFeature;
|
import androidx.webkit.WebViewFeature;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.find_interaction.FindInteractionController;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobController;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobManager;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobSettings;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.HitTestResult;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.JavaScriptBridgeInterface;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlocker;
|
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlocker;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerAction;
|
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerAction;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerHandler;
|
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerHandler;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerTrigger;
|
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerTrigger;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.find_interaction.FindInteractionController;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
|
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.ConsoleLogJS;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.ConsoleLogJS;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.InterceptAjaxRequestJS;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.InterceptAjaxRequestJS;
|
||||||
@ -79,16 +77,20 @@ import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.OnWindowFocusE
|
|||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PluginScriptsUtil;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PluginScriptsUtil;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PrintJS;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PrintJS;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PromisePolyfillJS;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.PromisePolyfillJS;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobController;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobManager;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.print_job.PrintJobSettings;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshLayout;
|
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshLayout;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.ContentWorld;
|
import com.pichillilorenzo.flutter_inappwebview.types.ContentWorld;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.DownloadStartRequest;
|
import com.pichillilorenzo.flutter_inappwebview.types.DownloadStartRequest;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.ContextMenuSettings;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.InAppWebViewInterface;
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.PluginScript;
|
import com.pichillilorenzo.flutter_inappwebview.types.PluginScript;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType;
|
import com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
|
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.UserContentController;
|
import com.pichillilorenzo.flutter_inappwebview.types.UserContentController;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
|
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.webview.ContextMenuSettings;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.webview.InAppWebViewInterface;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.webview.JavaScriptBridgeInterface;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.WebViewChannelDelegate;
|
import com.pichillilorenzo.flutter_inappwebview.webview.WebViewChannelDelegate;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.web_message.WebMessageChannel;
|
import com.pichillilorenzo.flutter_inappwebview.webview.web_message.WebMessageChannel;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.webview.web_message.WebMessageListener;
|
import com.pichillilorenzo.flutter_inappwebview.webview.web_message.WebMessageListener;
|
||||||
@ -99,20 +101,15 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
|
||||||
import static com.pichillilorenzo.flutter_inappwebview.types.PreferredContentModeOptionType.fromValue;
|
|
||||||
|
|
||||||
final public class InAppWebView extends InputAwareWebView implements InAppWebViewInterface {
|
final public class InAppWebView extends InputAwareWebView implements InAppWebViewInterface {
|
||||||
protected static final String LOG_TAG = "InAppWebView";
|
protected static final String LOG_TAG = "InAppWebView";
|
||||||
public static final String METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_";
|
public static final String METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user