added clearHistory webview methods on Android, setContextMenu and clearFocus webview methods, added ContextMenuOptions class
This commit is contained in:
parent
ad56ca6621
commit
9f9232e1f3
|
@ -3,12 +3,14 @@
|
|||
- Updated API docs
|
||||
- Updated Android context menu workaround
|
||||
- Calling `onCreateContextMenu` event on iOS also when the context menu is disabled in order to have the same effect as Android
|
||||
- Added `options` attribute to `ContextMenu` class and created `ContextMenuOptions` class
|
||||
- Added Android keyboard workaround to hide the keyboard when clicking other HTML elements, losing the focus on the previous input
|
||||
- Added `onEnterFullscreen`, `onExitFullscreen` webview events [#275](https://github.com/pichillilorenzo/flutter_inappwebview/issues/275)
|
||||
- Added Android support to use camera on HTML inputs that requires it, such as `<input type="file" accept="image/*" capture>` [#353](https://github.com/pichillilorenzo/flutter_inappwebview/issues/353)
|
||||
- Added `overScrollMode`, `networkAvailable`, `scrollBarStyle`, `verticalScrollbarPosition`, `scrollBarDefaultDelayBeforeFade`, `scrollbarFadingEnabled`, `scrollBarFadeDuration`, `rendererPriorityPolicy`, `useShouldInterceptRequest`, `useOnRenderProcessGone` webview options on Android
|
||||
- Added `pageDown`, `pageUp`, `saveWebArchive`, `zoomIn`, `zoomOut` webview methods on Android
|
||||
- Added `pageDown`, `pageUp`, `saveWebArchive`, `zoomIn`, `zoomOut`, `clearHistory` webview methods on Android
|
||||
- Added `getCurrentWebViewPackage` static webview method on Android
|
||||
- Added `setContextMenu`, `clearFocus` methods to webview controller
|
||||
- Added `onPageCommitVisible` webview event
|
||||
- Added `androidShouldInterceptRequest`, `androidOnRenderProcessUnresponsive`, `androidOnRenderProcessResponsive`, `androidOnRenderProcessGone`, `androidOnFormResubmission`, `androidOnScaleChanged` Android events
|
||||
- Added `toString()` method to various classes in order to have a better output instead of simply `Instance of ...`
|
||||
|
@ -23,6 +25,7 @@
|
|||
|
||||
- Android `clearClientCertPreferences`, `getSafeBrowsingPrivacyPolicyUrl`, `setSafeBrowsingWhitelist` webview methods are static now
|
||||
- Removed iOS event `onDidCommit`; it has been renamed to `onPageCommitVisible` and made cross-platform
|
||||
- `contextMenu` is `final` now
|
||||
|
||||
## 3.2.0
|
||||
|
||||
|
|
25
README.md
25
README.md
|
@ -400,6 +400,8 @@ Screenshots:
|
|||
* `getScale`: Gets the current scale of this WebView.
|
||||
* `getSelectedText`: Gets the selected text.
|
||||
* `getHitTestResult`: Gets the hit result for hitting an HTML elements.
|
||||
* `clearFocus`: Clears the current focus. It will clear also, for example, the current text selection.
|
||||
* `setContextMenu(ContextMenu contextMenu)`: Sets or updates the WebView context menu to be used next time it will appear.
|
||||
* `static getDefaultUserAgent`: Gets the default user agent.
|
||||
|
||||
##### `InAppWebViewController` Android-specific methods
|
||||
|
@ -416,6 +418,7 @@ Android-specific methods can be called using the `InAppWebViewController.android
|
|||
* `saveWebArchive({@required String basename, @required bool autoname})`: Saves the current view as a web archive.
|
||||
* `zoomIn`: Performs zoom in in this WebView.
|
||||
* `zoomOut`: Performs zoom out in this WebView.
|
||||
* `clearHistory`: Clears the internal back/forward list.
|
||||
* `static clearClientCertPreferences`: Clears the client certificate preferences stored in response to proceeding/cancelling client cert requests.
|
||||
* `static getSafeBrowsingPrivacyPolicyUrl`: Returns a URL pointing to the privacy policy for Safe Browsing reporting. This value will never be `null`.
|
||||
* `static setSafeBrowsingWhitelist({@required List<String> hosts})`: Sets the list of hosts (domain names/IP addresses) that are exempt from SafeBrowsing checks. The list is global for all the WebViews.
|
||||
|
@ -665,6 +668,11 @@ class _MyAppState extends State<MyApp> {
|
|||
super.initState();
|
||||
|
||||
contextMenu = ContextMenu(
|
||||
menuItems: [
|
||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||
print("Menu item Special clicked!");
|
||||
})
|
||||
],
|
||||
onCreateContextMenu: (hitTestResult) async {
|
||||
print("onCreateContextMenu");
|
||||
print(hitTestResult.extra);
|
||||
|
@ -679,12 +687,6 @@ class _MyAppState extends State<MyApp> {
|
|||
}
|
||||
);
|
||||
|
||||
contextMenu.menuItems = [
|
||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||
print("Menu item Special clicked!");
|
||||
})
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -782,6 +784,10 @@ class _MyAppState extends State<MyApp> {
|
|||
}
|
||||
```
|
||||
|
||||
### `ContextMenu` options
|
||||
|
||||
* `hideDefaultSystemContextMenuItems`: Whether all the default system context menu items should be hidden or not. The default value is `false`.
|
||||
|
||||
### `ContextMenu` Events
|
||||
|
||||
* `onCreateContextMenu`: Event fired when the context menu for this WebView is being built.
|
||||
|
@ -1118,7 +1124,7 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
}
|
||||
|
||||
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||
|
||||
|
||||
MyChromeSafariBrowser(browserFallback) : super(bFallback: browserFallback);
|
||||
|
||||
@override
|
||||
|
@ -1146,7 +1152,7 @@ void main() {
|
|||
|
||||
class MyApp extends StatefulWidget {
|
||||
final ChromeSafariBrowser browser = new MyChromeSafariBrowser(new MyInAppBrowser());
|
||||
|
||||
|
||||
@override
|
||||
_MyAppState createState() => new _MyAppState();
|
||||
}
|
||||
|
@ -1182,7 +1188,7 @@ class _MyAppState extends State<MyApp> {
|
|||
url: "https://flutter.dev/",
|
||||
options: ChromeSafariBrowserClassOptions(
|
||||
android: AndroidChromeCustomTabsOptions(addDefaultShareMenuItem: false),
|
||||
ios: IosSafariOptions(barCollapsingEnabled: true)));
|
||||
ios: IOSSafariOptions(barCollapsingEnabled: true)));
|
||||
},
|
||||
child: Text("Open Chrome Safari Browser")),
|
||||
),
|
||||
|
@ -1190,7 +1196,6 @@ class _MyAppState extends State<MyApp> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Screenshots:
|
||||
|
|
|
@ -365,6 +365,17 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
|
|||
case "zoomOut":
|
||||
result.success(zoomOut());
|
||||
break;
|
||||
case "clearFocus":
|
||||
clearFocus();
|
||||
result.success(true);
|
||||
break;
|
||||
case "setContextMenu":
|
||||
{
|
||||
Map<String, Object> contextMenu = (Map<String, Object>) call.argument("contextMenu");
|
||||
setContextMenu(contextMenu);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
@ -909,6 +920,16 @@ public class InAppBrowserActivity extends AppCompatActivity implements MethodCha
|
|||
return false;
|
||||
}
|
||||
|
||||
public void clearFocus() {
|
||||
if (webView != null)
|
||||
webView.clearFocus();
|
||||
}
|
||||
|
||||
public void setContextMenu(Map<String, Object> contextMenu) {
|
||||
if (webView != null)
|
||||
webView.contextMenu = contextMenu;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
activityResultListeners.clear();
|
||||
|
|
|
@ -30,10 +30,10 @@ public class InAppBrowserOptions implements Options<InAppBrowserActivity> {
|
|||
|
||||
switch (key) {
|
||||
case "hidden":
|
||||
hidden = (boolean) value;
|
||||
hidden = (Boolean) value;
|
||||
break;
|
||||
case "toolbarTop":
|
||||
toolbarTop = (boolean) value;
|
||||
toolbarTop = (Boolean) value;
|
||||
break;
|
||||
case "toolbarTopBackgroundColor":
|
||||
toolbarTopBackgroundColor = (String) value;
|
||||
|
@ -42,16 +42,16 @@ public class InAppBrowserOptions implements Options<InAppBrowserActivity> {
|
|||
toolbarTopFixedTitle = (String) value;
|
||||
break;
|
||||
case "hideUrlBar":
|
||||
hideUrlBar = (boolean) value;
|
||||
hideUrlBar = (Boolean) value;
|
||||
break;
|
||||
case "hideTitleBar":
|
||||
hideTitleBar = (boolean) value;
|
||||
hideTitleBar = (Boolean) value;
|
||||
break;
|
||||
case "closeOnCannotGoBack":
|
||||
closeOnCannotGoBack = (boolean) value;
|
||||
closeOnCannotGoBack = (Boolean) value;
|
||||
break;
|
||||
case "progressBar":
|
||||
progressBar = (boolean) value;
|
||||
progressBar = (Boolean) value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.Options;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContextMenuOptions implements Options<Object> {
|
||||
public static final String LOG_TAG = "ContextMenuOptions";
|
||||
|
||||
public Boolean hideDefaultSystemContextMenuItems = false;
|
||||
|
||||
public ContextMenuOptions parse(Map<String, Object> options) {
|
||||
for (Map.Entry<String, Object> pair : options.entrySet()) {
|
||||
String key = pair.getKey();
|
||||
Object value = pair.getValue();
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case "hideDefaultSystemContextMenuItems":
|
||||
hideDefaultSystemContextMenuItems = (Boolean) value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("hideDefaultSystemContextMenuItems", hideDefaultSystemContextMenuItems);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRealOptions(Object webView) {
|
||||
Map<String, Object> realOptions = toMap();
|
||||
return realOptions;
|
||||
}
|
||||
|
||||
}
|
|
@ -52,8 +52,8 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
|||
final String initialFile = (String) params.get("initialFile");
|
||||
final Map<String, String> initialData = (Map<String, String>) params.get("initialData");
|
||||
final Map<String, String> initialHeaders = (Map<String, String>) params.get("initialHeaders");
|
||||
HashMap<String, Object> initialOptions = (HashMap<String, Object>) params.get("initialOptions");
|
||||
HashMap<String, Object> contextMenu = (HashMap<String, Object>) params.get("contextMenu");
|
||||
Map<String, Object> initialOptions = (Map<String, Object>) params.get("initialOptions");
|
||||
Map<String, Object> contextMenu = (Map<String, Object>) params.get("contextMenu");
|
||||
|
||||
InAppWebViewOptions options = new InAppWebViewOptions();
|
||||
options.parse(initialOptions);
|
||||
|
@ -440,6 +440,23 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
|||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "clearFocus":
|
||||
if (webView != null) {
|
||||
webView.clearFocus();
|
||||
result.success(true);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "setContextMenu":
|
||||
if (webView != null) {
|
||||
Map<String, Object> contextMenu = (Map<String, Object>) call.argument("contextMenu");
|
||||
webView.contextMenu = contextMenu;
|
||||
result.success(true);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
public Pattern regexToCancelSubFramesLoadingCompiled;
|
||||
public GestureDetector gestureDetector = null;
|
||||
public LinearLayout floatingContextMenu = null;
|
||||
public HashMap<String, Object> contextMenu = null;
|
||||
public Map<String, Object> contextMenu = null;
|
||||
public Handler headlessHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public Runnable checkScrollStoppedTask;
|
||||
|
@ -608,7 +608,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
super(context, attrs, defaultStyle);
|
||||
}
|
||||
|
||||
public InAppWebView(Context context, Object obj, Object id, InAppWebViewOptions options, HashMap<String, Object> contextMenu, View containerView) {
|
||||
public InAppWebView(Context context, Object obj, Object id, InAppWebViewOptions options, Map<String, Object> contextMenu, View containerView) {
|
||||
super(context, containerView);
|
||||
if (obj instanceof InAppBrowserActivity)
|
||||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||
|
@ -1597,10 +1597,49 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
HorizontalScrollView horizontalScrollView = (HorizontalScrollView) floatingContextMenu.getChildAt(0);
|
||||
LinearLayout menuItemListLayout = (LinearLayout) horizontalScrollView.getChildAt(0);
|
||||
|
||||
for (int i = 0; i < actionMenu.size(); i++) {
|
||||
final MenuItem menuItem = actionMenu.getItem(i);
|
||||
final int itemId = menuItem.getItemId();
|
||||
final String itemTitle = menuItem.getTitle().toString();
|
||||
List<Map<String, Object>> customMenuItems = new ArrayList<>();
|
||||
ContextMenuOptions contextMenuOptions = new ContextMenuOptions();
|
||||
if (contextMenu != null) {
|
||||
customMenuItems = (List<Map<String, Object>>) contextMenu.get("menuItems");
|
||||
Map<String, Object> contextMenuOptionsMap = (Map<String, Object>) contextMenu.get("options");
|
||||
if (contextMenuOptionsMap != null) {
|
||||
contextMenuOptions.parse(contextMenuOptionsMap);
|
||||
}
|
||||
}
|
||||
customMenuItems = customMenuItems == null ? new ArrayList<Map<String, Object>>() : customMenuItems;
|
||||
|
||||
if (contextMenuOptions.hideDefaultSystemContextMenuItems == null || !contextMenuOptions.hideDefaultSystemContextMenuItems) {
|
||||
for (int i = 0; i < actionMenu.size(); i++) {
|
||||
final MenuItem menuItem = actionMenu.getItem(i);
|
||||
final int itemId = menuItem.getItemId();
|
||||
final String itemTitle = menuItem.getTitle().toString();
|
||||
TextView text = (TextView) LayoutInflater.from(this.getContext())
|
||||
.inflate(R.layout.floating_action_mode_item, this, false);
|
||||
text.setText(itemTitle);
|
||||
text.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
hideContextMenu();
|
||||
callback.onActionItemClicked(actionMode, menuItem);
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("androidId", itemId);
|
||||
obj.put("iosId", null);
|
||||
obj.put("title", itemTitle);
|
||||
channel.invokeMethod("onContextMenuActionItemClicked", obj);
|
||||
}
|
||||
});
|
||||
if (floatingContextMenu != null) {
|
||||
menuItemListLayout.addView(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final Map<String, Object> menuItem : customMenuItems) {
|
||||
final int itemId = (int) menuItem.get("androidId");
|
||||
final String itemTitle = (String) menuItem.get("title");
|
||||
TextView text = (TextView) LayoutInflater.from(this.getContext())
|
||||
.inflate(R.layout.floating_action_mode_item, this, false);
|
||||
text.setText(itemTitle);
|
||||
|
@ -1608,7 +1647,6 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
hideContextMenu();
|
||||
callback.onActionItemClicked(actionMode, menuItem);
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
|
@ -1621,38 +1659,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
});
|
||||
if (floatingContextMenu != null) {
|
||||
menuItemListLayout.addView(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (contextMenu != null) {
|
||||
List<HashMap<String, Object>> customMenuItems = (List<HashMap<String, Object>>) contextMenu.get("menuItems");
|
||||
if (customMenuItems != null) {
|
||||
for (final HashMap<String, Object> menuItem : customMenuItems) {
|
||||
final int itemId = (int) menuItem.get("androidId");
|
||||
final String itemTitle = (String) menuItem.get("title");
|
||||
TextView text = (TextView) LayoutInflater.from(this.getContext())
|
||||
.inflate(R.layout.floating_action_mode_item, this, false);
|
||||
text.setText(itemTitle);
|
||||
text.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// clearFocus();
|
||||
hideContextMenu();
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("androidId", itemId);
|
||||
obj.put("iosId", null);
|
||||
obj.put("title", itemTitle);
|
||||
channel.invokeMethod("onContextMenuActionItemClicked", obj);
|
||||
}
|
||||
});
|
||||
if (floatingContextMenu != null) {
|
||||
menuItemListLayout.addView(text);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@ package com.pichillilorenzo.flutter_inappwebview;
|
|||
import java.util.Map;
|
||||
|
||||
public interface Options<T> {
|
||||
static String LOG_TAG = "Options";
|
||||
public Options parse(Map<String, Object> options);
|
||||
public Map<String, Object> toMap();
|
||||
public Map<String, Object> getRealOptions(T webView);
|
||||
public Map<String, Object> getRealOptions(T obj);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"android":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-05-29 19:53:44.213613","version":"1.17.1"}
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"android":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-05-30 19:55:39.840707","version":"1.17.1"}
|
|
@ -23,6 +23,16 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
super.initState();
|
||||
|
||||
contextMenu = ContextMenu(
|
||||
menuItems: [
|
||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||
print("Menu item Special clicked!");
|
||||
print(await webView.getSelectedText());
|
||||
await webView.clearFocus();
|
||||
})
|
||||
],
|
||||
options: ContextMenuOptions(
|
||||
hideDefaultSystemContextMenuItems: true
|
||||
),
|
||||
onCreateContextMenu: (hitTestResult) async {
|
||||
print("onCreateContextMenu");
|
||||
print(hitTestResult.extra);
|
||||
|
@ -31,16 +41,11 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
onHideContextMenu: () {
|
||||
print("onHideContextMenu");
|
||||
},
|
||||
onContextMenuActionItemClicked: (contextMenuItemClicked) {
|
||||
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
|
||||
var id = (Platform.isAndroid) ? contextMenuItemClicked.androidId : contextMenuItemClicked.iosId;
|
||||
print("onContextMenuActionItemClicked: " + id.toString() + " " + contextMenuItemClicked.title);
|
||||
}
|
||||
);
|
||||
contextMenu.menuItems = [
|
||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||
print("Menu item Special clicked!");
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -74,17 +79,14 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
||||
child: InAppWebView(
|
||||
contextMenu: contextMenu,
|
||||
// initialUrl: "https://github.com/flutter",
|
||||
initialFile: "assets/index.html",
|
||||
initialUrl: "https://github.com/flutter",
|
||||
// initialFile: "assets/index.html",
|
||||
initialHeaders: {},
|
||||
initialOptions: InAppWebViewGroupOptions(
|
||||
crossPlatform: InAppWebViewOptions(
|
||||
debuggingEnabled: true,
|
||||
useShouldOverrideUrlLoading: true
|
||||
),
|
||||
android: AndroidInAppWebViewOptions(
|
||||
supportMultipleWindows: true
|
||||
)
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// ContextMenuOptions.swift
|
||||
// flutter_inappwebview
|
||||
//
|
||||
// Created by Lorenzo Pichilli on 30/05/2020.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ContextMenuOptions: Options<NSObject> {
|
||||
|
||||
var hideDefaultSystemContextMenuItems = false;
|
||||
|
||||
override init(){
|
||||
super.init()
|
||||
}
|
||||
}
|
|
@ -426,6 +426,23 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
result(nil)
|
||||
}
|
||||
break
|
||||
case "clearFocus":
|
||||
if webView != nil {
|
||||
webView!.clearFocus()
|
||||
result(true)
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "setContextMenu":
|
||||
if webView != nil {
|
||||
let contextMenu = arguments!["contextMenu"] as? [String: Any]
|
||||
webView!.contextMenu = contextMenu
|
||||
result(true)
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
|
|
|
@ -308,6 +308,24 @@ public class InAppBrowserWebViewController: UIViewController, FlutterPlugin, UIS
|
|||
result(nil)
|
||||
}
|
||||
break
|
||||
case "clearFocus":
|
||||
if webView != nil {
|
||||
webView!.clearFocus()
|
||||
result(true)
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
|
||||
break
|
||||
case "setContextMenu":
|
||||
if webView != nil {
|
||||
let contextMenu = arguments!["contextMenu"] as? [String: Any]
|
||||
webView!.contextMenu = contextMenu
|
||||
result(true)
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
|
|
|
@ -905,6 +905,16 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
return false
|
||||
}
|
||||
|
||||
if let menu = contextMenu {
|
||||
let contextMenuOptions = ContextMenuOptions()
|
||||
if let contextMenuOptionsMap = menu["options"] as? [String: Any?] {
|
||||
let _ = contextMenuOptions.parse(options: contextMenuOptionsMap)
|
||||
if !action.description.starts(with: "onContextMenuActionItemClicked-") && contextMenuOptions.hideDefaultSystemContextMenuItems {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if contextMenuIsShowing, !action.description.starts(with: "onContextMenuActionItemClicked-") {
|
||||
let id = action.description.compactMap({ $0.asciiValue?.description }).joined()
|
||||
let arguments: [String: Any?] = [
|
||||
|
@ -2729,6 +2739,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
}
|
||||
}
|
||||
|
||||
public func clearFocus() {
|
||||
self.scrollView.subviews.first?.resignFirstResponder()
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
stopLoading()
|
||||
configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_inappwebview/src/webview.dart';
|
||||
|
||||
import 'webview.dart';
|
||||
import 'types.dart';
|
||||
|
||||
///Class that represents the WebView context menu. It used by [WebView.contextMenu].
|
||||
|
@ -22,24 +22,35 @@ class ContextMenu {
|
|||
final void Function(ContextMenuItem contextMenuItemClicked)
|
||||
onContextMenuActionItemClicked;
|
||||
|
||||
///Context menu options.
|
||||
final ContextMenuOptions options;
|
||||
|
||||
///List of the custom [ContextMenuItem].
|
||||
List<ContextMenuItem> menuItems = List();
|
||||
final List<ContextMenuItem> menuItems;
|
||||
|
||||
ContextMenu(
|
||||
{this.menuItems,
|
||||
{this.menuItems = const [],
|
||||
this.onCreateContextMenu,
|
||||
this.onHideContextMenu,
|
||||
this.onContextMenuActionItemClicked});
|
||||
this.options,
|
||||
this.onContextMenuActionItemClicked})
|
||||
: assert(menuItems != null);
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"menuItems": menuItems.map((menuItem) => menuItem?.toMap()).toList()
|
||||
"menuItems": menuItems.map((menuItem) => menuItem?.toMap()).toList(),
|
||||
"options": options?.toMap()
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return this.toMap();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return toMap().toString();
|
||||
}
|
||||
}
|
||||
|
||||
///Class that represent an item of the [ContextMenu].
|
||||
|
@ -69,4 +80,32 @@ class ContextMenuItem {
|
|||
Map<String, dynamic> toJson() {
|
||||
return this.toMap();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return toMap().toString();
|
||||
}
|
||||
}
|
||||
|
||||
///Class that represents available options used by [ContextMenu].
|
||||
class ContextMenuOptions {
|
||||
///Whether all the default system context menu items should be hidden or not. The default value is `false`.
|
||||
bool hideDefaultSystemContextMenuItems;
|
||||
|
||||
ContextMenuOptions({this.hideDefaultSystemContextMenuItems = false});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"hideDefaultSystemContextMenuItems": hideDefaultSystemContextMenuItems
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return this.toMap();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return toMap().toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ import 'types.dart';
|
|||
///This class uses the native WebView of the platform.
|
||||
///The [webViewController] field can be used to access the [InAppWebViewController] API.
|
||||
class InAppBrowser {
|
||||
///Browser's UUID
|
||||
///Browser's UUID.
|
||||
String uuid;
|
||||
|
||||
///Context menu used by the browser
|
||||
///Context menu used by the browser. It should be set before opening the browser.
|
||||
ContextMenu contextMenu;
|
||||
|
||||
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
|
||||
|
|
|
@ -1487,6 +1487,23 @@ class InAppWebViewController {
|
|||
return InAppWebViewHitTestResult(type: type, extra: extra);
|
||||
}
|
||||
|
||||
///Clears the current focus. It will clear also, for example, the current text selection.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/view/ViewGroup#clearFocus()
|
||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiresponder/1621097-resignfirstresponder
|
||||
Future<void> clearFocus() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _channel.invokeMethod('clearFocus', args);
|
||||
}
|
||||
|
||||
///Sets or updates the WebView context menu to be used next time it will appear.
|
||||
Future<void> setContextMenu(ContextMenu contextMenu) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("contextMenu", () => contextMenu?.toMap());
|
||||
await _channel.invokeMethod('setContextMenu', args);
|
||||
_inAppBrowser?.contextMenu = contextMenu;
|
||||
}
|
||||
|
||||
///Gets the default user agent.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebSettings#getDefaultUserAgent(android.content.Context)
|
||||
|
@ -1617,6 +1634,14 @@ class AndroidInAppWebViewController {
|
|||
return await _controller._channel.invokeMethod('zoomOut', args);
|
||||
}
|
||||
|
||||
///Clears the internal back/forward list.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#clearHistory()
|
||||
Future<void> clearHistory() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _controller._channel.invokeMethod('clearHistory', args);
|
||||
}
|
||||
|
||||
///Clears the client certificate preferences stored in response to proceeding/cancelling client cert requests.
|
||||
///Note that WebView automatically clears these preferences when the system keychain is updated.
|
||||
///The preferences are shared by all the WebViews that are created by the embedder application.
|
||||
|
|
Loading…
Reference in New Issue