Added WebViewFeature.DOCUMENT_START_SCRIPT Android feature support
This commit is contained in:
parent
1791b8202b
commit
80b8bde10a
|
@ -10,6 +10,7 @@
|
||||||
- Added `onCameraCaptureStateChanged`, `onMicrophoneCaptureStateChanged` WebView events
|
- Added `onCameraCaptureStateChanged`, `onMicrophoneCaptureStateChanged` WebView events
|
||||||
- Added support for `onPermissionRequest` event on iOS 15.0+
|
- Added support for `onPermissionRequest` event on iOS 15.0+
|
||||||
- Added `debugLoggingSettings` static property for WebView and ChromeSafariBrowser
|
- Added `debugLoggingSettings` static property for WebView and ChromeSafariBrowser
|
||||||
|
- Added `WebViewFeature.DOCUMENT_START_SCRIPT` Android feature support
|
||||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||||
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes
|
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes
|
||||||
- Deprecated `onLoadHttpError` for `onReceivedError`. `onReceivedHttpError` will be called also for subframes
|
- Deprecated `onLoadHttpError` for `onReceivedError`. `onReceivedHttpError` will be called also for subframes
|
||||||
|
|
|
@ -10,7 +10,8 @@ public class ConsoleLogJS {
|
||||||
ConsoleLogJS.CONSOLE_LOG_JS_SOURCE,
|
ConsoleLogJS.CONSOLE_LOG_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String CONSOLE_LOG_JS_SOURCE = "(function(console) {" +
|
public static final String CONSOLE_LOG_JS_SOURCE = "(function(console) {" +
|
||||||
|
|
|
@ -12,7 +12,8 @@ public class InterceptAjaxRequestJS {
|
||||||
InterceptAjaxRequestJS.INTERCEPT_AJAX_REQUEST_JS_SOURCE,
|
InterceptAjaxRequestJS.INTERCEPT_AJAX_REQUEST_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String INTERCEPT_AJAX_REQUEST_JS_SOURCE = "(function(ajax) {" +
|
public static final String INTERCEPT_AJAX_REQUEST_JS_SOURCE = "(function(ajax) {" +
|
||||||
|
|
|
@ -12,7 +12,8 @@ public class InterceptFetchRequestJS {
|
||||||
InterceptFetchRequestJS.INTERCEPT_FETCH_REQUEST_JS_SOURCE,
|
InterceptFetchRequestJS.INTERCEPT_FETCH_REQUEST_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String INTERCEPT_FETCH_REQUEST_JS_SOURCE = "(function(fetch) {" +
|
public static final String INTERCEPT_FETCH_REQUEST_JS_SOURCE = "(function(fetch) {" +
|
||||||
|
|
|
@ -11,7 +11,8 @@ public class JavaScriptBridgeJS {
|
||||||
JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_JS_SOURCE,
|
JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String JAVASCRIPT_UTIL_VAR_NAME = "window." + JAVASCRIPT_BRIDGE_NAME + "._Util";
|
public static final String JAVASCRIPT_UTIL_VAR_NAME = "window." + JAVASCRIPT_BRIDGE_NAME + "._Util";
|
||||||
|
|
|
@ -11,7 +11,8 @@ public class OnLoadResourceJS {
|
||||||
OnLoadResourceJS.ON_LOAD_RESOURCE_JS_SOURCE,
|
OnLoadResourceJS.ON_LOAD_RESOURCE_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String ON_LOAD_RESOURCE_JS_SOURCE = "window." + FLAG_VARIABLE_FOR_ON_LOAD_RESOURCE_JS_SOURCE + " = true;" +
|
public static final String ON_LOAD_RESOURCE_JS_SOURCE = "window." + FLAG_VARIABLE_FOR_ON_LOAD_RESOURCE_JS_SOURCE + " = true;" +
|
||||||
|
|
|
@ -10,7 +10,8 @@ public class OnWindowBlurEventJS {
|
||||||
OnWindowBlurEventJS.ON_WINDOW_BLUR_EVENT_JS_SOURCE,
|
OnWindowBlurEventJS.ON_WINDOW_BLUR_EVENT_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String ON_WINDOW_BLUR_EVENT_JS_SOURCE = "(function(){" +
|
public static final String ON_WINDOW_BLUR_EVENT_JS_SOURCE = "(function(){" +
|
||||||
|
|
|
@ -10,7 +10,8 @@ public class OnWindowFocusEventJS {
|
||||||
OnWindowFocusEventJS.ON_WINDOW_FOCUS_EVENT_JS_SOURCE,
|
OnWindowFocusEventJS.ON_WINDOW_FOCUS_EVENT_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String ON_WINDOW_FOCUS_EVENT_JS_SOURCE = "(function(){" +
|
public static final String ON_WINDOW_FOCUS_EVENT_JS_SOURCE = "(function(){" +
|
||||||
|
|
|
@ -77,7 +77,8 @@ public class PluginScriptsUtil {
|
||||||
PluginScriptsUtil.CHECK_GLOBAL_KEY_DOWN_EVENT_TO_HIDE_CONTEXT_MENU_JS_SOURCE,
|
PluginScriptsUtil.CHECK_GLOBAL_KEY_DOWN_EVENT_TO_HIDE_CONTEXT_MENU_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
// android Workaround to hide context menu when user emit a keydown event
|
// android Workaround to hide context menu when user emit a keydown event
|
||||||
|
|
|
@ -10,7 +10,8 @@ public class PrintJS {
|
||||||
PrintJS.PRINT_JS_SOURCE,
|
PrintJS.PRINT_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final String PRINT_JS_SOURCE = "window.print = function() {" +
|
public static final String PRINT_JS_SOURCE = "window.print = function() {" +
|
||||||
|
|
|
@ -10,7 +10,8 @@ public class PromisePolyfillJS {
|
||||||
PromisePolyfillJS.PROMISE_POLYFILL_JS_SOURCE,
|
PromisePolyfillJS.PROMISE_POLYFILL_JS_SOURCE,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
// https://github.com/tildeio/rsvp.js
|
// https://github.com/tildeio/rsvp.js
|
||||||
|
|
|
@ -3,11 +3,13 @@ package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class PluginScript extends UserScript {
|
public class PluginScript extends UserScript {
|
||||||
private boolean requiredInAllContentWorlds;
|
private boolean requiredInAllContentWorlds;
|
||||||
|
|
||||||
public PluginScript(@Nullable String groupName, @NonNull String source, @NonNull UserScriptInjectionTime injectionTime, @Nullable ContentWorld contentWorld, boolean requiredInAllContentWorlds) {
|
public PluginScript(@Nullable String groupName, @NonNull String source, @NonNull UserScriptInjectionTime injectionTime, @Nullable ContentWorld contentWorld, boolean requiredInAllContentWorlds, @Nullable Set<String> allowedOriginRules) {
|
||||||
super(groupName, source, injectionTime, contentWorld);
|
super(groupName, source, injectionTime, contentWorld, allowedOriginRules);
|
||||||
this.requiredInAllContentWorlds = requiredInAllContentWorlds;
|
this.requiredInAllContentWorlds = requiredInAllContentWorlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package com.pichillilorenzo.flutter_inappwebview.types;
|
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.webkit.ScriptHandler;
|
||||||
|
import androidx.webkit.WebViewCompat;
|
||||||
|
import androidx.webkit.WebViewFeature;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
|
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
|
||||||
|
@ -21,7 +26,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class UserContentController {
|
@SuppressLint("RestrictedApi")
|
||||||
|
public class UserContentController implements Disposable {
|
||||||
protected static final String LOG_TAG = "UserContentController";
|
protected static final String LOG_TAG = "UserContentController";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -29,6 +35,8 @@ public class UserContentController {
|
||||||
add(ContentWorld.PAGE);
|
add(ContentWorld.PAGE);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
private final Map<UserScript, ScriptHandler> scriptHandlerMap = new HashMap<>();
|
||||||
|
|
||||||
@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>());
|
||||||
|
@ -40,7 +48,11 @@ public class UserContentController {
|
||||||
put(UserScriptInjectionTime.AT_DOCUMENT_END, new LinkedHashSet<PluginScript>());
|
put(UserScriptInjectionTime.AT_DOCUMENT_END, new LinkedHashSet<PluginScript>());
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public UserContentController() {
|
@Nullable
|
||||||
|
public WebView webView;
|
||||||
|
|
||||||
|
public UserContentController(WebView webView) {
|
||||||
|
this.webView = webView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateWrappedCodeForDocumentStart() {
|
public String generateWrappedCodeForDocumentStart() {
|
||||||
|
@ -52,8 +64,11 @@ public class UserContentController {
|
||||||
|
|
||||||
public String generateWrappedCodeForDocumentEnd() {
|
public String generateWrappedCodeForDocumentEnd() {
|
||||||
UserScriptInjectionTime injectionTime = UserScriptInjectionTime.AT_DOCUMENT_END;
|
UserScriptInjectionTime injectionTime = UserScriptInjectionTime.AT_DOCUMENT_END;
|
||||||
|
String js = "";
|
||||||
|
if (!WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
// try to reload scripts if they were not loaded during the AT_DOCUMENT_START event
|
// try to reload scripts if they were not loaded during the AT_DOCUMENT_START event
|
||||||
String js = generateCodeForDocumentStart();
|
js += generateCodeForDocumentStart();
|
||||||
|
}
|
||||||
js += generatePluginScriptsCodeAt(injectionTime);
|
js += generatePluginScriptsCodeAt(injectionTime);
|
||||||
js += generateUserOnlyScriptsCodeAt(injectionTime);
|
js += generateUserOnlyScriptsCodeAt(injectionTime);
|
||||||
js = USER_SCRIPTS_AT_DOCUMENT_END_WRAPPER_JS_SOURCE.replace(PluginScriptsUtil.VAR_PLACEHOLDER_VALUE, js);
|
js = USER_SCRIPTS_AT_DOCUMENT_END_WRAPPER_JS_SOURCE.replace(PluginScriptsUtil.VAR_PLACEHOLDER_VALUE, js);
|
||||||
|
@ -161,6 +176,14 @@ public class UserContentController {
|
||||||
if (contentWorld != null) {
|
if (contentWorld != null) {
|
||||||
contentWorlds.add(contentWorld);
|
contentWorlds.add(contentWorld);
|
||||||
}
|
}
|
||||||
|
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
||||||
|
webView,
|
||||||
|
userOnlyScript.getSource(),
|
||||||
|
userOnlyScript.getAllowedOriginRules()
|
||||||
|
);
|
||||||
|
this.scriptHandlerMap.put(userOnlyScript, scriptHandler);
|
||||||
|
}
|
||||||
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).add(userOnlyScript);
|
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).add(userOnlyScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +194,13 @@ public class UserContentController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeUserOnlyScript(UserScript userOnlyScript) {
|
public boolean removeUserOnlyScript(UserScript userOnlyScript) {
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
ScriptHandler scriptHandler = this.scriptHandlerMap.get(userOnlyScript);
|
||||||
|
if (scriptHandler != null) {
|
||||||
|
scriptHandler.remove();
|
||||||
|
this.scriptHandlerMap.remove(userOnlyScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).remove(userOnlyScript);
|
return this.userOnlyScripts.get(userOnlyScript.getInjectionTime()).remove(userOnlyScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +210,15 @@ public class UserContentController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllUserOnlyScripts() {
|
public void removeAllUserOnlyScripts() {
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
for (UserScript userOnlyScript : this.userOnlyScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START)) {
|
||||||
|
ScriptHandler scriptHandler = this.scriptHandlerMap.get(userOnlyScript);
|
||||||
|
if (scriptHandler != null) {
|
||||||
|
scriptHandler.remove();
|
||||||
|
this.scriptHandlerMap.remove(userOnlyScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.userOnlyScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START).clear();
|
this.userOnlyScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START).clear();
|
||||||
this.userOnlyScripts.get(UserScriptInjectionTime.AT_DOCUMENT_END).clear();
|
this.userOnlyScripts.get(UserScriptInjectionTime.AT_DOCUMENT_END).clear();
|
||||||
}
|
}
|
||||||
|
@ -204,6 +243,14 @@ public class UserContentController {
|
||||||
if (contentWorld != null) {
|
if (contentWorld != null) {
|
||||||
contentWorlds.add(contentWorld);
|
contentWorlds.add(contentWorld);
|
||||||
}
|
}
|
||||||
|
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
ScriptHandler scriptHandler = WebViewCompat.addDocumentStartJavaScript(
|
||||||
|
webView,
|
||||||
|
pluginScript.getSource(),
|
||||||
|
pluginScript.getAllowedOriginRules()
|
||||||
|
);
|
||||||
|
this.scriptHandlerMap.put(pluginScript, scriptHandler);
|
||||||
|
}
|
||||||
return this.pluginScripts.get(pluginScript.getInjectionTime()).add(pluginScript);
|
return this.pluginScripts.get(pluginScript.getInjectionTime()).add(pluginScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,10 +261,26 @@ public class UserContentController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removePluginScript(PluginScript pluginScript) {
|
public boolean removePluginScript(PluginScript pluginScript) {
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
ScriptHandler scriptHandler = this.scriptHandlerMap.get(pluginScript);
|
||||||
|
if (scriptHandler != null) {
|
||||||
|
scriptHandler.remove();
|
||||||
|
this.scriptHandlerMap.remove(pluginScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.pluginScripts.get(pluginScript.getInjectionTime()).remove(pluginScript);
|
return this.pluginScripts.get(pluginScript.getInjectionTime()).remove(pluginScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllPluginScripts() {
|
public void removeAllPluginScripts() {
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
|
for (PluginScript pluginScript : this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START)) {
|
||||||
|
ScriptHandler scriptHandler = this.scriptHandlerMap.get(pluginScript);
|
||||||
|
if (scriptHandler != null) {
|
||||||
|
scriptHandler.remove();
|
||||||
|
this.scriptHandlerMap.remove(pluginScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START).clear();
|
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_START).clear();
|
||||||
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_END).clear();
|
this.pluginScripts.get(UserScriptInjectionTime.AT_DOCUMENT_END).clear();
|
||||||
}
|
}
|
||||||
|
@ -353,4 +416,9 @@ public class UserContentController {
|
||||||
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') { " +
|
||||||
" " + PluginScriptsUtil.VAR_PLACEHOLDER_VALUE +
|
" " + PluginScriptsUtil.VAR_PLACEHOLDER_VALUE +
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
webView = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@ package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class UserScript {
|
public class UserScript {
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -14,12 +17,19 @@ public class UserScript {
|
||||||
private UserScriptInjectionTime injectionTime;
|
private UserScriptInjectionTime injectionTime;
|
||||||
@NonNull
|
@NonNull
|
||||||
private ContentWorld contentWorld;
|
private ContentWorld contentWorld;
|
||||||
|
@NonNull
|
||||||
|
private Set<String> allowedOriginRules = new HashSet<>();
|
||||||
|
|
||||||
public UserScript(@Nullable String groupName, @NonNull String source, @NonNull UserScriptInjectionTime injectionTime, @Nullable ContentWorld contentWorld) {
|
public UserScript(@Nullable String groupName, @NonNull String source,
|
||||||
|
@NonNull UserScriptInjectionTime injectionTime, @Nullable ContentWorld contentWorld,
|
||||||
|
@Nullable Set<String> allowedOriginRules) {
|
||||||
this.groupName = groupName;
|
this.groupName = groupName;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.injectionTime = injectionTime;
|
this.injectionTime = injectionTime;
|
||||||
this.contentWorld = contentWorld == null ? ContentWorld.PAGE : contentWorld;
|
this.contentWorld = contentWorld == null ? ContentWorld.PAGE : contentWorld;
|
||||||
|
this.allowedOriginRules = allowedOriginRules == null ? new HashSet<String>() {{
|
||||||
|
add("*");
|
||||||
|
}} : allowedOriginRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -31,8 +41,9 @@ public class UserScript {
|
||||||
String source = (String) map.get("source");
|
String source = (String) map.get("source");
|
||||||
UserScriptInjectionTime injectionTime = UserScriptInjectionTime.fromValue((int) map.get("injectionTime"));
|
UserScriptInjectionTime injectionTime = UserScriptInjectionTime.fromValue((int) map.get("injectionTime"));
|
||||||
ContentWorld contentWorld = ContentWorld.fromMap((Map<String, Object>) map.get("contentWorld"));
|
ContentWorld contentWorld = ContentWorld.fromMap((Map<String, Object>) map.get("contentWorld"));
|
||||||
|
Set<String> allowedOriginRules = new HashSet<>((List<String>) map.get("allowedOriginRules"));
|
||||||
assert source != null;
|
assert source != null;
|
||||||
return new UserScript(groupName, source, injectionTime, contentWorld);
|
return new UserScript(groupName, source, injectionTime, contentWorld, allowedOriginRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -71,6 +82,15 @@ public class UserScript {
|
||||||
this.contentWorld = contentWorld == null ? ContentWorld.PAGE : contentWorld;
|
this.contentWorld = contentWorld == null ? ContentWorld.PAGE : contentWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Set<String> getAllowedOriginRules() {
|
||||||
|
return allowedOriginRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedOriginRules(@NonNull Set<String> allowedOriginRules) {
|
||||||
|
this.allowedOriginRules = allowedOriginRules;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
@ -78,10 +98,12 @@ public class UserScript {
|
||||||
|
|
||||||
UserScript that = (UserScript) o;
|
UserScript that = (UserScript) o;
|
||||||
|
|
||||||
if (groupName != null ? !groupName.equals(that.groupName) : that.groupName != null) return false;
|
if (groupName != null ? !groupName.equals(that.groupName) : that.groupName != null)
|
||||||
|
return false;
|
||||||
if (!source.equals(that.source)) return false;
|
if (!source.equals(that.source)) return false;
|
||||||
if (injectionTime != that.injectionTime) return false;
|
if (injectionTime != that.injectionTime) return false;
|
||||||
return contentWorld.equals(that.contentWorld);
|
if (!contentWorld.equals(that.contentWorld)) return false;
|
||||||
|
return allowedOriginRules.equals(that.allowedOriginRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -90,6 +112,7 @@ public class UserScript {
|
||||||
result = 31 * result + source.hashCode();
|
result = 31 * result + source.hashCode();
|
||||||
result = 31 * result + injectionTime.hashCode();
|
result = 31 * result + injectionTime.hashCode();
|
||||||
result = 31 * result + contentWorld.hashCode();
|
result = 31 * result + contentWorld.hashCode();
|
||||||
|
result = 31 * result + allowedOriginRules.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +123,7 @@ public class UserScript {
|
||||||
", source='" + source + '\'' +
|
", source='" + source + '\'' +
|
||||||
", injectionTime=" + injectionTime +
|
", injectionTime=" + injectionTime +
|
||||||
", contentWorld=" + contentWorld +
|
", contentWorld=" + contentWorld +
|
||||||
|
", allowedOriginRules=" + allowedOriginRules +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview;
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.PropertyValuesHolder;
|
import android.animation.PropertyValuesHolder;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
@ -96,9 +97,11 @@ 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;
|
||||||
|
|
||||||
|
@ -153,7 +156,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
public Runnable checkContextMenuShouldBeClosedTask;
|
public Runnable checkContextMenuShouldBeClosedTask;
|
||||||
public int newCheckContextMenuShouldBeClosedTaskTask = 100; // ms
|
public int newCheckContextMenuShouldBeClosedTaskTask = 100; // ms
|
||||||
|
|
||||||
public UserContentController userContentController = new UserContentController();
|
public UserContentController userContentController = new UserContentController(this);
|
||||||
|
|
||||||
public Map<String, ValueCallback<String>> callAsyncJavaScriptCallbacks = new HashMap<>();
|
public Map<String, ValueCallback<String>> callAsyncJavaScriptCallbacks = new HashMap<>();
|
||||||
public Map<String, ValueCallback<String>> evaluateJavaScriptContentWorldCallbacks = new HashMap<>();
|
public Map<String, ValueCallback<String>> evaluateJavaScriptContentWorldCallbacks = new HashMap<>();
|
||||||
|
@ -161,6 +164,8 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
public Map<String, WebMessageChannel> webMessageChannels = new HashMap<>();
|
public Map<String, WebMessageChannel> webMessageChannels = new HashMap<>();
|
||||||
public List<WebMessageListener> webMessageListeners = new ArrayList<>();
|
public List<WebMessageListener> webMessageListeners = new ArrayList<>();
|
||||||
|
|
||||||
|
private List<UserScript> initialUserOnlyScript = new ArrayList<>();
|
||||||
|
|
||||||
public InAppWebView(Context context) {
|
public InAppWebView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +190,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
this.windowId = windowId;
|
this.windowId = windowId;
|
||||||
this.customSettings = customSettings;
|
this.customSettings = customSettings;
|
||||||
this.contextMenu = contextMenu;
|
this.contextMenu = contextMenu;
|
||||||
this.userContentController.addUserOnlyScripts(userScripts);
|
this.initialUserOnlyScript = userScripts;
|
||||||
if (plugin != null && plugin.activity != null) {
|
if (plugin != null && plugin.activity != null) {
|
||||||
plugin.activity.registerForContextMenu(this);
|
plugin.activity.registerForContextMenu(this);
|
||||||
}
|
}
|
||||||
|
@ -208,24 +213,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
WebViewCompat.setWebViewRenderProcessClient(this, inAppWebViewRenderProcessClient);
|
WebViewCompat.setWebViewRenderProcessClient(this, inAppWebViewRenderProcessClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
userContentController.addPluginScript(PromisePolyfillJS.PROMISE_POLYFILL_JS_PLUGIN_SCRIPT);
|
prepareAndAddUserScripts();
|
||||||
userContentController.addPluginScript(JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT);
|
|
||||||
userContentController.addPluginScript(ConsoleLogJS.CONSOLE_LOG_JS_PLUGIN_SCRIPT);
|
|
||||||
userContentController.addPluginScript(PrintJS.PRINT_JS_PLUGIN_SCRIPT);
|
|
||||||
userContentController.addPluginScript(OnWindowBlurEventJS.ON_WINDOW_BLUR_EVENT_JS_PLUGIN_SCRIPT);
|
|
||||||
userContentController.addPluginScript(OnWindowFocusEventJS.ON_WINDOW_FOCUS_EVENT_JS_PLUGIN_SCRIPT);
|
|
||||||
if (customSettings.useShouldInterceptAjaxRequest) {
|
|
||||||
userContentController.addPluginScript(InterceptAjaxRequestJS.INTERCEPT_AJAX_REQUEST_JS_PLUGIN_SCRIPT);
|
|
||||||
}
|
|
||||||
if (customSettings.useShouldInterceptFetchRequest) {
|
|
||||||
userContentController.addPluginScript(InterceptFetchRequestJS.INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT);
|
|
||||||
}
|
|
||||||
if (customSettings.useOnLoadResource) {
|
|
||||||
userContentController.addPluginScript(OnLoadResourceJS.ON_LOAD_RESOURCE_JS_PLUGIN_SCRIPT);
|
|
||||||
}
|
|
||||||
if (!customSettings.useHybridComposition) {
|
|
||||||
userContentController.addPluginScript(PluginScriptsUtil.CHECK_GLOBAL_KEY_DOWN_EVENT_TO_HIDE_CONTEXT_MENU_JS_PLUGIN_SCRIPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customSettings.useOnDownloadStart)
|
if (customSettings.useOnDownloadStart)
|
||||||
setDownloadListener(new DownloadStartListener());
|
setDownloadListener(new DownloadStartListener());
|
||||||
|
@ -504,6 +492,28 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareAndAddUserScripts() {
|
||||||
|
userContentController.addPluginScript(PromisePolyfillJS.PROMISE_POLYFILL_JS_PLUGIN_SCRIPT);
|
||||||
|
userContentController.addPluginScript(JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT);
|
||||||
|
userContentController.addPluginScript(ConsoleLogJS.CONSOLE_LOG_JS_PLUGIN_SCRIPT);
|
||||||
|
userContentController.addPluginScript(PrintJS.PRINT_JS_PLUGIN_SCRIPT);
|
||||||
|
userContentController.addPluginScript(OnWindowBlurEventJS.ON_WINDOW_BLUR_EVENT_JS_PLUGIN_SCRIPT);
|
||||||
|
userContentController.addPluginScript(OnWindowFocusEventJS.ON_WINDOW_FOCUS_EVENT_JS_PLUGIN_SCRIPT);
|
||||||
|
if (customSettings.useShouldInterceptAjaxRequest) {
|
||||||
|
userContentController.addPluginScript(InterceptAjaxRequestJS.INTERCEPT_AJAX_REQUEST_JS_PLUGIN_SCRIPT);
|
||||||
|
}
|
||||||
|
if (customSettings.useShouldInterceptFetchRequest) {
|
||||||
|
userContentController.addPluginScript(InterceptFetchRequestJS.INTERCEPT_FETCH_REQUEST_JS_PLUGIN_SCRIPT);
|
||||||
|
}
|
||||||
|
if (customSettings.useOnLoadResource) {
|
||||||
|
userContentController.addPluginScript(OnLoadResourceJS.ON_LOAD_RESOURCE_JS_PLUGIN_SCRIPT);
|
||||||
|
}
|
||||||
|
if (!customSettings.useHybridComposition) {
|
||||||
|
userContentController.addPluginScript(PluginScriptsUtil.CHECK_GLOBAL_KEY_DOWN_EVENT_TO_HIDE_CONTEXT_MENU_JS_PLUGIN_SCRIPT);
|
||||||
|
}
|
||||||
|
this.userContentController.addUserOnlyScripts(this.initialUserOnlyScript);
|
||||||
|
}
|
||||||
|
|
||||||
public void setIncognito(boolean enabled) {
|
public void setIncognito(boolean enabled) {
|
||||||
WebSettings settings = getSettings();
|
WebSettings settings = getSettings();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
@ -1879,6 +1889,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
userContentController.dispose();
|
||||||
if (windowId != null) {
|
if (windowId != null) {
|
||||||
InAppWebViewChromeClient.windowWebViewMessages.remove(windowId);
|
InAppWebViewChromeClient.windowWebViewMessages.remove(windowId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview;
|
package com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -166,17 +167,19 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
public void loadCustomJavaScriptOnPageStarted(WebView view) {
|
public void loadCustomJavaScriptOnPageStarted(WebView view) {
|
||||||
InAppWebView webView = (InAppWebView) view;
|
InAppWebView webView = (InAppWebView) view;
|
||||||
|
|
||||||
|
if (!WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT)) {
|
||||||
String source = webView.userContentController.generateWrappedCodeForDocumentStart();
|
String source = webView.userContentController.generateWrappedCodeForDocumentStart();
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
webView.evaluateJavascript(source, (ValueCallback<String>) null);
|
webView.evaluateJavascript(source, (ValueCallback<String>) null);
|
||||||
} else {
|
} else {
|
||||||
webView.loadUrl("javascript:" + source.replaceAll("[\r\n]+", ""));
|
webView.loadUrl("javascript:" + source.replaceAll("[\r\n]+", ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void loadCustomJavaScriptOnPageFinished(WebView view) {
|
public void loadCustomJavaScriptOnPageFinished(WebView view) {
|
||||||
InAppWebView webView = (InAppWebView) view;
|
InAppWebView webView = (InAppWebView) view;
|
||||||
|
|
|
@ -96,7 +96,8 @@ public class WebMessageListener implements Disposable {
|
||||||
source,
|
source,
|
||||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
null
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,7 +586,7 @@ class ExchangeableObjectGenerator
|
||||||
getToMapValue('$genericTypeFieldName', genericType) +
|
getToMapValue('$genericTypeFieldName', genericType) +
|
||||||
').toList()';
|
').toList()';
|
||||||
} else {
|
} else {
|
||||||
return fieldName;
|
return elementType.isDartCoreSet ? "$fieldName${(isNullable ? '?' : '')}.toList()" : fieldName;
|
||||||
}
|
}
|
||||||
} else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) {
|
} else if (fieldTypeElement != null && hasToMapMethod(fieldTypeElement)) {
|
||||||
return fieldName +
|
return fieldName +
|
||||||
|
|
|
@ -6,6 +6,7 @@ import '../in_app_webview/in_app_webview_settings.dart';
|
||||||
import 'proxy_controller.dart';
|
import 'proxy_controller.dart';
|
||||||
import 'service_worker_controller.dart';
|
import 'service_worker_controller.dart';
|
||||||
import '../web_message/main.dart';
|
import '../web_message/main.dart';
|
||||||
|
import '../types/user_script_injection_time.dart';
|
||||||
|
|
||||||
part 'webview_feature.g.dart';
|
part 'webview_feature.g.dart';
|
||||||
|
|
||||||
|
@ -187,6 +188,10 @@ class WebViewFeature_ {
|
||||||
static const WEB_VIEW_RENDERER_TERMINATE =
|
static const WEB_VIEW_RENDERER_TERMINATE =
|
||||||
const WebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
|
const WebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
|
||||||
|
|
||||||
|
///This feature covers [UserScriptInjectionTime.AT_DOCUMENT_START].
|
||||||
|
static const DOCUMENT_START_SCRIPT =
|
||||||
|
const AndroidWebViewFeature_._internal("DOCUMENT_START_SCRIPT");
|
||||||
|
|
||||||
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
||||||
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
||||||
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
||||||
|
@ -386,6 +391,10 @@ class AndroidWebViewFeature_ {
|
||||||
static const WEB_VIEW_RENDERER_TERMINATE =
|
static const WEB_VIEW_RENDERER_TERMINATE =
|
||||||
const AndroidWebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
|
const AndroidWebViewFeature_._internal("WEB_VIEW_RENDERER_TERMINATE");
|
||||||
|
|
||||||
|
///This feature covers [UserScriptInjectionTime.AT_DOCUMENT_START].
|
||||||
|
static const DOCUMENT_START_SCRIPT =
|
||||||
|
const AndroidWebViewFeature_._internal("DOCUMENT_START_SCRIPT");
|
||||||
|
|
||||||
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
||||||
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
||||||
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
||||||
|
|
|
@ -189,6 +189,10 @@ class WebViewFeature {
|
||||||
static const WEB_VIEW_RENDERER_TERMINATE = WebViewFeature._internal(
|
static const WEB_VIEW_RENDERER_TERMINATE = WebViewFeature._internal(
|
||||||
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
|
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
|
||||||
|
|
||||||
|
///This feature covers [UserScriptInjectionTime.AT_DOCUMENT_START].
|
||||||
|
static const DOCUMENT_START_SCRIPT = WebViewFeature._internal(
|
||||||
|
'DOCUMENT_START_SCRIPT', 'DOCUMENT_START_SCRIPT');
|
||||||
|
|
||||||
///Set of all values of [WebViewFeature].
|
///Set of all values of [WebViewFeature].
|
||||||
static final Set<WebViewFeature> values = [
|
static final Set<WebViewFeature> values = [
|
||||||
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||||
|
@ -232,6 +236,7 @@ class WebViewFeature {
|
||||||
WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
||||||
WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
||||||
WebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
WebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
||||||
|
WebViewFeature.DOCUMENT_START_SCRIPT,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
///Gets a possible [WebViewFeature] instance from [String] value.
|
///Gets a possible [WebViewFeature] instance from [String] value.
|
||||||
|
@ -479,6 +484,10 @@ class AndroidWebViewFeature {
|
||||||
static const WEB_VIEW_RENDERER_TERMINATE = AndroidWebViewFeature._internal(
|
static const WEB_VIEW_RENDERER_TERMINATE = AndroidWebViewFeature._internal(
|
||||||
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
|
'WEB_VIEW_RENDERER_TERMINATE', 'WEB_VIEW_RENDERER_TERMINATE');
|
||||||
|
|
||||||
|
///This feature covers [UserScriptInjectionTime.AT_DOCUMENT_START].
|
||||||
|
static const DOCUMENT_START_SCRIPT = AndroidWebViewFeature._internal(
|
||||||
|
'DOCUMENT_START_SCRIPT', 'DOCUMENT_START_SCRIPT');
|
||||||
|
|
||||||
///Set of all values of [AndroidWebViewFeature].
|
///Set of all values of [AndroidWebViewFeature].
|
||||||
static final Set<AndroidWebViewFeature> values = [
|
static final Set<AndroidWebViewFeature> values = [
|
||||||
AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||||
|
@ -522,6 +531,7 @@ class AndroidWebViewFeature {
|
||||||
AndroidWebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
AndroidWebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
||||||
AndroidWebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
AndroidWebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
||||||
AndroidWebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
AndroidWebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
||||||
|
AndroidWebViewFeature.DOCUMENT_START_SCRIPT,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
///Gets a possible [AndroidWebViewFeature] instance from [String] value.
|
///Gets a possible [AndroidWebViewFeature] instance from [String] value.
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_i
|
||||||
import '../in_app_webview/webview.dart';
|
import '../in_app_webview/webview.dart';
|
||||||
import 'user_script_injection_time.dart';
|
import 'user_script_injection_time.dart';
|
||||||
import 'content_world.dart';
|
import 'content_world.dart';
|
||||||
|
import '../android/webview_feature.dart';
|
||||||
|
|
||||||
part 'user_script.g.dart';
|
part 'user_script.g.dart';
|
||||||
|
|
||||||
|
@ -29,6 +30,11 @@ class UserScript_ {
|
||||||
///**NOTE**: available only on iOS.
|
///**NOTE**: available only on iOS.
|
||||||
bool forMainFrameOnly;
|
bool forMainFrameOnly;
|
||||||
|
|
||||||
|
///A set of matching rules for the allowed origins.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on Android and only if [WebViewFeature.DOCUMENT_START_SCRIPT] feature is supported.
|
||||||
|
late Set<String> allowedOriginRules;
|
||||||
|
|
||||||
///A scope of execution in which to evaluate the script to prevent conflicts between different scripts.
|
///A scope of execution in which to evaluate the script to prevent conflicts between different scripts.
|
||||||
///For more information about content worlds, see [ContentWorld].
|
///For more information about content worlds, see [ContentWorld].
|
||||||
late ContentWorld contentWorld;
|
late ContentWorld contentWorld;
|
||||||
|
@ -40,7 +46,10 @@ class UserScript_ {
|
||||||
required this.injectionTime,
|
required this.injectionTime,
|
||||||
@Deprecated("Use forMainFrameOnly instead") this.iosForMainFrameOnly,
|
@Deprecated("Use forMainFrameOnly instead") this.iosForMainFrameOnly,
|
||||||
this.forMainFrameOnly = true,
|
this.forMainFrameOnly = true,
|
||||||
|
Set<String>? allowedOriginRules,
|
||||||
ContentWorld? contentWorld}) {
|
ContentWorld? contentWorld}) {
|
||||||
|
this.allowedOriginRules = allowedOriginRules != null ?
|
||||||
|
allowedOriginRules : Set.from(["*"]);
|
||||||
this.contentWorld = contentWorld ?? ContentWorld.PAGE;
|
this.contentWorld = contentWorld ?? ContentWorld.PAGE;
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
this.forMainFrameOnly = this.iosForMainFrameOnly != null
|
this.forMainFrameOnly = this.iosForMainFrameOnly != null
|
||||||
|
|
|
@ -28,6 +28,11 @@ class UserScript {
|
||||||
///**NOTE**: available only on iOS.
|
///**NOTE**: available only on iOS.
|
||||||
bool forMainFrameOnly;
|
bool forMainFrameOnly;
|
||||||
|
|
||||||
|
///A set of matching rules for the allowed origins.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on Android and only if [WebViewFeature.DOCUMENT_START_SCRIPT] feature is supported.
|
||||||
|
late Set<String> allowedOriginRules;
|
||||||
|
|
||||||
///A scope of execution in which to evaluate the script to prevent conflicts between different scripts.
|
///A scope of execution in which to evaluate the script to prevent conflicts between different scripts.
|
||||||
///For more information about content worlds, see [ContentWorld].
|
///For more information about content worlds, see [ContentWorld].
|
||||||
late ContentWorld contentWorld;
|
late ContentWorld contentWorld;
|
||||||
|
@ -37,7 +42,10 @@ class UserScript {
|
||||||
required this.injectionTime,
|
required this.injectionTime,
|
||||||
@Deprecated("Use forMainFrameOnly instead") this.iosForMainFrameOnly,
|
@Deprecated("Use forMainFrameOnly instead") this.iosForMainFrameOnly,
|
||||||
this.forMainFrameOnly = true,
|
this.forMainFrameOnly = true,
|
||||||
|
Set<String>? allowedOriginRules,
|
||||||
ContentWorld? contentWorld}) {
|
ContentWorld? contentWorld}) {
|
||||||
|
this.allowedOriginRules =
|
||||||
|
allowedOriginRules != null ? allowedOriginRules : Set.from(["*"]);
|
||||||
this.contentWorld = contentWorld ?? ContentWorld.PAGE;
|
this.contentWorld = contentWorld ?? ContentWorld.PAGE;
|
||||||
this.forMainFrameOnly = this.iosForMainFrameOnly != null
|
this.forMainFrameOnly = this.iosForMainFrameOnly != null
|
||||||
? this.iosForMainFrameOnly!
|
? this.iosForMainFrameOnly!
|
||||||
|
@ -57,6 +65,7 @@ class UserScript {
|
||||||
iosForMainFrameOnly: map['forMainFrameOnly'],
|
iosForMainFrameOnly: map['forMainFrameOnly'],
|
||||||
);
|
);
|
||||||
instance.forMainFrameOnly = map['forMainFrameOnly'];
|
instance.forMainFrameOnly = map['forMainFrameOnly'];
|
||||||
|
instance.allowedOriginRules = map['allowedOriginRules'].cast<String>();
|
||||||
instance.contentWorld = map['contentWorld'];
|
instance.contentWorld = map['contentWorld'];
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +77,7 @@ class UserScript {
|
||||||
"source": source,
|
"source": source,
|
||||||
"injectionTime": injectionTime.toNativeValue(),
|
"injectionTime": injectionTime.toNativeValue(),
|
||||||
"forMainFrameOnly": forMainFrameOnly,
|
"forMainFrameOnly": forMainFrameOnly,
|
||||||
|
"allowedOriginRules": allowedOriginRules.toList(),
|
||||||
"contentWorld": contentWorld.toMap(),
|
"contentWorld": contentWorld.toMap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -79,6 +89,6 @@ class UserScript {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'UserScript{groupName: $groupName, source: $source, injectionTime: $injectionTime, forMainFrameOnly: $forMainFrameOnly, contentWorld: $contentWorld}';
|
return 'UserScript{groupName: $groupName, source: $source, injectionTime: $injectionTime, forMainFrameOnly: $forMainFrameOnly, allowedOriginRules: $allowedOriginRules, contentWorld: $contentWorld}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue