Added 'values' property for all the custom Enums, bug fixes
This commit is contained in:
parent
b0c06c6146
commit
64246d84d9
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -3,15 +3,21 @@
|
||||||
- Added `requestFocusNodeHref`, `requestImageRef`, `getMetaTags`, `getMetaThemeColor`, `getScrollX`, `getScrollY`, `getCertificate` webview methods
|
- Added `requestFocusNodeHref`, `requestImageRef`, `getMetaTags`, `getMetaThemeColor`, `getScrollX`, `getScrollY`, `getCertificate` webview methods
|
||||||
- Added `WebStorage`, `LocalStorage` and `SessionStorage` class to manage `window.localStorage` and `window.sessionStorage` JavaScript [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)
|
- Added `WebStorage`, `LocalStorage` and `SessionStorage` class to manage `window.localStorage` and `window.sessionStorage` JavaScript [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)
|
||||||
- Added `supportZoom` webview option also on iOS
|
- Added `supportZoom` webview option also on iOS
|
||||||
- Added `HttpOnly`, `SameSite` set cookie options
|
- Added `HttpOnly`, `SameSite` cookie options
|
||||||
- Updated `Cookie` class
|
- Updated `Cookie` class
|
||||||
- Added `animated` option to `scrollTo` and `scrollBy` webview methods
|
- Added `animated` option to `scrollTo` and `scrollBy` webview methods
|
||||||
- Added error and message to the `ServerTrustChallenge` class for iOS (class used by the `onReceivedServerTrustAuthRequest` event)
|
- Added error and message to the `ServerTrustChallenge` class for iOS (class used by the `onReceivedServerTrustAuthRequest` event)
|
||||||
- Added `contentInsetAdjustmentBehavior` webview iOS-specific option
|
- Added `contentInsetAdjustmentBehavior` webview iOS-specific option
|
||||||
- Added `copy` and `copyWithValue` methods for webview class options
|
- Added `copy` methods for webview class options
|
||||||
- Added `SslCertificate` class and `X509Certificate` class and parser
|
- Added `SslCertificate` class and `X509Certificate` class and parser
|
||||||
|
- Added `values` property for all the custom Enums
|
||||||
|
- Updated Android workaround to hide the Keyboard when the user click outside on something not focusable such as input or a textarea.
|
||||||
- Fixed `zoomBy`, `setOptions` webview methods on Android
|
- Fixed `zoomBy`, `setOptions` webview methods on Android
|
||||||
- Fixed `databaseEnabled` android webview option default value to `true`
|
- Fixed `databaseEnabled` android webview option default value to `true`
|
||||||
|
- Fixed `verticalScrollBarEnabled` and `horizontalScrollBarEnabled` on Android
|
||||||
|
- Fixed error caused by `pauseTimers` on iOS when the WebView has been disposed
|
||||||
|
- Fixed `ignoresViewportScaleLimits`, `dataDetectorTypes`, `suppressesIncrementalRendering`, `selectionGranularity` iOS-specific option when used in `initialOptions`
|
||||||
|
- Fixed `getFavicons` method
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.MutableContextWrapper;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -64,6 +65,11 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
|
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MutableContextWrapper mMutableContext = new MutableContextWrapper(Shared.activity);
|
||||||
|
// webView = new InAppWebView(mMutableContext, this, id, options, contextMenu, containerView);
|
||||||
|
// displayListenerProxy.onPostWebViewInitialization(displayManager);
|
||||||
|
// mMutableContext.setBaseContext(context);
|
||||||
|
|
||||||
webView = new InAppWebView(Shared.activity, this, id, options, contextMenu, containerView);
|
webView = new InAppWebView(Shared.activity, this, id, options, contextMenu, containerView);
|
||||||
displayListenerProxy.onPostWebViewInitialization(displayManager);
|
displayListenerProxy.onPostWebViewInitialization(displayManager);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@ import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputConnection;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.DownloadListener;
|
import android.webkit.DownloadListener;
|
||||||
import android.webkit.ValueCallback;
|
import android.webkit.ValueCallback;
|
||||||
|
@ -70,6 +73,7 @@ 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.InAppWebView.PreferredContentModeOptionType.fromValue;
|
import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.fromValue;
|
||||||
|
|
||||||
final public class InAppWebView extends InputAwareWebView {
|
final public class InAppWebView extends InputAwareWebView {
|
||||||
|
@ -204,7 +208,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
" };" +
|
" };" +
|
||||||
" function handleEvent(e) {" +
|
" function handleEvent(e) {" +
|
||||||
" var self = this;" +
|
" var self = this;" +
|
||||||
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
" if (" + variableForShouldInterceptAjaxRequestJS + " == null || " + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
" var headers = this.getAllResponseHeaders();" +
|
" var headers = this.getAllResponseHeaders();" +
|
||||||
" var responseHeaders = {};" +
|
" var responseHeaders = {};" +
|
||||||
" if (headers != null) {" +
|
" if (headers != null) {" +
|
||||||
|
@ -255,12 +259,12 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
" };" +
|
" };" +
|
||||||
" ajax.prototype.send = function(data) {" +
|
" ajax.prototype.send = function(data) {" +
|
||||||
" var self = this;" +
|
" var self = this;" +
|
||||||
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
" if (" + variableForShouldInterceptAjaxRequestJS + " == null || " + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
" if (!this._flutter_inappwebview_already_onreadystatechange_wrapped) {" +
|
" if (!this._flutter_inappwebview_already_onreadystatechange_wrapped) {" +
|
||||||
" this._flutter_inappwebview_already_onreadystatechange_wrapped = true;" +
|
" this._flutter_inappwebview_already_onreadystatechange_wrapped = true;" +
|
||||||
" var onreadystatechange = this.onreadystatechange;" +
|
" var onreadystatechange = this.onreadystatechange;" +
|
||||||
" this.onreadystatechange = function() {" +
|
" this.onreadystatechange = function() {" +
|
||||||
" if (window." + variableForShouldInterceptAjaxRequestJS + " == null || window." + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
" if (" + variableForShouldInterceptAjaxRequestJS + " == null || " + variableForShouldInterceptAjaxRequestJS + " == true) {" +
|
||||||
" var headers = this.getAllResponseHeaders();" +
|
" var headers = this.getAllResponseHeaders();" +
|
||||||
" var responseHeaders = {};" +
|
" var responseHeaders = {};" +
|
||||||
" if (headers != null) {" +
|
" if (headers != null) {" +
|
||||||
|
@ -588,26 +592,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
" });" +
|
" });" +
|
||||||
"})();";
|
"})();";
|
||||||
|
|
||||||
// android Workaround to hide the Keyboard when the user click outside
|
|
||||||
// on something not focusable such as input or a textarea.
|
|
||||||
static final String androidKeyboardWorkaroundFocusoutEventJS = "(function(){" +
|
|
||||||
" var isFocusin = false;" +
|
|
||||||
" document.addEventListener('focusin', function(e) {" +
|
|
||||||
" var nodeName = e.target.nodeName.toLowerCase();" +
|
|
||||||
" var isInputButton = nodeName === 'input' && e.target.type != null && e.target.type === 'button';" +
|
|
||||||
" isFocusin = (['a', 'area', 'button', 'details', 'iframe', 'select', 'summary'].indexOf(nodeName) >= 0 || isInputButton) ? false : true;" +
|
|
||||||
" });" +
|
|
||||||
" document.addEventListener('focusout', function(e) {" +
|
|
||||||
" isFocusin = false;" +
|
|
||||||
" setTimeout(function() {" +
|
|
||||||
isActiveElementInputEditableJS +
|
|
||||||
" if (!isFocusin && !isActiveElementEditable) {" +
|
|
||||||
" window." + JavaScriptBridgeInterface.name + ".callHandler('androidKeyboardWorkaroundFocusoutEvent');" +
|
|
||||||
" }" +
|
|
||||||
" }, 300);" +
|
|
||||||
" });" +
|
|
||||||
"})();";
|
|
||||||
|
|
||||||
public InAppWebView(Context context) {
|
public InAppWebView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
@ -705,8 +689,9 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
settings.setUseWideViewPort(options.useWideViewPort);
|
settings.setUseWideViewPort(options.useWideViewPort);
|
||||||
settings.setSupportZoom(options.supportZoom);
|
settings.setSupportZoom(options.supportZoom);
|
||||||
settings.setTextZoom(options.textZoom);
|
settings.setTextZoom(options.textZoom);
|
||||||
setVerticalScrollBarEnabled(options.verticalScrollBarEnabled);
|
|
||||||
setHorizontalScrollBarEnabled(options.horizontalScrollBarEnabled);
|
setVerticalScrollBarEnabled(!options.disableVerticalScroll && options.verticalScrollBarEnabled);
|
||||||
|
setHorizontalScrollBarEnabled(!options.disableHorizontalScroll && options.horizontalScrollBarEnabled);
|
||||||
|
|
||||||
if (options.transparentBackground)
|
if (options.transparentBackground)
|
||||||
setBackgroundColor(Color.TRANSPARENT);
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
@ -780,8 +765,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
options.scrollBarFadeDuration = getScrollBarFadeDuration();
|
options.scrollBarFadeDuration = getScrollBarFadeDuration();
|
||||||
}
|
}
|
||||||
setVerticalScrollbarPosition(options.verticalScrollbarPosition);
|
setVerticalScrollbarPosition(options.verticalScrollbarPosition);
|
||||||
setVerticalScrollBarEnabled(!options.disableVerticalScroll);
|
|
||||||
setHorizontalScrollBarEnabled(!options.disableHorizontalScroll);
|
|
||||||
setOverScrollMode(options.overScrollMode);
|
setOverScrollMode(options.overScrollMode);
|
||||||
if (options.networkAvailable != null) {
|
if (options.networkAvailable != null) {
|
||||||
setNetworkAvailable(options.networkAvailable);
|
setNetworkAvailable(options.networkAvailable);
|
||||||
|
@ -1065,29 +1048,41 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
headlessHandler.post(new Runnable() {
|
headlessHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int height = (int) (getContentHeight() * scale + 0.5);
|
|
||||||
|
|
||||||
Bitmap b = Bitmap.createBitmap( getWidth(),
|
|
||||||
height, Bitmap.Config.ARGB_8888);
|
|
||||||
Canvas c = new Canvas(b);
|
|
||||||
|
|
||||||
draw(c);
|
|
||||||
int scrollOffset = (getScrollY() + getMeasuredHeight() > b.getHeight())
|
|
||||||
? b.getHeight() : getScrollY();
|
|
||||||
Bitmap resized = Bitmap.createBitmap(
|
|
||||||
b, 0, scrollOffset, b.getWidth(), getMeasuredHeight());
|
|
||||||
|
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
resized.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
|
||||||
try {
|
try {
|
||||||
byteArrayOutputStream.close();
|
int height = (int) (getContentHeight() * scale + 0.5);
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
Bitmap b = Bitmap.createBitmap(getWidth(),
|
||||||
Log.e(LOG_TAG, e.getMessage());
|
height, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas c = new Canvas(b);
|
||||||
|
|
||||||
|
draw(c);
|
||||||
|
int scrollOffset = (getScrollY() + getMeasuredHeight() > b.getHeight())
|
||||||
|
? b.getHeight() : getScrollY();
|
||||||
|
Bitmap resized = Bitmap.createBitmap(
|
||||||
|
b, 0, scrollOffset, b.getWidth(), getMeasuredHeight());
|
||||||
|
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
resized.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
||||||
|
try {
|
||||||
|
byteArrayOutputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
String errorMessage = e.getMessage();
|
||||||
|
if (errorMessage != null) {
|
||||||
|
Log.e(LOG_TAG, errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resized.recycle();
|
||||||
|
result.success(byteArrayOutputStream.toByteArray());
|
||||||
|
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
String errorMessage = e.getMessage();
|
||||||
|
if (errorMessage != null) {
|
||||||
|
Log.e(LOG_TAG, errorMessage);
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
}
|
}
|
||||||
resized.recycle();
|
|
||||||
result.success(byteArrayOutputStream.toByteArray());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1367,10 +1362,10 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
setVerticalScrollbarPosition(newOptions.verticalScrollbarPosition);
|
setVerticalScrollbarPosition(newOptions.verticalScrollbarPosition);
|
||||||
|
|
||||||
if (newOptionsMap.get("disableVerticalScroll") != null && options.disableVerticalScroll != newOptions.disableVerticalScroll)
|
if (newOptionsMap.get("disableVerticalScroll") != null && options.disableVerticalScroll != newOptions.disableVerticalScroll)
|
||||||
setVerticalScrollBarEnabled(!newOptions.disableVerticalScroll);
|
setVerticalScrollBarEnabled(!newOptions.disableVerticalScroll && newOptions.verticalScrollBarEnabled);
|
||||||
|
|
||||||
if (newOptionsMap.get("disableHorizontalScroll") != null && options.disableHorizontalScroll != newOptions.disableHorizontalScroll)
|
if (newOptionsMap.get("disableHorizontalScroll") != null && options.disableHorizontalScroll != newOptions.disableHorizontalScroll)
|
||||||
setHorizontalScrollBarEnabled(!newOptions.disableHorizontalScroll);
|
setHorizontalScrollBarEnabled(!newOptions.disableHorizontalScroll && newOptions.horizontalScrollBarEnabled);
|
||||||
|
|
||||||
if (newOptionsMap.get("overScrollMode") != null && !options.overScrollMode.equals(newOptions.overScrollMode))
|
if (newOptionsMap.get("overScrollMode") != null && !options.overScrollMode.equals(newOptions.overScrollMode))
|
||||||
setOverScrollMode(newOptions.overScrollMode);
|
setOverScrollMode(newOptions.overScrollMode);
|
||||||
|
@ -1600,6 +1595,31 @@ final public class InAppWebView extends InputAwareWebView {
|
||||||
return super.dispatchTouchEvent(event);
|
return super.dispatchTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||||
|
InputConnection connection = super.onCreateInputConnection(outAttrs);
|
||||||
|
if (connection == null && containerView != null) {
|
||||||
|
// workaround to hide the Keyboard when the user click outside
|
||||||
|
// on something not focusable such as input or a textarea.
|
||||||
|
containerView
|
||||||
|
.getHandler()
|
||||||
|
.postDelayed(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
InputMethodManager imm =
|
||||||
|
(InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
|
if (imm != null && !imm.isAcceptingText()) {
|
||||||
|
imm.hideSoftInputFromWindow(
|
||||||
|
containerView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
128);
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionMode startActionMode(ActionMode.Callback callback) {
|
public ActionMode startActionMode(ActionMode.Callback callback) {
|
||||||
return rebuildActionMode(super.startActionMode(callback), callback);
|
return rebuildActionMode(super.startActionMode(callback), callback);
|
||||||
|
|
|
@ -185,9 +185,6 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
|
||||||
}
|
}
|
||||||
js += InAppWebView.checkGlobalKeyDownEventToHideContextMenuJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.checkGlobalKeyDownEventToHideContextMenuJS.replaceAll("[\r\n]+", "");
|
||||||
if (flutterWebView != null) {
|
|
||||||
js += InAppWebView.androidKeyboardWorkaroundFocusoutEventJS.replaceAll("[\r\n]+", "");
|
|
||||||
}
|
|
||||||
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
|
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
|
|
@ -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_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","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_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.9/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.0+hotfix.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-06-14 18:36:37.641339","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_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.10/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1/","dependencies":[]}],"android":[{"name":"e2e","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/e2e-0.2.4+4/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.10/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[]},"dependencyGraph":[{"name":"e2e","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-06-18 15:48:06.962625","version":"1.17.3"}
|
|
@ -24,7 +24,6 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main role="main" class="inner cover">
|
<main role="main" class="inner cover">
|
||||||
<input type="text">
|
|
||||||
<h1 class="cover-heading">Inline WebView</h1>
|
<h1 class="cover-heading">Inline WebView</h1>
|
||||||
<img src="images/flutter-logo.svg" alt="flutter logo">
|
<img src="images/flutter-logo.svg" alt="flutter logo">
|
||||||
<a href="index.html"><img src="images/flutter-logo.svg" alt="flutter logo"></a>
|
<a href="index.html"><img src="images/flutter-logo.svg" alt="flutter logo"></a>
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
# This is a generated file; do not edit or check into version control.
|
# This is a generated file; do not edit or check into version control.
|
||||||
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
|
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
|
||||||
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
|
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
|
||||||
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
|
export "FLUTTER_TARGET=lib/main.dart"
|
||||||
export "FLUTTER_BUILD_DIR=build"
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
||||||
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
|
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
|
||||||
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
||||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
export "FLUTTER_BUILD_NUMBER=1"
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
export "TRACK_WIDGET_CREATION=true"
|
|
||||||
|
|
|
@ -26,25 +26,25 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
contextMenu = ContextMenu(
|
contextMenu = ContextMenu(
|
||||||
menuItems: [
|
menuItems: [
|
||||||
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
ContextMenuItem(androidId: 1, iosId: "1", title: "Special", action: () async {
|
||||||
print("Menu item Special clicked!");
|
//print("Menu item Special clicked!");
|
||||||
print(await webView.getSelectedText());
|
print(await webView.getSelectedText());
|
||||||
await webView.clearFocus();
|
await webView.clearFocus();
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
options: ContextMenuOptions(
|
options: ContextMenuOptions(
|
||||||
hideDefaultSystemContextMenuItems: true
|
hideDefaultSystemContextMenuItems: false
|
||||||
),
|
),
|
||||||
onCreateContextMenu: (hitTestResult) async {
|
onCreateContextMenu: (hitTestResult) async {
|
||||||
print("onCreateContextMenu");
|
//print("onCreateContextMenu");
|
||||||
print(hitTestResult.extra);
|
print(hitTestResult.extra);
|
||||||
print(await webView.getSelectedText());
|
print(await webView.getSelectedText());
|
||||||
},
|
},
|
||||||
onHideContextMenu: () {
|
onHideContextMenu: () {
|
||||||
print("onHideContextMenu");
|
//print("onHideContextMenu");
|
||||||
},
|
},
|
||||||
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
|
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
|
||||||
var id = (Platform.isAndroid) ? contextMenuItemClicked.androidId : contextMenuItemClicked.iosId;
|
var id = (Platform.isAndroid) ? contextMenuItemClicked.androidId : contextMenuItemClicked.iosId;
|
||||||
print("onContextMenuActionItemClicked: " + id.toString() + " " + contextMenuItemClicked.title);
|
// print("onContextMenuActionItemClicked: " + id.toString() + " " + contextMenuItemClicked.title);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
||||||
child: InAppWebView(
|
child: InAppWebView(
|
||||||
contextMenu: contextMenu,
|
contextMenu: contextMenu,
|
||||||
initialUrl: "https://github.com/flutter",
|
// initialUrl: "https://github.com/flutter",
|
||||||
// initialFile: "assets/index.html",
|
initialFile: "assets/index.html",
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
initialOptions: InAppWebViewGroupOptions(
|
||||||
crossPlatform: InAppWebViewOptions(
|
crossPlatform: InAppWebViewOptions(
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/build" />
|
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/build" />
|
||||||
|
|
|
@ -320,7 +320,7 @@ let interceptAjaxRequestsJS = """
|
||||||
};
|
};
|
||||||
function handleEvent(e) {
|
function handleEvent(e) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
var headers = this.getAllResponseHeaders();
|
var headers = this.getAllResponseHeaders();
|
||||||
var responseHeaders = {};
|
var responseHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
|
@ -371,12 +371,12 @@ let interceptAjaxRequestsJS = """
|
||||||
};
|
};
|
||||||
ajax.prototype.send = function(data) {
|
ajax.prototype.send = function(data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
if (!this._flutter_inappwebview_already_onreadystatechange_wrapped) {
|
if (!this._flutter_inappwebview_already_onreadystatechange_wrapped) {
|
||||||
this._flutter_inappwebview_already_onreadystatechange_wrapped = true;
|
this._flutter_inappwebview_already_onreadystatechange_wrapped = true;
|
||||||
var onreadystatechange = this.onreadystatechange;
|
var onreadystatechange = this.onreadystatechange;
|
||||||
this.onreadystatechange = function() {
|
this.onreadystatechange = function() {
|
||||||
if (window.\(variableForShouldInterceptAjaxRequestJS) == null || window.\(variableForShouldInterceptAjaxRequestJS) == true) {
|
if (\(variableForShouldInterceptAjaxRequestJS) == null || \(variableForShouldInterceptAjaxRequestJS) == true) {
|
||||||
var headers = this.getAllResponseHeaders();
|
var headers = this.getAllResponseHeaders();
|
||||||
var responseHeaders = {};
|
var responseHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
|
@ -1029,143 +1029,130 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
configuration.userContentController = WKUserContentController()
|
configuration.userContentController = WKUserContentController()
|
||||||
configuration.preferences = WKPreferences()
|
configuration.preferences = WKPreferences()
|
||||||
|
|
||||||
if (options?.transparentBackground)! {
|
if let options = options {
|
||||||
isOpaque = false
|
if options.transparentBackground {
|
||||||
backgroundColor = UIColor.clear
|
isOpaque = false
|
||||||
scrollView.backgroundColor = UIColor.clear
|
backgroundColor = UIColor.clear
|
||||||
}
|
scrollView.backgroundColor = UIColor.clear
|
||||||
|
|
||||||
// prevent webView from bouncing
|
|
||||||
if (options?.disallowOverScroll)! {
|
|
||||||
if responds(to: #selector(getter: scrollView)) {
|
|
||||||
scrollView.bounces = false
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
for subview: UIView in subviews {
|
// prevent webView from bouncing
|
||||||
if subview is UIScrollView {
|
if options.disallowOverScroll {
|
||||||
(subview as! UIScrollView).bounces = false
|
if responds(to: #selector(getter: scrollView)) {
|
||||||
|
scrollView.bounces = false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for subview: UIView in subviews {
|
||||||
|
if subview is UIScrollView {
|
||||||
|
(subview as! UIScrollView).bounces = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let originalViewPortMetaTagContentJSScript = WKUserScript(source: originalViewPortMetaTagContentJS, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
|
||||||
configuration.userContentController.addUserScript(originalViewPortMetaTagContentJSScript)
|
|
||||||
|
|
||||||
if !(options?.supportZoom)! {
|
|
||||||
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
|
||||||
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
|
||||||
configuration.userContentController.addUserScript(userScript)
|
|
||||||
} else if (options?.enableViewportScale)! {
|
|
||||||
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
|
||||||
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
|
||||||
configuration.userContentController.addUserScript(userScript)
|
|
||||||
}
|
|
||||||
|
|
||||||
let promisePolyfillJSScript = WKUserScript(source: promisePolyfillJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(promisePolyfillJSScript)
|
|
||||||
|
|
||||||
let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
|
||||||
configuration.userContentController.add(self, name: "callHandler")
|
|
||||||
|
|
||||||
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(consoleLogJSScript)
|
|
||||||
configuration.userContentController.add(self, name: "consoleLog")
|
|
||||||
configuration.userContentController.add(self, name: "consoleDebug")
|
|
||||||
configuration.userContentController.add(self, name: "consoleError")
|
|
||||||
configuration.userContentController.add(self, name: "consoleInfo")
|
|
||||||
configuration.userContentController.add(self, name: "consoleWarn")
|
|
||||||
|
|
||||||
let findElementsAtPointJSScript = WKUserScript(source: findElementsAtPointJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(findElementsAtPointJSScript)
|
|
||||||
|
|
||||||
let printJSScript = WKUserScript(source: printJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(printJSScript)
|
|
||||||
|
|
||||||
let lastTouchedAnchorOrImageJSScript = WKUserScript(source: lastTouchedAnchorOrImageJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(lastTouchedAnchorOrImageJSScript)
|
|
||||||
|
|
||||||
if (options?.useOnLoadResource)! {
|
|
||||||
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(resourceObserverJSScript)
|
|
||||||
}
|
|
||||||
|
|
||||||
let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(findTextHighlightJSScript)
|
|
||||||
configuration.userContentController.add(self, name: "onFindResultReceived")
|
|
||||||
|
|
||||||
if (options?.useShouldInterceptAjaxRequest)! {
|
|
||||||
let interceptAjaxRequestsJSScript = WKUserScript(source: interceptAjaxRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(interceptAjaxRequestsJSScript)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.useShouldInterceptFetchRequest)! {
|
|
||||||
let interceptFetchRequestsJSScript = WKUserScript(source: interceptFetchRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
|
||||||
configuration.userContentController.addUserScript(interceptFetchRequestsJSScript)
|
|
||||||
}
|
|
||||||
|
|
||||||
if #available(iOS 11.0, *) {
|
|
||||||
accessibilityIgnoresInvertColors = (options?.accessibilityIgnoresInvertColors)!
|
|
||||||
scrollView.contentInsetAdjustmentBehavior =
|
|
||||||
UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: (options?.contentInsetAdjustmentBehavior)!)!
|
|
||||||
}
|
|
||||||
|
|
||||||
configuration.suppressesIncrementalRendering = (options?.suppressesIncrementalRendering)!
|
|
||||||
allowsBackForwardNavigationGestures = (options?.allowsBackForwardNavigationGestures)!
|
|
||||||
if #available(iOS 9.0, *) {
|
|
||||||
allowsLinkPreview = (options?.allowsLinkPreview)!
|
|
||||||
configuration.allowsAirPlayForMediaPlayback = (options?.allowsAirPlayForMediaPlayback)!
|
|
||||||
configuration.allowsPictureInPictureMediaPlayback = (options?.allowsPictureInPictureMediaPlayback)!
|
|
||||||
if (options?.applicationNameForUserAgent != nil && (options?.applicationNameForUserAgent)! != "") {
|
|
||||||
configuration.applicationNameForUserAgent = (options?.applicationNameForUserAgent)!
|
|
||||||
}
|
|
||||||
if (options?.userAgent != nil && (options?.userAgent)! != "") {
|
|
||||||
customUserAgent = (options?.userAgent)!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = (options?.javaScriptCanOpenWindowsAutomatically)!
|
|
||||||
configuration.preferences.javaScriptEnabled = (options?.javaScriptEnabled)!
|
|
||||||
configuration.preferences.minimumFontSize = CGFloat((options?.minimumFontSize)!)
|
|
||||||
configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: (options?.selectionGranularity)!)!
|
|
||||||
|
|
||||||
if #available(iOS 10.0, *) {
|
|
||||||
configuration.ignoresViewportScaleLimits = (options?.ignoresViewportScaleLimits)!
|
|
||||||
|
|
||||||
var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0)
|
let originalViewPortMetaTagContentJSScript = WKUserScript(source: originalViewPortMetaTagContentJS, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
||||||
for type in options?.dataDetectorTypes ?? [] {
|
configuration.userContentController.addUserScript(originalViewPortMetaTagContentJSScript)
|
||||||
let dataDetectorType = InAppWebView.getDataDetectorType(type: type)
|
|
||||||
dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue)
|
if !options.supportZoom {
|
||||||
|
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
||||||
|
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
||||||
|
configuration.userContentController.addUserScript(userScript)
|
||||||
|
} else if options.enableViewportScale {
|
||||||
|
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
|
||||||
|
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
||||||
|
configuration.userContentController.addUserScript(userScript)
|
||||||
}
|
}
|
||||||
configuration.dataDetectorTypes = dataDetectorTypes
|
|
||||||
}
|
let promisePolyfillJSScript = WKUserScript(source: promisePolyfillJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(promisePolyfillJSScript)
|
||||||
if #available(iOS 13.0, *) {
|
|
||||||
configuration.preferences.isFraudulentWebsiteWarningEnabled = (options?.isFraudulentWebsiteWarningEnabled)!
|
let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
if options?.preferredContentMode != nil {
|
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
||||||
configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: (options?.preferredContentMode)!)!
|
configuration.userContentController.add(self, name: "callHandler")
|
||||||
|
|
||||||
|
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(consoleLogJSScript)
|
||||||
|
configuration.userContentController.add(self, name: "consoleLog")
|
||||||
|
configuration.userContentController.add(self, name: "consoleDebug")
|
||||||
|
configuration.userContentController.add(self, name: "consoleError")
|
||||||
|
configuration.userContentController.add(self, name: "consoleInfo")
|
||||||
|
configuration.userContentController.add(self, name: "consoleWarn")
|
||||||
|
|
||||||
|
let findElementsAtPointJSScript = WKUserScript(source: findElementsAtPointJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(findElementsAtPointJSScript)
|
||||||
|
|
||||||
|
let printJSScript = WKUserScript(source: printJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(printJSScript)
|
||||||
|
|
||||||
|
let lastTouchedAnchorOrImageJSScript = WKUserScript(source: lastTouchedAnchorOrImageJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(lastTouchedAnchorOrImageJSScript)
|
||||||
|
|
||||||
|
if options.useOnLoadResource {
|
||||||
|
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(resourceObserverJSScript)
|
||||||
}
|
}
|
||||||
scrollView.automaticallyAdjustsScrollIndicatorInsets = (options?.automaticallyAdjustsScrollIndicatorInsets)!
|
|
||||||
}
|
let findTextHighlightJSScript = WKUserScript(source: findTextHighlightJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(findTextHighlightJSScript)
|
||||||
scrollView.showsVerticalScrollIndicator = !(options?.disableVerticalScroll)!
|
configuration.userContentController.add(self, name: "onFindResultReceived")
|
||||||
scrollView.showsHorizontalScrollIndicator = !(options?.disableHorizontalScroll)!
|
|
||||||
scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)!
|
if options.useShouldInterceptAjaxRequest {
|
||||||
scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)!
|
let interceptAjaxRequestsJSScript = WKUserScript(source: interceptAjaxRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(interceptAjaxRequestsJSScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.useShouldInterceptFetchRequest {
|
||||||
|
let interceptFetchRequestsJSScript = WKUserScript(source: interceptFetchRequestsJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
|
configuration.userContentController.addUserScript(interceptFetchRequestsJSScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
accessibilityIgnoresInvertColors = options.accessibilityIgnoresInvertColors
|
||||||
|
scrollView.contentInsetAdjustmentBehavior =
|
||||||
|
UIScrollView.ContentInsetAdjustmentBehavior.init(rawValue: options.contentInsetAdjustmentBehavior)!
|
||||||
|
}
|
||||||
|
|
||||||
|
allowsBackForwardNavigationGestures = options.allowsBackForwardNavigationGestures
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
allowsLinkPreview = options.allowsLinkPreview
|
||||||
|
configuration.allowsAirPlayForMediaPlayback = options.allowsAirPlayForMediaPlayback
|
||||||
|
configuration.allowsPictureInPictureMediaPlayback = options.allowsPictureInPictureMediaPlayback
|
||||||
|
if !options.applicationNameForUserAgent.isEmpty {
|
||||||
|
configuration.applicationNameForUserAgent = options.applicationNameForUserAgent
|
||||||
|
}
|
||||||
|
if !options.userAgent.isEmpty {
|
||||||
|
customUserAgent = options.userAgent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.preferences.javaScriptCanOpenWindowsAutomatically = options.javaScriptCanOpenWindowsAutomatically
|
||||||
|
configuration.preferences.javaScriptEnabled = options.javaScriptEnabled
|
||||||
|
configuration.preferences.minimumFontSize = CGFloat(options.minimumFontSize)
|
||||||
|
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
configuration.preferences.isFraudulentWebsiteWarningEnabled = options.isFraudulentWebsiteWarningEnabled
|
||||||
|
configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: options.preferredContentMode)!
|
||||||
|
scrollView.automaticallyAdjustsScrollIndicatorInsets = options.automaticallyAdjustsScrollIndicatorInsets
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollView.showsVerticalScrollIndicator = !options.disableVerticalScroll
|
||||||
|
scrollView.showsHorizontalScrollIndicator = !options.disableHorizontalScroll
|
||||||
|
scrollView.showsVerticalScrollIndicator = options.verticalScrollBarEnabled
|
||||||
|
scrollView.showsHorizontalScrollIndicator = options.horizontalScrollBarEnabled
|
||||||
|
|
||||||
scrollView.decelerationRate = InAppWebView.getDecelerationRate(type: (options?.decelerationRate)!)
|
scrollView.decelerationRate = InAppWebView.getDecelerationRate(type: options.decelerationRate)
|
||||||
scrollView.alwaysBounceVertical = (options?.alwaysBounceVertical)!
|
scrollView.alwaysBounceVertical = options.alwaysBounceVertical
|
||||||
scrollView.alwaysBounceHorizontal = (options?.alwaysBounceHorizontal)!
|
scrollView.alwaysBounceHorizontal = options.alwaysBounceHorizontal
|
||||||
scrollView.scrollsToTop = (options?.scrollsToTop)!
|
scrollView.scrollsToTop = options.scrollsToTop
|
||||||
scrollView.isPagingEnabled = (options?.isPagingEnabled)!
|
scrollView.isPagingEnabled = options.isPagingEnabled
|
||||||
scrollView.maximumZoomScale = CGFloat((options?.maximumZoomScale)!)
|
scrollView.maximumZoomScale = CGFloat(options.maximumZoomScale)
|
||||||
scrollView.minimumZoomScale = CGFloat((options?.minimumZoomScale)!)
|
scrollView.minimumZoomScale = CGFloat(options.minimumZoomScale)
|
||||||
|
|
||||||
// options.debuggingEnabled is always enabled for iOS.
|
// options.debuggingEnabled is always enabled for iOS.
|
||||||
|
|
||||||
if (options?.clearCache)! {
|
if options.clearCache {
|
||||||
clearCache()
|
clearCache()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,43 +1248,51 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
configuration.processPool = WKProcessPoolManager.sharedProcessPool
|
configuration.processPool = WKProcessPoolManager.sharedProcessPool
|
||||||
|
|
||||||
if #available(iOS 10.0, *) {
|
if let options = options {
|
||||||
configuration.mediaTypesRequiringUserActionForPlayback = ((options?.mediaPlaybackRequiresUserGesture)!) ? .all : []
|
configuration.allowsInlineMediaPlayback = options.allowsInlineMediaPlayback
|
||||||
} else {
|
configuration.suppressesIncrementalRendering = options.suppressesIncrementalRendering
|
||||||
// Fallback on earlier versions
|
configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: options.selectionGranularity)!
|
||||||
configuration.mediaPlaybackRequiresUserAction = (options?.mediaPlaybackRequiresUserGesture)!
|
|
||||||
}
|
if #available(iOS 9.0, *) {
|
||||||
|
if options.incognito {
|
||||||
configuration.allowsInlineMediaPlayback = (options?.allowsInlineMediaPlayback)!
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
|
} else if options.cacheEnabled {
|
||||||
if #available(iOS 11.0, *) {
|
configuration.websiteDataStore = WKWebsiteDataStore.default()
|
||||||
if let schemes = options?.resourceCustomSchemes {
|
}
|
||||||
for scheme in schemes {
|
}
|
||||||
|
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
configuration.ignoresViewportScaleLimits = options.ignoresViewportScaleLimits
|
||||||
|
|
||||||
|
var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0)
|
||||||
|
for type in options.dataDetectorTypes {
|
||||||
|
let dataDetectorType = InAppWebView.getDataDetectorType(type: type)
|
||||||
|
dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue)
|
||||||
|
}
|
||||||
|
configuration.dataDetectorTypes = dataDetectorTypes
|
||||||
|
|
||||||
|
configuration.mediaTypesRequiringUserActionForPlayback = options.mediaPlaybackRequiresUserGesture ? .all : []
|
||||||
|
} else {
|
||||||
|
// Fallback on earlier versions
|
||||||
|
configuration.mediaPlaybackRequiresUserAction = options.mediaPlaybackRequiresUserGesture
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
for scheme in options.resourceCustomSchemes {
|
||||||
configuration.setURLSchemeHandler(CustomeSchemeHandler(), forURLScheme: scheme)
|
configuration.setURLSchemeHandler(CustomeSchemeHandler(), forURLScheme: scheme)
|
||||||
}
|
}
|
||||||
}
|
if options.sharedCookiesEnabled {
|
||||||
}
|
// More info to sending cookies with WKWebView
|
||||||
|
// https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
|
||||||
if #available(iOS 9.0, *) {
|
// Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies
|
||||||
if ((options?.incognito)!) {
|
// See also https://forums.developer.apple.com/thread/97194
|
||||||
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
// check if websiteDataStore has not been initialized before
|
||||||
} else if ((options?.cacheEnabled)!) {
|
if(!options.incognito && options.cacheEnabled) {
|
||||||
configuration.websiteDataStore = WKWebsiteDataStore.default()
|
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
||||||
}
|
}
|
||||||
}
|
for cookie in HTTPCookieStorage.shared.cookies ?? [] {
|
||||||
|
configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
|
||||||
if #available(iOS 11.0, *) {
|
}
|
||||||
if((options?.sharedCookiesEnabled)!) {
|
|
||||||
// More info to sending cookies with WKWebView
|
|
||||||
// https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303
|
|
||||||
// Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies
|
|
||||||
// See also https://forums.developer.apple.com/thread/97194
|
|
||||||
// check if websiteDataStore has not been initialized before
|
|
||||||
if(!(options?.incognito)! && !(options?.cacheEnabled)!) {
|
|
||||||
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
|
||||||
}
|
|
||||||
for cookie in HTTPCookieStorage.shared.cookies ?? [] {
|
|
||||||
configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2804,17 +2799,21 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
|
|
||||||
|
|
||||||
public func pauseTimers() {
|
public func pauseTimers() {
|
||||||
isPausedTimers = true
|
if !isPausedTimers {
|
||||||
let script = "alert();";
|
isPausedTimers = true
|
||||||
self.evaluateJavaScript(script, completionHandler: nil)
|
let script = "alert();";
|
||||||
|
self.evaluateJavaScript(script, completionHandler: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func resumeTimers() {
|
public func resumeTimers() {
|
||||||
if let completionHandler = isPausedTimersCompletionHandler {
|
if isPausedTimers {
|
||||||
completionHandler()
|
if let completionHandler = isPausedTimersCompletionHandler {
|
||||||
isPausedTimersCompletionHandler = nil
|
self.isPausedTimersCompletionHandler = nil
|
||||||
|
completionHandler()
|
||||||
|
}
|
||||||
|
isPausedTimers = false
|
||||||
}
|
}
|
||||||
isPausedTimers = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func printCurrentPage(printCompletionHandler: ((_ completed: Bool, _ error: Error?) -> Void)?) {
|
public func printCurrentPage(printCompletionHandler: ((_ completed: Bool, _ error: Error?) -> Void)?) {
|
||||||
|
@ -2925,6 +2924,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dispose() {
|
public func dispose() {
|
||||||
|
if isPausedTimers, let completionHandler = isPausedTimersCompletionHandler {
|
||||||
|
isPausedTimersCompletionHandler = nil
|
||||||
|
completionHandler()
|
||||||
|
}
|
||||||
stopLoading()
|
stopLoading()
|
||||||
configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog")
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog")
|
||||||
configuration.userContentController.removeScriptMessageHandler(forName: "consoleDebug")
|
configuration.userContentController.removeScriptMessageHandler(forName: "consoleDebug")
|
||||||
|
|
|
@ -4,7 +4,7 @@ class ASN1DistinguishedNames {
|
||||||
|
|
||||||
const ASN1DistinguishedNames._internal(this._oid, this._representation);
|
const ASN1DistinguishedNames._internal(this._oid, this._representation);
|
||||||
|
|
||||||
static List<ASN1DistinguishedNames> values = [
|
static final Set<ASN1DistinguishedNames> values = [
|
||||||
ASN1DistinguishedNames.COMMON_NAME,
|
ASN1DistinguishedNames.COMMON_NAME,
|
||||||
ASN1DistinguishedNames.DN_QUALIFIER,
|
ASN1DistinguishedNames.DN_QUALIFIER,
|
||||||
ASN1DistinguishedNames.SERIAL_NUMBER,
|
ASN1DistinguishedNames.SERIAL_NUMBER,
|
||||||
|
@ -17,10 +17,12 @@ class ASN1DistinguishedNames {
|
||||||
ASN1DistinguishedNames.STATE_OR_PROVINCE_NAME,
|
ASN1DistinguishedNames.STATE_OR_PROVINCE_NAME,
|
||||||
ASN1DistinguishedNames.COUNTRY_NAME,
|
ASN1DistinguishedNames.COUNTRY_NAME,
|
||||||
ASN1DistinguishedNames.EMAIL,
|
ASN1DistinguishedNames.EMAIL,
|
||||||
];
|
].toSet();
|
||||||
|
|
||||||
static ASN1DistinguishedNames fromValue(String oid) {
|
static ASN1DistinguishedNames fromValue(String oid) {
|
||||||
return ASN1DistinguishedNames.values.firstWhere((element) => element.oid() == oid, orElse: () => null);
|
if (oid != null)
|
||||||
|
return ASN1DistinguishedNames.values.firstWhere((element) => element.oid() == oid, orElse: () => null);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String oid() => _oid;
|
String oid() => _oid;
|
||||||
|
|
|
@ -3,12 +3,12 @@ class ASN1IdentifierClass {
|
||||||
|
|
||||||
const ASN1IdentifierClass._internal(this._value);
|
const ASN1IdentifierClass._internal(this._value);
|
||||||
|
|
||||||
static List<ASN1IdentifierClass> values = [
|
static final Set<ASN1IdentifierClass> values = [
|
||||||
ASN1IdentifierClass.UNIVERSAL,
|
ASN1IdentifierClass.UNIVERSAL,
|
||||||
ASN1IdentifierClass.APPLICATION,
|
ASN1IdentifierClass.APPLICATION,
|
||||||
ASN1IdentifierClass.CONTEXT_SPECIFIC,
|
ASN1IdentifierClass.CONTEXT_SPECIFIC,
|
||||||
ASN1IdentifierClass.PRIVATE,
|
ASN1IdentifierClass.PRIVATE,
|
||||||
];
|
].toSet();
|
||||||
|
|
||||||
static ASN1IdentifierClass fromValue(int value) {
|
static ASN1IdentifierClass fromValue(int value) {
|
||||||
if (value != null)
|
if (value != null)
|
||||||
|
@ -47,7 +47,7 @@ class ASN1IdentifierTagNumber {
|
||||||
|
|
||||||
const ASN1IdentifierTagNumber._internal(this._value);
|
const ASN1IdentifierTagNumber._internal(this._value);
|
||||||
|
|
||||||
static List<ASN1IdentifierTagNumber> values = [
|
static final Set<ASN1IdentifierTagNumber> values = [
|
||||||
ASN1IdentifierTagNumber.END_OF_CONTENT,
|
ASN1IdentifierTagNumber.END_OF_CONTENT,
|
||||||
ASN1IdentifierTagNumber.BOOLEAN,
|
ASN1IdentifierTagNumber.BOOLEAN,
|
||||||
ASN1IdentifierTagNumber.INTEGER,
|
ASN1IdentifierTagNumber.INTEGER,
|
||||||
|
@ -77,7 +77,7 @@ class ASN1IdentifierTagNumber {
|
||||||
ASN1IdentifierTagNumber.UNIVERSAL_STRING,
|
ASN1IdentifierTagNumber.UNIVERSAL_STRING,
|
||||||
ASN1IdentifierTagNumber.CHARACTER_STRING,
|
ASN1IdentifierTagNumber.CHARACTER_STRING,
|
||||||
ASN1IdentifierTagNumber.BMP_STRING,
|
ASN1IdentifierTagNumber.BMP_STRING,
|
||||||
];
|
].toSet();
|
||||||
|
|
||||||
static ASN1IdentifierTagNumber fromValue(int value) {
|
static ASN1IdentifierTagNumber fromValue(int value) {
|
||||||
if (value != null)
|
if (value != null)
|
||||||
|
|
|
@ -3,7 +3,7 @@ class KeyUsage {
|
||||||
|
|
||||||
const KeyUsage._internal(this._value);
|
const KeyUsage._internal(this._value);
|
||||||
|
|
||||||
static List<KeyUsage> values = [
|
static final Set<KeyUsage> values = [
|
||||||
KeyUsage.digitalSignature,
|
KeyUsage.digitalSignature,
|
||||||
KeyUsage.nonRepudiation,
|
KeyUsage.nonRepudiation,
|
||||||
KeyUsage.keyEncipherment,
|
KeyUsage.keyEncipherment,
|
||||||
|
@ -13,7 +13,7 @@ class KeyUsage {
|
||||||
KeyUsage.cRLSign,
|
KeyUsage.cRLSign,
|
||||||
KeyUsage.encipherOnly,
|
KeyUsage.encipherOnly,
|
||||||
KeyUsage.decipherOnly,
|
KeyUsage.decipherOnly,
|
||||||
];
|
].toSet();
|
||||||
|
|
||||||
static KeyUsage fromIndex(int value) {
|
static KeyUsage fromIndex(int value) {
|
||||||
return KeyUsage.values.firstWhere((element) => element.toValue() == value, orElse: () => null);
|
return KeyUsage.values.firstWhere((element) => element.toValue() == value, orElse: () => null);
|
||||||
|
|
|
@ -3,7 +3,7 @@ class OID {
|
||||||
|
|
||||||
const OID._internal(this._value);
|
const OID._internal(this._value);
|
||||||
|
|
||||||
static List<OID> values = [
|
static final Set<OID> values = [
|
||||||
OID.etsiQcsCompliance,
|
OID.etsiQcsCompliance,
|
||||||
OID.etsiQcsRetentionPeriod,
|
OID.etsiQcsRetentionPeriod,
|
||||||
OID.etsiQcsQcSSCD,
|
OID.etsiQcsQcSSCD,
|
||||||
|
@ -100,7 +100,7 @@ class OID {
|
||||||
OID.codeSigning,
|
OID.codeSigning,
|
||||||
OID.emailProtection,
|
OID.emailProtection,
|
||||||
OID.timeStamping,
|
OID.timeStamping,
|
||||||
];
|
].toSet();
|
||||||
|
|
||||||
static OID fromValue(String value) {
|
static OID fromValue(String value) {
|
||||||
return OID.values.firstWhere((element) => element.toValue() == value, orElse: () => null);
|
return OID.values.firstWhere((element) => element.toValue() == value, orElse: () => null);
|
||||||
|
|
|
@ -287,10 +287,18 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
var gestureRecognizers = widget.gestureRecognizers;
|
||||||
|
if (gestureRecognizers == null) {
|
||||||
|
gestureRecognizers = <Factory<OneSequenceGestureRecognizer>>[
|
||||||
|
Factory<OneSequenceGestureRecognizer>(
|
||||||
|
() => EagerGestureRecognizer(),
|
||||||
|
),
|
||||||
|
].toSet();
|
||||||
|
}
|
||||||
return AndroidView(
|
return AndroidView(
|
||||||
viewType: 'com.pichillilorenzo/flutter_inappwebview',
|
viewType: 'com.pichillilorenzo/flutter_inappwebview',
|
||||||
onPlatformViewCreated: _onPlatformViewCreated,
|
onPlatformViewCreated: _onPlatformViewCreated,
|
||||||
gestureRecognizers: widget.gestureRecognizers,
|
gestureRecognizers: gestureRecognizers,
|
||||||
layoutDirection: TextDirection.rtl,
|
layoutDirection: TextDirection.rtl,
|
||||||
creationParams: <String, dynamic>{
|
creationParams: <String, dynamic>{
|
||||||
'initialUrl': '${Uri.parse(widget.initialUrl)}',
|
'initialUrl': '${Uri.parse(widget.initialUrl)}',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
@ -13,8 +12,6 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'X509Certificate/asn1_distinguished_names.dart';
|
import 'X509Certificate/asn1_distinguished_names.dart';
|
||||||
import 'X509Certificate/x509_certificate.dart';
|
import 'X509Certificate/x509_certificate.dart';
|
||||||
|
|
||||||
import 'package:html/parser.dart' show parse;
|
|
||||||
|
|
||||||
import 'context_menu.dart';
|
import 'context_menu.dart';
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
import 'in_app_browser.dart';
|
import 'in_app_browser.dart';
|
||||||
|
@ -586,11 +583,6 @@ class InAppWebViewController {
|
||||||
List<dynamic> args = jsonDecode(call.arguments["args"]);
|
List<dynamic> args = jsonDecode(call.arguments["args"]);
|
||||||
|
|
||||||
switch (handlerName) {
|
switch (handlerName) {
|
||||||
case "androidKeyboardWorkaroundFocusoutEvent":
|
|
||||||
// android Workaround to hide the Keyboard when the user click outside
|
|
||||||
// on something not focusable such as input or a textarea.
|
|
||||||
SystemChannels.textInput.invokeMethod("TextInput.hide");
|
|
||||||
break;
|
|
||||||
case "onLoadResource":
|
case "onLoadResource":
|
||||||
Map<dynamic, dynamic> argMap = args[0];
|
Map<dynamic, dynamic> argMap = args[0];
|
||||||
String initiatorType = argMap["initiatorType"];
|
String initiatorType = argMap["initiatorType"];
|
||||||
|
@ -883,7 +875,6 @@ class InAppWebViewController {
|
||||||
if (html == null || (html != null && html.isEmpty)) {
|
if (html == null || (html != null && html.isEmpty)) {
|
||||||
return favicons;
|
return favicons;
|
||||||
}
|
}
|
||||||
|
|
||||||
var assetPathBase;
|
var assetPathBase;
|
||||||
|
|
||||||
if (webviewUrl.startsWith("file:///")) {
|
if (webviewUrl.startsWith("file:///")) {
|
||||||
|
@ -891,29 +882,53 @@ class InAppWebViewController {
|
||||||
assetPathBase = assetPathSplitted[0] + "/flutter_assets/";
|
assetPathBase = assetPathSplitted[0] + "/flutter_assets/";
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all link html elements
|
InAppWebViewGroupOptions options = await getOptions();
|
||||||
var document = parse(html);
|
if (options != null && options.crossPlatform.javaScriptEnabled == true) {
|
||||||
var links = document.getElementsByTagName('link');
|
List<Map<dynamic, dynamic>> links = (await evaluateJavascript(
|
||||||
for (var link in links) {
|
source: """
|
||||||
var attributes = link.attributes;
|
(function() {
|
||||||
if (attributes["rel"] == "manifest") {
|
var linkNodes = document.head.getElementsByTagName("link");
|
||||||
manifestUrl = attributes["href"];
|
var links = [];
|
||||||
if (!_isUrlAbsolute(manifestUrl)) {
|
for (var i = 0; i < linkNodes.length; i++) {
|
||||||
if (manifestUrl.startsWith("/")) {
|
var linkNode = linkNodes[i];
|
||||||
manifestUrl = manifestUrl.substring(1);
|
if (linkNode.rel === 'manifest') {
|
||||||
}
|
links.push(
|
||||||
manifestUrl = ((assetPathBase == null)
|
{
|
||||||
? url.scheme + "://" + url.host + "/"
|
rel: linkNode.rel,
|
||||||
: assetPathBase) +
|
href: linkNode.href,
|
||||||
manifestUrl;
|
sizes: null
|
||||||
}
|
}
|
||||||
continue;
|
);
|
||||||
|
} else if (linkNode.rel != null && linkNode.rel.indexOf('icon') >= 0) {
|
||||||
|
links.push(
|
||||||
|
{
|
||||||
|
rel: linkNode.rel,
|
||||||
|
href: linkNode.href,
|
||||||
|
sizes: linkNode.sizes != null && linkNode.sizes.value != "" ? linkNode.sizes.value : null
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return links;
|
||||||
|
})();
|
||||||
|
"""))?.cast<Map<dynamic, dynamic>>() ?? [];
|
||||||
|
for (var link in links) {
|
||||||
|
if (link["rel"] == "manifest") {
|
||||||
|
manifestUrl = link["href"];
|
||||||
|
if (!_isUrlAbsolute(manifestUrl)) {
|
||||||
|
if (manifestUrl.startsWith("/")) {
|
||||||
|
manifestUrl = manifestUrl.substring(1);
|
||||||
|
}
|
||||||
|
manifestUrl = ((assetPathBase == null)
|
||||||
|
? url.scheme + "://" + url.host + "/"
|
||||||
|
: assetPathBase) +
|
||||||
|
manifestUrl;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
favicons.addAll(_createFavicons(url, assetPathBase, link["href"],
|
||||||
|
link["rel"], link["sizes"], false));
|
||||||
}
|
}
|
||||||
if (!attributes["rel"].contains("icon")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
favicons.addAll(_createFavicons(url, assetPathBase, attributes["href"],
|
|
||||||
attributes["rel"], attributes["sizes"], false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to get /favicon.ico
|
// try to get /favicon.ico
|
||||||
|
@ -923,7 +938,7 @@ class InAppWebViewController {
|
||||||
favicons.add(Favicon(url: faviconUrl, rel: "shortcut icon"));
|
favicons.add(Favicon(url: faviconUrl, rel: "shortcut icon"));
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print("/favicon.ico file not found: " + e.toString());
|
print("/favicon.ico file not found: " + e.toString());
|
||||||
print(stacktrace);
|
// print(stacktrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to get the manifest file
|
// try to get the manifest file
|
||||||
|
@ -940,7 +955,7 @@ class InAppWebViewController {
|
||||||
manifestResponse.headers.contentType?.mimeType == "application/json";
|
manifestResponse.headers.contentType?.mimeType == "application/json";
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print("Manifest file not found: " + e.toString());
|
print("Manifest file not found: " + e.toString());
|
||||||
print(stacktrace);
|
// print(stacktrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manifestFound) {
|
if (manifestFound) {
|
||||||
|
@ -1181,6 +1196,11 @@ class InAppWebViewController {
|
||||||
|
|
||||||
///Evaluates JavaScript code into the WebView and returns the result of the evaluation.
|
///Evaluates JavaScript code into the WebView and returns the result of the evaluation.
|
||||||
///
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript
|
||||||
Future<dynamic> evaluateJavascript({@required String source}) async {
|
Future<dynamic> evaluateJavascript({@required String source}) async {
|
||||||
|
@ -1192,6 +1212,11 @@ class InAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects an external JavaScript file into the WebView from a defined url.
|
///Injects an external JavaScript file into the WebView from a defined url.
|
||||||
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectJavascriptFileFromUrl({@required String urlFile}) async {
|
Future<void> injectJavascriptFileFromUrl({@required String urlFile}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
|
@ -1199,6 +1224,11 @@ class InAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a JavaScript file into the WebView from the flutter assets directory.
|
///Injects a JavaScript file into the WebView from the flutter assets directory.
|
||||||
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectJavascriptFileFromAsset(
|
Future<void> injectJavascriptFileFromAsset(
|
||||||
{@required String assetFilePath}) async {
|
{@required String assetFilePath}) async {
|
||||||
String source = await rootBundle.loadString(assetFilePath);
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
|
@ -1206,6 +1236,11 @@ class InAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects CSS into the WebView.
|
///Injects CSS into the WebView.
|
||||||
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectCSSCode({@required String source}) async {
|
Future<void> injectCSSCode({@required String source}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
|
@ -1213,6 +1248,11 @@ class InAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects an external CSS file into the WebView from a defined url.
|
///Injects an external CSS file into the WebView from a defined url.
|
||||||
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectCSSFileFromUrl({@required String urlFile}) async {
|
Future<void> injectCSSFileFromUrl({@required String urlFile}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
|
@ -1220,6 +1260,11 @@ class InAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a CSS file into the WebView from the flutter assets directory.
|
///Injects a CSS file into the WebView from the flutter assets directory.
|
||||||
|
///
|
||||||
|
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
|
||||||
|
///because, in these events, the [WebView] is not ready to handle it yet.
|
||||||
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
|
///where you know the page is ready "enough".
|
||||||
Future<void> injectCSSFileFromAsset({@required String assetFilePath}) async {
|
Future<void> injectCSSFileFromAsset({@required String assetFilePath}) async {
|
||||||
String source = await rootBundle.loadString(assetFilePath);
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
await injectCSSCode(source: source);
|
await injectCSSCode(source: source);
|
||||||
|
@ -1271,6 +1316,10 @@ class InAppWebViewController {
|
||||||
///```
|
///```
|
||||||
///
|
///
|
||||||
///Forbidden names for JavaScript handlers are defined in [javaScriptHandlerForbiddenNames].
|
///Forbidden names for JavaScript handlers are defined in [javaScriptHandlerForbiddenNames].
|
||||||
|
///
|
||||||
|
///**NOTE**: This method should be called, for example, in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events or, at least,
|
||||||
|
///before you know that your JavaScript code will call the `window.flutter_inappwebview.callHandler` method,
|
||||||
|
///otherwise you won't be able to intercept the JavaScript message.
|
||||||
void addJavaScriptHandler(
|
void addJavaScriptHandler(
|
||||||
{@required String handlerName,
|
{@required String handlerName,
|
||||||
@required JavaScriptHandlerCallback callback}) {
|
@required JavaScriptHandlerCallback callback}) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -301,12 +301,6 @@ class InAppWebViewOptions
|
||||||
InAppWebViewOptions copy() {
|
InAppWebViewOptions copy() {
|
||||||
return InAppWebViewOptions.fromMap(this.toMap());
|
return InAppWebViewOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
InAppWebViewOptions copyWithValue(InAppWebViewOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return InAppWebViewOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the Android-only WebView options available.
|
///This class represents all the Android-only WebView options available.
|
||||||
|
@ -709,12 +703,6 @@ class AndroidInAppWebViewOptions
|
||||||
AndroidInAppWebViewOptions copy() {
|
AndroidInAppWebViewOptions copy() {
|
||||||
return AndroidInAppWebViewOptions.fromMap(this.toMap());
|
return AndroidInAppWebViewOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidInAppWebViewOptions copyWithValue(AndroidInAppWebViewOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return AndroidInAppWebViewOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the iOS-only WebView options available.
|
///This class represents all the iOS-only WebView options available.
|
||||||
|
@ -783,7 +771,7 @@ class IOSInAppWebViewOptions
|
||||||
///**NOTE**: available on iOS 13.0+.
|
///**NOTE**: available on iOS 13.0+.
|
||||||
bool automaticallyAdjustsScrollIndicatorInsets;
|
bool automaticallyAdjustsScrollIndicatorInsets;
|
||||||
|
|
||||||
///A Boolean value indicating whether the view ignores an accessibility request to invert its colors.
|
///A Boolean value indicating whether the WebView ignores an accessibility request to invert its colors.
|
||||||
///The default value is `false`.
|
///The default value is `false`.
|
||||||
///
|
///
|
||||||
///**NOTE**: available on iOS 11.0+.
|
///**NOTE**: available on iOS 11.0+.
|
||||||
|
@ -949,12 +937,6 @@ class IOSInAppWebViewOptions
|
||||||
IOSInAppWebViewOptions copy() {
|
IOSInAppWebViewOptions copy() {
|
||||||
return IOSInAppWebViewOptions.fromMap(this.toMap());
|
return IOSInAppWebViewOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
IOSInAppWebViewOptions copyWithValue(IOSInAppWebViewOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return IOSInAppWebViewOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the cross-platform [InAppBrowser] options available.
|
///This class represents all the cross-platform [InAppBrowser] options available.
|
||||||
|
@ -1012,12 +994,6 @@ class InAppBrowserOptions
|
||||||
InAppBrowserOptions copy() {
|
InAppBrowserOptions copy() {
|
||||||
return InAppBrowserOptions.fromMap(this.toMap());
|
return InAppBrowserOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
InAppBrowserOptions copyWithValue(InAppBrowserOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return InAppBrowserOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the Android-only [InAppBrowser] options available.
|
///This class represents all the Android-only [InAppBrowser] options available.
|
||||||
|
@ -1073,12 +1049,6 @@ class AndroidInAppBrowserOptions implements BrowserOptions, AndroidOptions {
|
||||||
AndroidInAppBrowserOptions copy() {
|
AndroidInAppBrowserOptions copy() {
|
||||||
return AndroidInAppBrowserOptions.fromMap(this.toMap());
|
return AndroidInAppBrowserOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidInAppBrowserOptions copyWithValue(AndroidInAppBrowserOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return AndroidInAppBrowserOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the iOS-only [InAppBrowser] options available.
|
///This class represents all the iOS-only [InAppBrowser] options available.
|
||||||
|
@ -1160,12 +1130,6 @@ class IOSInAppBrowserOptions implements BrowserOptions, IosOptions {
|
||||||
IOSInAppBrowserOptions copy() {
|
IOSInAppBrowserOptions copy() {
|
||||||
return IOSInAppBrowserOptions.fromMap(this.toMap());
|
return IOSInAppBrowserOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
IOSInAppBrowserOptions copyWithValue(IOSInAppBrowserOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return IOSInAppBrowserOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the Android-only [ChromeSafariBrowser] options available.
|
///This class represents all the Android-only [ChromeSafariBrowser] options available.
|
||||||
|
@ -1245,12 +1209,6 @@ class AndroidChromeCustomTabsOptions
|
||||||
AndroidChromeCustomTabsOptions copy() {
|
AndroidChromeCustomTabsOptions copy() {
|
||||||
return AndroidChromeCustomTabsOptions.fromMap(this.toMap());
|
return AndroidChromeCustomTabsOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidChromeCustomTabsOptions copyWithValue(AndroidChromeCustomTabsOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return AndroidChromeCustomTabsOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///This class represents all the iOS-only [ChromeSafariBrowser] options available.
|
///This class represents all the iOS-only [ChromeSafariBrowser] options available.
|
||||||
|
@ -1333,10 +1291,4 @@ class IOSSafariOptions implements ChromeSafariBrowserOptions, IosOptions {
|
||||||
IOSSafariOptions copy() {
|
IOSSafariOptions copy() {
|
||||||
return IOSSafariOptions.fromMap(this.toMap());
|
return IOSSafariOptions.fromMap(this.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
IOSSafariOptions copyWithValue(IOSSafariOptions webViewOptions) {
|
|
||||||
var mergedMap = this.toMap();
|
|
||||||
mergedMap.addAll(webViewOptions.toMap());
|
|
||||||
return IOSSafariOptions.fromMap(mergedMap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
uuid: ^2.0.0
|
uuid: ^2.0.0
|
||||||
mime: ^0.9.6+2
|
mime: ^0.9.6+2
|
||||||
html: ^0.14.0+3
|
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||||
|
|
Loading…
Reference in New Issue