Added initialSize property and setSize/getSize methods to the HeadlessInAppWebView class, androidOnScaleChanged event is deprecated - use onZoomScaleChanged event, getScale method is deprecated - use getZoomScale method, Removed final keyword for all HeadlessInAppWebView events, Fixed wrong usage of Android WebView scale property
This commit is contained in:
parent
14d06fad48
commit
22ea0091cd
420
.idea/libraries/Dart_Packages.xml
generated
420
.idea/libraries/Dart_Packages.xml
generated
@ -1,420 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Dart Packages" type="DartPackagesLibraryType">
|
||||
<properties>
|
||||
<option name="packageNameToDirsMap">
|
||||
<entry key="archive">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/archive-3.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="async">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="boolean_selector">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="characters">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="charcode">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="clock">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="collection">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="crypto">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="cupertino_icons">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="fake_async">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="ffi">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/ffi-1.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="file">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/file-6.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="flutter">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="flutter_downloader">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="flutter_driver">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter_driver/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="flutter_test">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter_test/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="fuchsia_remote_debug_protocol">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/fuchsia_remote_debug_protocol/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="integration_test">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/integration_test/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="matcher">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="meta">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path_provider">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path_provider_linux">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path_provider_macos">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path_provider_platform_interface">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.0-nullsafety/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="path_provider_windows">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="pedantic">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pedantic-1.10.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="permission_handler">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="permission_handler_platform_interface">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/permission_handler_platform_interface-2.0.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="platform">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/platform-3.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="plugin_platform_interface">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-1.1.0-nullsafety.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="process">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/process-4.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="sky_engine">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/fvm/versions/2.1.0-10.0.pre/bin/cache/pkg/sky_engine/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="source_span">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="stack_trace">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="stream_channel">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="string_scanner">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="sync_http">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/sync_http-0.3.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="term_glyph">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="test_api">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.19/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="typed_data">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="url_launcher">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="url_launcher_linux">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="url_launcher_macos">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="url_launcher_platform_interface">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_platform_interface-2.0.0-nullsafety.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="url_launcher_windows">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="vector_math">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="vm_service">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service-6.0.1-nullsafety.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="webdriver">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/webdriver-3.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="win32">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/win32-2.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="xdg_directories">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0-nullsafety.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
</option>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/archive-3.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/ffi-1.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/file-6.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.0-nullsafety/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pedantic-1.10.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/permission_handler_platform_interface-2.0.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/platform-3.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-1.1.0-nullsafety.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/process-4.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/sync_http-0.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.19/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_platform_interface-2.0.0-nullsafety.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service-6.0.1-nullsafety.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/webdriver-3.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/win32-2.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0-nullsafety.1/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/bin/cache/pkg/sky_engine/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter_driver/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/flutter_test/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/fuchsia_remote_debug_protocol/lib" />
|
||||
<root url="file://$USER_HOME$/fvm/versions/2.1.0-10.0.pre/packages/integration_test/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
4
.idea/libraries/Flutter_Plugins.xml
generated
4
.idea/libraries/Flutter_Plugins.xml
generated
@ -1,6 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Flutter Plugins">
|
||||
<CLASSES />
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
|
@ -1,3 +1,12 @@
|
||||
## 5.3.0
|
||||
|
||||
- Added `initialSize` property to the `HeadlessInAppWebView` class
|
||||
- Added `setSize` and `getSize` methods to the `HeadlessInAppWebView` class
|
||||
- `androidOnScaleChanged` WebView event is now deprecated. Use the new `onZoomScaleChanged` WebView event, that is available for both Android and iOS
|
||||
- `getScale` WebView method is now deprecated. Use the new `getZoomScale` WebView method
|
||||
- Removed `final` keyword for all `HeadlessInAppWebView` events
|
||||
- Fixed wrong usage of Android WebView scale property
|
||||
|
||||
## 5.2.1+1
|
||||
|
||||
- Fixed iOS "Unexpectedly found nil while unwrapping an Optional value: file flutter_inappwebview/WKUserContentController.swift, line 36" error when `applePayAPIEnabled` iOS-specific WebView option is enabled
|
||||
|
@ -10,7 +10,7 @@ import com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ChromeSafariB
|
||||
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabaseHandler;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserManager;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebViewFactory;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.HeadlessInAppWebViewManager;
|
||||
import com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview.HeadlessInAppWebViewManager;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
|
@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebView;
|
||||
|
||||
@ -332,8 +331,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||
case "getOriginalUrl":
|
||||
result.success((webView != null) ? webView.getOriginalUrl() : null);
|
||||
break;
|
||||
case "getScale":
|
||||
result.success((webView != null) ? webView.getUpdatedScale() : null);
|
||||
case "getZoomScale":
|
||||
result.success((webView != null) ? webView.zoomScale : null);
|
||||
break;
|
||||
case "getSelectedText":
|
||||
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.pichillilorenzo.flutter_inappwebview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.os.Build;
|
||||
@ -287,4 +288,8 @@ public class Util {
|
||||
} while (i < newline);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getPixelDensity(Context context) {
|
||||
return context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,119 @@
|
||||
package com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
||||
import com.pichillilorenzo.flutter_inappwebview.types.Size2D;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
|
||||
|
||||
protected static final String LOG_TAG = "HeadlessInAppWebView";
|
||||
@NonNull
|
||||
public final String id;
|
||||
public final MethodChannel channel;
|
||||
@Nullable
|
||||
public FlutterWebView flutterWebView;
|
||||
|
||||
public HeadlessInAppWebView(BinaryMessenger messenger, @NonNull String id, @NonNull FlutterWebView flutterWebView) {
|
||||
this.id = id;
|
||||
this.flutterWebView = flutterWebView;
|
||||
this.channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview_" + id);
|
||||
channel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "dispose":
|
||||
dispose();
|
||||
result.success(true);
|
||||
break;
|
||||
case "setSize":
|
||||
{
|
||||
Map<String, Object> sizeMap = (Map<String, Object>) call.argument("size");
|
||||
Size2D size = Size2D.fromMap(sizeMap);
|
||||
if (size != null)
|
||||
setSize(size);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getSize":
|
||||
{
|
||||
Size2D size = getSize();
|
||||
result.success(size != null ? size.toMap() : null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
public void onWebViewCreated() {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
channel.invokeMethod("onWebViewCreated", obj);
|
||||
}
|
||||
|
||||
public void prepare(Map<String, Object> params) {
|
||||
// Add the headless WebView to the view hierarchy.
|
||||
// This way is also possible to take screenshots.
|
||||
ViewGroup contentView = (ViewGroup) Shared.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null) {
|
||||
View view = flutterWebView.getView();
|
||||
final Map<String, Object> initialSize = (Map<String, Object>) params.get("initialSize");
|
||||
Size2D size = Size2D.fromMap(initialSize);
|
||||
if (size != null) {
|
||||
setSize(size);
|
||||
} else {
|
||||
view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
mainView.addView(view, 0);
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSize(@NonNull Size2D size) {
|
||||
if (flutterWebView != null && flutterWebView.webView != null) {
|
||||
View view = flutterWebView.getView();
|
||||
float scale = Util.getPixelDensity(view.getContext());
|
||||
view.setLayoutParams(new FrameLayout.LayoutParams((int) (size.getWidth() * scale), (int) (size.getHeight() * scale)));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Size2D getSize() {
|
||||
if (flutterWebView != null && flutterWebView.webView != null) {
|
||||
View view = flutterWebView.getView();
|
||||
float scale = Util.getPixelDensity(view.getContext());
|
||||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
|
||||
return new Size2D(layoutParams.width / scale, layoutParams.height / scale);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
HeadlessInAppWebViewManager.webViews.remove(id);
|
||||
ViewGroup contentView = (ViewGroup) Shared.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null) {
|
||||
mainView.removeView(flutterWebView.getView());
|
||||
}
|
||||
flutterWebView.dispose();
|
||||
flutterWebView = null;
|
||||
}
|
||||
}
|
@ -19,11 +19,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package com.pichillilorenzo.flutter_inappwebview.in_app_webview;
|
||||
|
||||
import android.app.Activity;
|
||||
package com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -33,14 +32,11 @@ import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
|
||||
/**
|
||||
* InAppBrowserManager
|
||||
*/
|
||||
public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHandler {
|
||||
|
||||
public MethodChannel channel;
|
||||
protected static final String LOG_TAG = "HeadlessInAppWebViewManager";
|
||||
Map<String, FlutterWebView> flutterWebViews = new HashMap<>();
|
||||
public MethodChannel channel;
|
||||
public static final Map<String, HeadlessInAppWebView> webViews = new HashMap<>();
|
||||
|
||||
public HeadlessInAppWebViewManager(BinaryMessenger messenger) {
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview");
|
||||
@ -49,40 +45,34 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
|
||||
|
||||
@Override
|
||||
public void onMethodCall(final MethodCall call, final Result result) {
|
||||
final Activity activity = Shared.activity;
|
||||
final String id = (String) call.argument("id");
|
||||
|
||||
switch (call.method) {
|
||||
case "createHeadlessWebView":
|
||||
case "run":
|
||||
{
|
||||
HashMap<String, Object> params = (HashMap<String, Object>) call.argument("params");
|
||||
createHeadlessWebView(activity, id, params);
|
||||
HeadlessInAppWebViewManager.run(id, params);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "disposeHeadlessWebView":
|
||||
disposeHeadlessWebView(id);
|
||||
result.success(true);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void createHeadlessWebView(Activity activity, String id, HashMap<String, Object> params) {
|
||||
FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, activity, id, params, null);
|
||||
flutterWebViews.put(id, flutterWebView);
|
||||
}
|
||||
|
||||
public void disposeHeadlessWebView(String id) {
|
||||
if (flutterWebViews.containsKey(id)) {
|
||||
flutterWebViews.get(id).dispose();
|
||||
flutterWebViews.remove(id);
|
||||
}
|
||||
public static void run(String id, HashMap<String, Object> params) {
|
||||
FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, Shared.activity, id, params, null);
|
||||
HeadlessInAppWebView headlessInAppWebView = new HeadlessInAppWebView(Shared.messenger, id, flutterWebView);
|
||||
HeadlessInAppWebViewManager.webViews.put(id, headlessInAppWebView);
|
||||
|
||||
headlessInAppWebView.prepare(params);
|
||||
headlessInAppWebView.onWebViewCreated();
|
||||
flutterWebView.makeInitialLoad(params);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
HeadlessInAppWebViewManager.webViews.clear();
|
||||
channel.setMethodCallHandler(null);
|
||||
}
|
||||
}
|
@ -44,16 +44,14 @@ public class FlutterWebView implements PlatformView {
|
||||
public InAppWebViewMethodHandler methodCallDelegate;
|
||||
public PullToRefreshLayout pullToRefreshLayout;
|
||||
|
||||
public FlutterWebView(BinaryMessenger messenger, final Context context, Object id, HashMap<String, Object> params, View containerView) {
|
||||
public FlutterWebView(BinaryMessenger messenger, final Context context, Object id,
|
||||
HashMap<String, Object> params, View containerView) {
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
|
||||
|
||||
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
|
||||
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
||||
displayListenerProxy.onPreWebViewInitialization(displayManager);
|
||||
|
||||
Map<String, Object> initialUrlRequest = (Map<String, Object>) params.get("initialUrlRequest");
|
||||
final String initialFile = (String) params.get("initialFile");
|
||||
final Map<String, String> initialData = (Map<String, String>) params.get("initialData");
|
||||
|
||||
Map<String, Object> initialOptions = (Map<String, Object>) params.get("initialOptions");
|
||||
Map<String, Object> contextMenu = (Map<String, Object>) params.get("contextMenu");
|
||||
Integer windowId = (Integer) params.get("windowId");
|
||||
@ -95,6 +93,18 @@ public class FlutterWebView implements PlatformView {
|
||||
channel.setMethodCallHandler(methodCallDelegate);
|
||||
|
||||
webView.prepare();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return pullToRefreshLayout != null ? pullToRefreshLayout : webView;
|
||||
}
|
||||
|
||||
public void makeInitialLoad(HashMap<String, Object> params) {
|
||||
Integer windowId = (Integer) params.get("windowId");
|
||||
Map<String, Object> initialUrlRequest = (Map<String, Object>) params.get("initialUrlRequest");
|
||||
final String initialFile = (String) params.get("initialFile");
|
||||
final Map<String, String> initialData = (Map<String, String>) params.get("initialData");
|
||||
|
||||
if (windowId != null) {
|
||||
Message resultMsg = InAppWebViewChromeClient.windowWebViewMessages.get(windowId);
|
||||
@ -109,7 +119,6 @@ public class FlutterWebView implements PlatformView {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, initialFile + " asset file cannot be found!", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (initialData != null) {
|
||||
@ -125,16 +134,6 @@ public class FlutterWebView implements PlatformView {
|
||||
webView.loadUrl(urlRequest);
|
||||
}
|
||||
}
|
||||
|
||||
if (containerView == null && id instanceof String) {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
channel.invokeMethod("onHeadlessWebViewCreated", obj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return pullToRefreshLayout != null ? pullToRefreshLayout : webView;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,7 +23,9 @@ public class FlutterWebViewFactory extends PlatformViewFactory {
|
||||
@Override
|
||||
public PlatformView create(Context context, int id, Object args) {
|
||||
HashMap<String, Object> params = (HashMap<String, Object>) args;
|
||||
return new FlutterWebView(messenger, context, id, params, containerView);
|
||||
FlutterWebView flutterWebView = new FlutterWebView(messenger, context, id, params, containerView);
|
||||
flutterWebView.makeInitialLoad(params);
|
||||
return flutterWebView;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
public InAppWebViewOptions options;
|
||||
public boolean isLoading = false;
|
||||
public OkHttpClient httpClient;
|
||||
public float scale = getResources().getDisplayMetrics().density;
|
||||
public float zoomScale = 1.0f;
|
||||
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
||||
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
||||
public Pattern regexToCancelSubFramesLoadingCompiled;
|
||||
@ -579,6 +579,8 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
}
|
||||
|
||||
public void takeScreenshot(final @Nullable Map<String, Object> screenshotConfiguration, final MethodChannel.Result result) {
|
||||
final float pixelDensity = Util.getPixelDensity(getContext());
|
||||
|
||||
headlessHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -595,10 +597,10 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
if (screenshotConfiguration != null) {
|
||||
Map<String, Double> rect = (Map<String, Double>) screenshotConfiguration.get("rect");
|
||||
if (rect != null) {
|
||||
int rectX = (int) Math.floor(rect.get("x") * scale + 0.5);
|
||||
int rectY = (int) Math.floor(rect.get("y") * scale + 0.5);
|
||||
int rectWidth = Math.min(resized.getWidth(), (int) Math.floor(rect.get("width") * scale + 0.5));
|
||||
int rectHeight = Math.min(resized.getHeight(), (int) Math.floor(rect.get("height") * scale + 0.5));
|
||||
int rectX = (int) Math.floor(rect.get("x") * pixelDensity + 0.5);
|
||||
int rectY = (int) Math.floor(rect.get("y") * pixelDensity + 0.5);
|
||||
int rectWidth = Math.min(resized.getWidth(), (int) Math.floor(rect.get("width") * pixelDensity + 0.5));
|
||||
int rectHeight = Math.min(resized.getHeight(), (int) Math.floor(rect.get("height") * pixelDensity + 0.5));
|
||||
resized = Bitmap.createBitmap(
|
||||
resized,
|
||||
rectX,
|
||||
@ -609,7 +611,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
|
||||
Double snapshotWidth = (Double) screenshotConfiguration.get("snapshotWidth");
|
||||
if (snapshotWidth != null) {
|
||||
int dstWidth = (int) Math.floor(snapshotWidth * scale + 0.5);
|
||||
int dstWidth = (int) Math.floor(snapshotWidth * pixelDensity + 0.5);
|
||||
float ratioBitmap = (float) resized.getWidth() / (float) resized.getHeight();
|
||||
int dstHeight = (int) ((float) dstWidth / ratioBitmap);
|
||||
resized = Bitmap.createScaledBitmap(resized, dstWidth, dstHeight, true);
|
||||
@ -1222,10 +1224,6 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
}
|
||||
}
|
||||
|
||||
public Float getUpdatedScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu) {
|
||||
super.onCreateContextMenu(menu);
|
||||
@ -1509,7 +1507,7 @@ final public class InAppWebView extends InputAwareWebView {
|
||||
if (floatingContextMenu != null) {
|
||||
if (value != null && !value.equalsIgnoreCase("null")) {
|
||||
int x = contextMenuPoint.x;
|
||||
int y = (int) ((Float.parseFloat(value) * scale) + (floatingContextMenu.getHeight() / 3.5));
|
||||
int y = (int) ((Float.parseFloat(value) * Util.getPixelDensity(getContext())) + (floatingContextMenu.getHeight() / 3.5));
|
||||
contextMenuPoint.y = y;
|
||||
onFloatingActionGlobalLayout(x, y);
|
||||
} else {
|
||||
|
@ -23,6 +23,7 @@ import android.webkit.WebViewClient;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabase;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
|
||||
@ -508,12 +509,12 @@ public class InAppWebViewClient extends WebViewClient {
|
||||
public void onScaleChanged(WebView view, float oldScale, float newScale) {
|
||||
super.onScaleChanged(view, oldScale, newScale);
|
||||
final InAppWebView webView = (InAppWebView) view;
|
||||
webView.scale = newScale;
|
||||
webView.zoomScale = newScale / Util.getPixelDensity(webView.getContext());
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("oldScale", oldScale);
|
||||
obj.put("newScale", newScale);
|
||||
channel.invokeMethod("onScaleChanged", obj);
|
||||
channel.invokeMethod("onZoomScaleChanged", obj);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O_MR1)
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Size2D {
|
||||
private double width;
|
||||
private double height;
|
||||
|
||||
public Size2D(double width, double height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Size2D fromMap(@Nullable Map<String, Object> map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
Double width = (Double) map.get("width");
|
||||
Double height = (Double) map.get("height");
|
||||
assert width != null;
|
||||
assert height != null;
|
||||
return new Size2D(width, height);
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> sizeMap = new HashMap<>();
|
||||
sizeMap.put("width", width);
|
||||
sizeMap.put("height", height);
|
||||
return sizeMap;
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(double width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Size2D size = (Size2D) o;
|
||||
|
||||
if (Double.compare(size.width, width) != 0) return false;
|
||||
return Double.compare(size.height, height) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(width);
|
||||
result = (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(height);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Size{" +
|
||||
"width=" + width +
|
||||
", height=" + height +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -3247,6 +3247,45 @@ setTimeout(function() {
|
||||
await expectLater(onTitleChangedCompleter.future, completes);
|
||||
});
|
||||
|
||||
testWidgets('onZoomScaleChanged', (WidgetTester tester) async {
|
||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||
final Completer<void> pageLoaded = Completer<void>();
|
||||
final Completer<void> onZoomScaleChangedCompleter = Completer<void>();
|
||||
|
||||
var listenForScaleChange = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: InAppWebView(
|
||||
key: GlobalKey(),
|
||||
initialUrlRequest:
|
||||
URLRequest(url: Uri.parse('https://github.com/flutter')),
|
||||
onWebViewCreated: (controller) {
|
||||
controllerCompleter.complete(controller);
|
||||
},
|
||||
onLoadStop: (controller, url) {
|
||||
pageLoaded.complete();
|
||||
},
|
||||
onZoomScaleChanged: (controller, oldScale, newScale) {
|
||||
if (listenForScaleChange) {
|
||||
onZoomScaleChangedCompleter.complete();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final InAppWebViewController controller =
|
||||
await controllerCompleter.future;
|
||||
await pageLoaded.future;
|
||||
listenForScaleChange = true;
|
||||
|
||||
await controller.zoomBy(zoomFactor: 2);
|
||||
|
||||
await expectLater(onZoomScaleChangedCompleter.future, completes);
|
||||
});
|
||||
|
||||
testWidgets('androidOnPermissionRequest', (WidgetTester tester) async {
|
||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||
final Completer<void> pageLoaded = Completer<void>();
|
||||
@ -3341,50 +3380,6 @@ setTimeout(function() {
|
||||
expect(resourceLoaded, containsAll(resourceList));
|
||||
}, skip: !Platform.isAndroid);
|
||||
|
||||
testWidgets('androidOnScaleChanged', (WidgetTester tester) async {
|
||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||
final Completer<void> pageLoaded = Completer<void>();
|
||||
final Completer<void> onScaleChangedCompleter = Completer<void>();
|
||||
|
||||
var listenForScaleChange = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: InAppWebView(
|
||||
key: GlobalKey(),
|
||||
initialUrlRequest:
|
||||
URLRequest(url: Uri.parse('https://flutter.dev/')),
|
||||
onWebViewCreated: (controller) {
|
||||
controllerCompleter.complete(controller);
|
||||
},
|
||||
onLoadStop: (controller, url) {
|
||||
pageLoaded.complete();
|
||||
},
|
||||
androidOnScaleChanged: (controller, oldScale, newScale) {
|
||||
if (listenForScaleChange) {
|
||||
onScaleChangedCompleter.complete();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final InAppWebViewController controller =
|
||||
await controllerCompleter.future;
|
||||
await pageLoaded.future;
|
||||
listenForScaleChange = true;
|
||||
|
||||
await controller.evaluateJavascript(source: """
|
||||
var meta = document.createElement('meta');
|
||||
meta.setAttribute('name', 'viewport');
|
||||
meta.setAttribute('content', 'width=device-width, initial-scale=2.0, maximum-scale=2.0, minimum-scale=2.0, user-scalable=no');
|
||||
document.getElementsByTagName('head')[0].appendChild(meta);
|
||||
""");
|
||||
|
||||
await expectLater(onScaleChangedCompleter.future, completes);
|
||||
}, skip: !Platform.isAndroid);
|
||||
|
||||
testWidgets('androidOnReceivedIcon', (WidgetTester tester) async {
|
||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||
final Completer<void> pageLoaded = Completer<void>();
|
||||
@ -4540,7 +4535,7 @@ setTimeout(function() {
|
||||
controller.zoomBy(zoomFactor: 3.0, iosAnimated: true), completes);
|
||||
});
|
||||
|
||||
testWidgets('getScale', (WidgetTester tester) async {
|
||||
testWidgets('getZoomScale', (WidgetTester tester) async {
|
||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||
final Completer<void> pageLoaded = Completer<void>();
|
||||
|
||||
@ -4565,7 +4560,7 @@ setTimeout(function() {
|
||||
await controllerCompleter.future;
|
||||
await pageLoaded.future;
|
||||
|
||||
final scale = await controller.getScale();
|
||||
final scale = await controller.getZoomScale();
|
||||
expect(scale, isNonZero);
|
||||
expect(scale, isPositive);
|
||||
});
|
||||
|
@ -80,6 +80,5 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
95
ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift
Normal file
95
ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// HeadlessInAppWebView.swift
|
||||
// flutter_inappwebview
|
||||
//
|
||||
// Created by Lorenzo Pichilli on 26/03/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class HeadlessInAppWebView : FlutterMethodCallDelegate {
|
||||
var id: String
|
||||
var channel: FlutterMethodChannel?
|
||||
var flutterWebView: FlutterWebViewController?
|
||||
|
||||
public init(id: String, flutterWebView: FlutterWebViewController) {
|
||||
self.id = id
|
||||
super.init()
|
||||
self.flutterWebView = flutterWebView
|
||||
self.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_headless_inappwebview_" + id,
|
||||
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
|
||||
self.channel?.setMethodCallHandler(self.handle)
|
||||
}
|
||||
|
||||
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
let arguments = call.arguments as? NSDictionary
|
||||
|
||||
switch call.method {
|
||||
case "dispose":
|
||||
dispose()
|
||||
result(true)
|
||||
break
|
||||
case "setSize":
|
||||
let sizeMap = arguments!["size"] as? [String: Any?]
|
||||
if let size = Size2D.fromMap(map: sizeMap) {
|
||||
setSize(size: size)
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "getSize":
|
||||
result(getSize()?.toMap())
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func onWebViewCreated() {
|
||||
let arguments: [String: Any?] = [:]
|
||||
channel?.invokeMethod("onWebViewCreated", arguments: arguments)
|
||||
}
|
||||
|
||||
public func prepare(params: NSDictionary) {
|
||||
if let view = flutterWebView?.view() {
|
||||
view.alpha = 0.01
|
||||
let initialSize = params["initialSize"] as? [String: Any?]
|
||||
if let size = Size2D.fromMap(map: initialSize) {
|
||||
setSize(size: size)
|
||||
} else {
|
||||
view.frame = CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
|
||||
}
|
||||
if let keyWindow = UIApplication.shared.keyWindow {
|
||||
/// Note: The WKWebView behaves very unreliable when rendering offscreen
|
||||
/// on a device. This is especially true with JavaScript, which simply
|
||||
/// won't be executed sometimes.
|
||||
/// So, add the headless WKWebView to the view hierarchy.
|
||||
/// This way is also possible to take screenshots.
|
||||
keyWindow.insertSubview(view, at: 0)
|
||||
keyWindow.sendSubviewToBack(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func setSize(size: Size2D) {
|
||||
if let view = flutterWebView?.view() {
|
||||
let width = size.width == -1.0 ? UIScreen.main.bounds.width : CGFloat(size.width)
|
||||
let height = size.height == -1.0 ? UIScreen.main.bounds.height : CGFloat(size.height)
|
||||
view.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
public func getSize() -> Size2D? {
|
||||
if let view = flutterWebView?.view() {
|
||||
return Size2D(width: Double(view.frame.width), height: Double(view.frame.height))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
channel?.setMethodCallHandler(nil)
|
||||
channel = nil
|
||||
HeadlessInAppWebViewManager.webViews.removeValue(forKey: id)
|
||||
flutterWebView = nil
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ import AVFoundation
|
||||
public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
||||
static var registrar: FlutterPluginRegistrar?
|
||||
static var channel: FlutterMethodChannel?
|
||||
var flutterWebViews: [String: FlutterWebViewController] = [:]
|
||||
static var webViews: [String: HeadlessInAppWebView] = [:]
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
|
||||
@ -34,13 +34,9 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
||||
let id: String = arguments!["id"] as! String
|
||||
|
||||
switch call.method {
|
||||
case "createHeadlessWebView":
|
||||
case "run":
|
||||
let params = arguments!["params"] as! [String: Any?]
|
||||
createHeadlessWebView(id: id, params: params)
|
||||
result(true)
|
||||
break
|
||||
case "disposeHeadlessWebView":
|
||||
disposeHeadlessWebView(id: id)
|
||||
HeadlessInAppWebViewManager.run(id: id, params: params)
|
||||
result(true)
|
||||
break
|
||||
default:
|
||||
@ -49,17 +45,16 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
public func createHeadlessWebView(id: String, params: [String: Any?]) {
|
||||
let controller = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
|
||||
public static func run(id: String, params: [String: Any?]) {
|
||||
let flutterWebView = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
|
||||
withFrame: CGRect.zero,
|
||||
viewIdentifier: id,
|
||||
arguments: params as NSDictionary)
|
||||
flutterWebViews[id] = controller
|
||||
}
|
||||
|
||||
public func disposeHeadlessWebView(id: String) {
|
||||
if let _ = flutterWebViews[id] {
|
||||
flutterWebViews.removeValue(forKey: id)
|
||||
}
|
||||
params: params as NSDictionary)
|
||||
let headlessInAppWebView = HeadlessInAppWebView(id: id, flutterWebView: flutterWebView)
|
||||
HeadlessInAppWebViewManager.webViews[id] = headlessInAppWebView
|
||||
|
||||
headlessInAppWebView.prepare(params: params as NSDictionary)
|
||||
headlessInAppWebView.onWebViewCreated()
|
||||
flutterWebView.makeInitialLoad(params: params as NSDictionary)
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||
var myView: UIView?
|
||||
var methodCallDelegate: InAppWebViewMethodHandler?
|
||||
|
||||
init(registrar: FlutterPluginRegistrar, withFrame frame: CGRect, viewIdentifier viewId: Any, arguments args: NSDictionary) {
|
||||
init(registrar: FlutterPluginRegistrar, withFrame frame: CGRect, viewIdentifier viewId: Any, params: NSDictionary) {
|
||||
super.init()
|
||||
|
||||
self.registrar = registrar
|
||||
@ -29,14 +29,11 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||
myView = UIView(frame: frame)
|
||||
myView!.clipsToBounds = true
|
||||
|
||||
let initialUrlRequest = args["initialUrlRequest"] as? [String: Any?]
|
||||
let initialFile = args["initialFile"] as? String
|
||||
let initialData = args["initialData"] as? [String: String]
|
||||
let initialOptions = args["initialOptions"] as! [String: Any?]
|
||||
let contextMenu = args["contextMenu"] as? [String: Any]
|
||||
let windowId = args["windowId"] as? Int64
|
||||
let initialUserScripts = args["initialUserScripts"] as? [[String: Any]]
|
||||
let pullToRefreshInitialOptions = args["pullToRefreshOptions"] as! [String: Any?]
|
||||
let initialOptions = params["initialOptions"] as! [String: Any?]
|
||||
let contextMenu = params["contextMenu"] as? [String: Any]
|
||||
let windowId = params["windowId"] as? Int64
|
||||
let initialUserScripts = params["initialUserScripts"] as? [[String: Any]]
|
||||
let pullToRefreshInitialOptions = params["pullToRefreshOptions"] as! [String: Any?]
|
||||
|
||||
var userScripts: [UserScript] = []
|
||||
if let initialUserScripts = initialUserScripts {
|
||||
@ -83,6 +80,17 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||
webView!.options = options
|
||||
webView!.prepare()
|
||||
webView!.windowCreated = true
|
||||
}
|
||||
|
||||
public func view() -> UIView {
|
||||
return myView!
|
||||
}
|
||||
|
||||
public func makeInitialLoad(params: NSDictionary) {
|
||||
let windowId = params["windowId"] as? Int64
|
||||
let initialUrlRequest = params["initialUrlRequest"] as? [String: Any?]
|
||||
let initialFile = params["initialFile"] as? String
|
||||
let initialData = params["initialData"] as? [String: String]
|
||||
|
||||
if windowId == nil {
|
||||
if #available(iOS 11.0, *) {
|
||||
@ -116,37 +124,9 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||
else if let wId = windowId, let webViewTransport = InAppWebView.windowWebViews[wId] {
|
||||
webView!.load(webViewTransport.request)
|
||||
}
|
||||
|
||||
if (frame.isEmpty && viewId is String) {
|
||||
/// Note: The WKWebView behaves very unreliable when rendering offscreen
|
||||
/// on a device. This is especially true with JavaScript, which simply
|
||||
/// won't be executed sometimes.
|
||||
/// Therefore, I decided to add this very ugly hack where the rendering
|
||||
/// webview will be added to the view hierarchy (between the
|
||||
/// rootViewController's view and the key window).
|
||||
self.myView!.alpha = 0.01
|
||||
UIApplication.shared.keyWindow!.insertSubview(self.myView!, at: 0)
|
||||
|
||||
let arguments: [String: Any] = ["id": viewId]
|
||||
channel!.invokeMethod("onHeadlessWebViewCreated", arguments: arguments)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("FlutterWebViewController - dealloc")
|
||||
channel?.setMethodCallHandler(nil)
|
||||
methodCallDelegate?.webView = nil
|
||||
methodCallDelegate = nil
|
||||
webView?.dispose()
|
||||
webView = nil
|
||||
myView = nil
|
||||
}
|
||||
|
||||
public func view() -> UIView {
|
||||
return myView!
|
||||
}
|
||||
|
||||
public func load(initialUrlRequest: [String:Any?]?, initialFile: String?, initialData: [String: String]?) {
|
||||
func load(initialUrlRequest: [String:Any?]?, initialFile: String?, initialData: [String: String]?) {
|
||||
if let initialFile = initialFile {
|
||||
do {
|
||||
try webView?.loadFile(assetFilePath: initialFile)
|
||||
@ -174,4 +154,18 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||
webView?.loadUrl(urlRequest: urlRequest, allowingReadAccessTo: allowingReadAccessToURL)
|
||||
}
|
||||
}
|
||||
|
||||
func dispose() {
|
||||
channel?.setMethodCallHandler(nil)
|
||||
methodCallDelegate?.webView = nil
|
||||
methodCallDelegate = nil
|
||||
webView?.dispose()
|
||||
webView = nil
|
||||
myView = nil
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("FlutterWebViewController - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ public class FlutterWebViewFactory: NSObject, FlutterPlatformViewFactory {
|
||||
let webviewController = FlutterWebViewController(registrar: registrar!,
|
||||
withFrame: frame,
|
||||
viewIdentifier: viewId,
|
||||
arguments: arguments!)
|
||||
params: arguments!)
|
||||
webviewController.makeInitialLoad(params: arguments!)
|
||||
return webviewController
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
|
||||
var callAsyncJavaScriptBelowIOS14Results: [String:((Any?) -> Void)] = [:]
|
||||
|
||||
var oldZoomScale = Float(1.0)
|
||||
|
||||
init(frame: CGRect, configuration: WKWebViewConfiguration, contextMenu: [String: Any]?, channel: FlutterMethodChannel?, userScripts: [UserScript] = []) {
|
||||
super.init(frame: frame, configuration: configuration)
|
||||
self.channel = channel
|
||||
@ -270,6 +272,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
scrollView.addGestureRecognizer(self.longPressRecognizer)
|
||||
scrollView.addGestureRecognizer(self.recognizerForDisablingContextMenuOnLinks)
|
||||
scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset), options: [.new, .old], context: nil)
|
||||
scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale), options: [.new, .old], context: nil)
|
||||
|
||||
addObserver(self,
|
||||
forKeyPath: #keyPath(WKWebView.estimatedProgress),
|
||||
@ -2056,6 +2059,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
}
|
||||
}
|
||||
|
||||
public func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||
let newScale = Float(scrollView.zoomScale)
|
||||
if newScale != oldZoomScale {
|
||||
self.onZoomScaleChanged(newScale: newScale, oldScale: oldZoomScale)
|
||||
oldZoomScale = newScale
|
||||
}
|
||||
}
|
||||
|
||||
public func webView(_ webView: WKWebView,
|
||||
createWebViewWith configuration: WKWebViewConfiguration,
|
||||
for navigationAction: WKNavigationAction,
|
||||
@ -2306,6 +2317,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||
channel?.invokeMethod("onScrollChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onZoomScaleChanged(newScale: Float, oldScale: Float) {
|
||||
let arguments: [String: Any] = ["newScale": newScale, "oldScale": oldScale]
|
||||
channel?.invokeMethod("onZoomScaleChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onOverScrolled(x: Int, y: Int, clampedX: Bool, clampedY: Bool) {
|
||||
let arguments: [String: Any] = ["x": x, "y": y, "clampedX": clampedX, "clampedY": clampedY]
|
||||
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
||||
@ -2678,7 +2694,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
||||
scrollView.setZoomScale(currentZoomScale * CGFloat(zoomFactor), animated: animated)
|
||||
}
|
||||
|
||||
public func getScale() -> Float {
|
||||
public func getZoomScale() -> Float {
|
||||
return Float(scrollView.zoomScale)
|
||||
}
|
||||
|
||||
@ -2869,6 +2885,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
||||
imp_removeBlock(imp)
|
||||
}
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
||||
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
||||
longPressRecognizer.delegate = nil
|
||||
scrollView.removeGestureRecognizer(longPressRecognizer)
|
||||
|
@ -293,8 +293,8 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||
webView?.reloadFromOrigin()
|
||||
result(true)
|
||||
break
|
||||
case "getScale":
|
||||
result(webView?.getScale())
|
||||
case "getZoomScale":
|
||||
result(webView?.getZoomScale())
|
||||
break
|
||||
case "hasOnlySecureContent":
|
||||
result(webView?.hasOnlySecureContent ?? false)
|
||||
|
35
ios/Classes/Types/Size2D.swift
Normal file
35
ios/Classes/Types/Size2D.swift
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Size.swift
|
||||
// flutter_inappwebview
|
||||
//
|
||||
// Created by Lorenzo Pichilli on 26/03/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class Size2D : NSObject {
|
||||
var width: Double
|
||||
var height: Double
|
||||
|
||||
public init(width: Double, height: Double) {
|
||||
self.width = width
|
||||
self.height = height
|
||||
}
|
||||
|
||||
public static func fromMap(map: [String:Any?]?) -> Size2D? {
|
||||
guard let map = map else {
|
||||
return nil
|
||||
}
|
||||
return Size2D(
|
||||
width: map["width"] as? Double ?? -1.0,
|
||||
height: map["height"] as? Double ?? -1.0
|
||||
)
|
||||
}
|
||||
|
||||
public func toMap() -> [String:Any?] {
|
||||
return [
|
||||
"width": width,
|
||||
"height": height
|
||||
]
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ class InAppBrowser {
|
||||
const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
||||
|
||||
/// WebView Controller that can be used to access the [InAppWebViewController] API.
|
||||
late InAppWebViewController webViewController;
|
||||
late final InAppWebViewController webViewController;
|
||||
|
||||
///The window id of a [CreateWindowAction.windowId].
|
||||
final int? windowId;
|
||||
@ -620,6 +620,19 @@ class InAppBrowser {
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#onOverScrolled(int,%20int,%20boolean,%20boolean)
|
||||
void onOverScrolled(int x, int y, bool clampedX, bool clampedY) {}
|
||||
|
||||
///Event fired when the zoom scale of the WebView has changed.
|
||||
///
|
||||
///[oldScale] The old zoom scale factor.
|
||||
///
|
||||
///[newScale] The new zoom scale factor.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||
///
|
||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619409-scrollviewdidzoom
|
||||
void onZoomScaleChanged(double oldScale, double newScale) {}
|
||||
|
||||
///Event fired when the WebView notifies that a loading URL has been flagged by Safe Browsing.
|
||||
///The default behavior is to show an interstitial to the user, with the reporting checkbox visible.
|
||||
///
|
||||
@ -738,15 +751,8 @@ class InAppBrowser {
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onFormResubmission(android.webkit.WebView,%20android.os.Message,%20android.os.Message)
|
||||
Future<FormResubmissionAction?>? androidOnFormResubmission(Uri? url) {}
|
||||
|
||||
///Event fired when the scale applied to the WebView has changed.
|
||||
///
|
||||
///[oldScale] The old scale factor.
|
||||
///
|
||||
///[newScale] The new scale factor.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||
///Use [onZoomScaleChanged] instead.
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
void androidOnScaleChanged(double oldScale, double newScale) {}
|
||||
|
||||
///Event fired when there is new favicon for the current page.
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_inappwebview/src/util.dart';
|
||||
@ -11,6 +12,7 @@ import 'in_app_webview_controller.dart';
|
||||
import 'in_app_webview_options.dart';
|
||||
import '../pull_to_refresh/pull_to_refresh_controller.dart';
|
||||
import '../pull_to_refresh/pull_to_refresh_options.dart';
|
||||
import '../util.dart';
|
||||
|
||||
///Class that represents a WebView in headless mode.
|
||||
///It can be used to run a WebView in background without attaching an `InAppWebView` to the widget tree.
|
||||
@ -23,17 +25,33 @@ class HeadlessInAppWebView implements WebView {
|
||||
bool _started = false;
|
||||
bool _running = false;
|
||||
|
||||
static const MethodChannel _sharedChannel =
|
||||
const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
||||
static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
||||
late MethodChannel _channel;
|
||||
|
||||
///WebView Controller that can be used to access the [InAppWebViewController] API.
|
||||
late InAppWebViewController webViewController;
|
||||
late final InAppWebViewController webViewController;
|
||||
|
||||
///The window id of a [CreateWindowAction.windowId].
|
||||
final int? windowId;
|
||||
|
||||
///The WebView initial size in pixels.
|
||||
///
|
||||
///Set `-1` to match the corresponding width or height of the current device screen size.
|
||||
///`Size(-1, -1)` will match both width and height of the current device screen size.
|
||||
///
|
||||
///**NOTE for Android**: `Size` width and height values will be converted to `int` values because they cannot have `double` values.
|
||||
final Size initialSize;
|
||||
|
||||
HeadlessInAppWebView(
|
||||
{this.windowId,
|
||||
{this.initialSize = const Size(-1, -1),
|
||||
this.windowId,
|
||||
this.initialUrlRequest,
|
||||
this.initialFile,
|
||||
this.initialData,
|
||||
this.initialOptions,
|
||||
this.contextMenu,
|
||||
this.initialUserScripts,
|
||||
this.pullToRefreshController,
|
||||
this.onWebViewCreated,
|
||||
this.onLoadStart,
|
||||
this.onLoadStop,
|
||||
@ -78,6 +96,7 @@ class HeadlessInAppWebView implements WebView {
|
||||
this.androidOnRenderProcessResponsive,
|
||||
this.androidOnRenderProcessUnresponsive,
|
||||
this.androidOnFormResubmission,
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
this.androidOnScaleChanged,
|
||||
this.androidOnReceivedIcon,
|
||||
this.androidOnReceivedTouchIconUrl,
|
||||
@ -86,29 +105,26 @@ class HeadlessInAppWebView implements WebView {
|
||||
this.iosOnWebContentProcessDidTerminate,
|
||||
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
|
||||
this.iosOnNavigationResponse,
|
||||
this.iosShouldAllowDeprecatedTLS,
|
||||
this.initialUrlRequest,
|
||||
this.initialFile,
|
||||
this.initialData,
|
||||
this.initialOptions,
|
||||
this.contextMenu,
|
||||
this.initialUserScripts,
|
||||
this.pullToRefreshController}) {
|
||||
this.iosShouldAllowDeprecatedTLS}) {
|
||||
id = IdGenerator.generate();
|
||||
webViewController = new InAppWebViewController(id, this);
|
||||
this._channel = MethodChannel(
|
||||
'com.pichillilorenzo/flutter_headless_inappwebview_$id');
|
||||
this._channel.setMethodCallHandler(handleMethod);
|
||||
}
|
||||
|
||||
Future<dynamic> handleMethod(MethodCall call) async {
|
||||
switch (call.method) {
|
||||
case "onHeadlessWebViewCreated":
|
||||
case "onWebViewCreated":
|
||||
pullToRefreshController?.initMethodChannel(id);
|
||||
if (onWebViewCreated != null) {
|
||||
onWebViewCreated!(webViewController);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return webViewController.handleMethod(call);
|
||||
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
///Runs the headless WebView.
|
||||
@ -134,9 +150,10 @@ class HeadlessInAppWebView implements WebView {
|
||||
this.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
||||
'pullToRefreshOptions':
|
||||
this.pullToRefreshController?.options.toMap() ??
|
||||
PullToRefreshOptions(enabled: false).toMap()
|
||||
PullToRefreshOptions(enabled: false).toMap(),
|
||||
'initialSize': this.initialSize.toMap()
|
||||
});
|
||||
await _sharedChannel.invokeMethod('createHeadlessWebView', args);
|
||||
await _sharedChannel.invokeMethod('run', args);
|
||||
_running = true;
|
||||
}
|
||||
|
||||
@ -146,8 +163,7 @@ class HeadlessInAppWebView implements WebView {
|
||||
return;
|
||||
}
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('id', () => id);
|
||||
await _sharedChannel.invokeMethod('disposeHeadlessWebView', args);
|
||||
await _channel.invokeMethod('dispose', args);
|
||||
_started = false;
|
||||
_running = false;
|
||||
}
|
||||
@ -157,26 +173,24 @@ class HeadlessInAppWebView implements WebView {
|
||||
return _running;
|
||||
}
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)?
|
||||
androidOnGeolocationPermissionsHidePrompt;
|
||||
///Set the size of the WebView in pixels.
|
||||
///
|
||||
///Set `-1` to match the corresponding width or height of the current device screen size.
|
||||
///`Size(-1, -1)` will match both width and height of the current device screen size.
|
||||
///
|
||||
///**NOTE for Android**: `Size` width and height values will be converted to `int` values because they cannot have `double` values.
|
||||
Future<void> setSize(Size size) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('size', () => size.toMap());
|
||||
await _channel.invokeMethod('setSize', args);
|
||||
}
|
||||
|
||||
@override
|
||||
final Future<GeolocationPermissionShowPromptResponse?> Function(
|
||||
InAppWebViewController controller, String origin)?
|
||||
androidOnGeolocationPermissionsShowPrompt;
|
||||
|
||||
@override
|
||||
final Future<PermissionRequestResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
String origin,
|
||||
List<String> resources)? androidOnPermissionRequest;
|
||||
|
||||
@override
|
||||
final Future<SafeBrowsingResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
Uri url,
|
||||
SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
|
||||
///Gets the current size in pixels of the WebView.
|
||||
Future<Size?> getSize() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
Map<String, dynamic> sizeMap = (await _channel.invokeMethod('getSize', args))?.cast<String, dynamic>();
|
||||
return MapSize.fromMap(sizeMap);
|
||||
}
|
||||
|
||||
@override
|
||||
final InAppWebViewInitialData? initialData;
|
||||
@ -200,211 +214,239 @@ class HeadlessInAppWebView implements WebView {
|
||||
final PullToRefreshController? pullToRefreshController;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url)?
|
||||
void Function(InAppWebViewController controller)?
|
||||
androidOnGeolocationPermissionsHidePrompt;
|
||||
|
||||
@override
|
||||
Future<GeolocationPermissionShowPromptResponse?> Function(
|
||||
InAppWebViewController controller, String origin)?
|
||||
androidOnGeolocationPermissionsShowPrompt;
|
||||
|
||||
@override
|
||||
Future<PermissionRequestResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
String origin,
|
||||
List<String> resources)? androidOnPermissionRequest;
|
||||
|
||||
@override
|
||||
Future<SafeBrowsingResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
Uri url,
|
||||
SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
|
||||
|
||||
@override
|
||||
void Function(InAppWebViewController controller, Uri? url)?
|
||||
onPageCommitVisible;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, String? title)?
|
||||
void Function(InAppWebViewController controller, String? title)?
|
||||
onTitleChanged;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)?
|
||||
void Function(InAppWebViewController controller)?
|
||||
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)?
|
||||
void Function(InAppWebViewController controller)?
|
||||
iosOnWebContentProcessDidTerminate;
|
||||
|
||||
@override
|
||||
final Future<IOSNavigationResponseAction?> Function(
|
||||
Future<IOSNavigationResponseAction?> Function(
|
||||
InAppWebViewController controller,
|
||||
IOSWKNavigationResponse navigationResponse)? iosOnNavigationResponse;
|
||||
|
||||
@override
|
||||
final Future<IOSShouldAllowDeprecatedTLSAction?> Function(
|
||||
Future<IOSShouldAllowDeprecatedTLSAction?> Function(
|
||||
InAppWebViewController controller,
|
||||
URLAuthenticationChallenge challenge)? iosShouldAllowDeprecatedTLS;
|
||||
|
||||
@override
|
||||
final Future<AjaxRequestAction> Function(
|
||||
Future<AjaxRequestAction> Function(
|
||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||
onAjaxProgress;
|
||||
|
||||
@override
|
||||
final Future<AjaxRequestAction?> Function(
|
||||
Future<AjaxRequestAction?> Function(
|
||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||
onAjaxReadyStateChange;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
||||
onConsoleMessage;
|
||||
|
||||
@override
|
||||
final Future<bool?> Function(InAppWebViewController controller,
|
||||
Future<bool?> Function(InAppWebViewController controller,
|
||||
CreateWindowAction createWindowAction)? onCreateWindow;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onCloseWindow;
|
||||
void Function(InAppWebViewController controller)? onCloseWindow;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onWindowFocus;
|
||||
void Function(InAppWebViewController controller)? onWindowFocus;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onWindowBlur;
|
||||
void Function(InAppWebViewController controller)? onWindowBlur;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri url)?
|
||||
void Function(InAppWebViewController controller, Uri url)?
|
||||
onDownloadStart;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||
void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
||||
|
||||
@override
|
||||
final Future<JsAlertResponse?> Function(
|
||||
Future<JsAlertResponse?> Function(
|
||||
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
||||
onJsAlert;
|
||||
|
||||
@override
|
||||
final Future<JsConfirmResponse?> Function(
|
||||
Future<JsConfirmResponse?> Function(
|
||||
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
||||
onJsConfirm;
|
||||
|
||||
@override
|
||||
final Future<JsPromptResponse?> Function(
|
||||
Future<JsPromptResponse?> Function(
|
||||
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
||||
onJsPrompt;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url, int code,
|
||||
void Function(InAppWebViewController controller, Uri? url, int code,
|
||||
String message)? onLoadError;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url,
|
||||
void Function(InAppWebViewController controller, Uri? url,
|
||||
int statusCode, String description)? onLoadHttpError;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, LoadedResource resource)?
|
||||
onLoadResource;
|
||||
|
||||
@override
|
||||
final Future<CustomSchemeResponse?> Function(
|
||||
Future<CustomSchemeResponse?> Function(
|
||||
InAppWebViewController controller, Uri url)? onLoadResourceCustomScheme;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url)? onLoadStart;
|
||||
void Function(InAppWebViewController controller, Uri? url)? onLoadStart;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url)? onLoadStop;
|
||||
void Function(InAppWebViewController controller, Uri? url)? onLoadStop;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller,
|
||||
void Function(InAppWebViewController controller,
|
||||
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uri? url)? onPrint;
|
||||
void Function(InAppWebViewController controller, Uri? url)? onPrint;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, int progress)?
|
||||
void Function(InAppWebViewController controller, int progress)?
|
||||
onProgressChanged;
|
||||
|
||||
@override
|
||||
final Future<ClientCertResponse?> Function(InAppWebViewController controller,
|
||||
Future<ClientCertResponse?> Function(InAppWebViewController controller,
|
||||
URLAuthenticationChallenge challenge)? onReceivedClientCertRequest;
|
||||
|
||||
@override
|
||||
final Future<HttpAuthResponse?> Function(InAppWebViewController controller,
|
||||
Future<HttpAuthResponse?> Function(InAppWebViewController controller,
|
||||
URLAuthenticationChallenge challenge)? onReceivedHttpAuthRequest;
|
||||
|
||||
@override
|
||||
final Future<ServerTrustAuthResponse?> Function(
|
||||
Future<ServerTrustAuthResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
URLAuthenticationChallenge challenge)? onReceivedServerTrustAuthRequest;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, int x, int y)?
|
||||
void Function(InAppWebViewController controller, int x, int y)?
|
||||
onScrollChanged;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, Uri? url, bool? androidIsReload)?
|
||||
onUpdateVisitedHistory;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||
void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||
|
||||
@override
|
||||
final Future<AjaxRequest?> Function(
|
||||
Future<AjaxRequest?> Function(
|
||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||
shouldInterceptAjaxRequest;
|
||||
|
||||
@override
|
||||
final Future<FetchRequest?> Function(
|
||||
Future<FetchRequest?> Function(
|
||||
InAppWebViewController controller, FetchRequest fetchRequest)?
|
||||
shouldInterceptFetchRequest;
|
||||
|
||||
@override
|
||||
final Future<NavigationActionPolicy?> Function(
|
||||
Future<NavigationActionPolicy?> Function(
|
||||
InAppWebViewController controller, NavigationAction navigationAction)?
|
||||
shouldOverrideUrlLoading;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||
void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||
void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, int x, int y,
|
||||
void Function(InAppWebViewController controller, int x, int y,
|
||||
bool clampedX, bool clampedY)? onOverScrolled;
|
||||
|
||||
@override
|
||||
final Future<WebResourceResponse?> Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
onZoomScaleChanged;
|
||||
|
||||
@override
|
||||
Future<WebResourceResponse?> Function(
|
||||
InAppWebViewController controller, WebResourceRequest request)?
|
||||
androidShouldInterceptRequest;
|
||||
|
||||
@override
|
||||
final Future<WebViewRenderProcessAction?> Function(
|
||||
Future<WebViewRenderProcessAction?> Function(
|
||||
InAppWebViewController controller, Uri? url)?
|
||||
androidOnRenderProcessUnresponsive;
|
||||
|
||||
@override
|
||||
final Future<WebViewRenderProcessAction?> Function(
|
||||
Future<WebViewRenderProcessAction?> Function(
|
||||
InAppWebViewController controller, Uri? url)?
|
||||
androidOnRenderProcessResponsive;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
||||
androidOnRenderProcessGone;
|
||||
|
||||
@override
|
||||
final Future<FormResubmissionAction?> Function(
|
||||
Future<FormResubmissionAction?> Function(
|
||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||
|
||||
///Use [onZoomScaleChanged] instead.
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
androidOnScaleChanged;
|
||||
|
||||
@override
|
||||
final void Function(InAppWebViewController controller, Uint8List icon)?
|
||||
void Function(InAppWebViewController controller, Uint8List icon)?
|
||||
androidOnReceivedIcon;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, Uri url, bool precomposed)?
|
||||
androidOnReceivedTouchIconUrl;
|
||||
|
||||
@override
|
||||
final Future<JsBeforeUnloadResponse?> Function(
|
||||
Future<JsBeforeUnloadResponse?> Function(
|
||||
InAppWebViewController controller,
|
||||
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
void Function(
|
||||
InAppWebViewController controller, LoginRequest loginRequest)?
|
||||
androidOnReceivedLoginRequest;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||
this.onWindowFocus,
|
||||
this.onWindowBlur,
|
||||
this.onOverScrolled,
|
||||
this.onZoomScaleChanged,
|
||||
this.androidOnSafeBrowsingHit,
|
||||
this.androidOnPermissionRequest,
|
||||
this.androidOnGeolocationPermissionsShowPrompt,
|
||||
@ -86,6 +87,7 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||
this.androidOnRenderProcessResponsive,
|
||||
this.androidOnRenderProcessUnresponsive,
|
||||
this.androidOnFormResubmission,
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
this.androidOnScaleChanged,
|
||||
this.androidOnReceivedIcon,
|
||||
this.androidOnReceivedTouchIconUrl,
|
||||
@ -313,6 +315,11 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||
final void Function(InAppWebViewController controller, int x, int y,
|
||||
bool clampedX, bool clampedY)? onOverScrolled;
|
||||
|
||||
@override
|
||||
final void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
onZoomScaleChanged;
|
||||
|
||||
@override
|
||||
final Future<WebResourceResponse?> Function(
|
||||
InAppWebViewController controller, WebResourceRequest request)?
|
||||
@ -337,6 +344,8 @@ class InAppWebView extends StatefulWidget implements WebView {
|
||||
final Future<FormResubmissionAction?> Function(
|
||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||
|
||||
///Use [onZoomScaleChanged] instead.
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
@override
|
||||
final void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
|
@ -101,12 +101,6 @@ class InAppWebViewController {
|
||||
|
||||
Future<dynamic> handleMethod(MethodCall call) async {
|
||||
switch (call.method) {
|
||||
case "onHeadlessWebViewCreated":
|
||||
if (_webview != null &&
|
||||
_webview is HeadlessInAppWebView &&
|
||||
_webview!.onWebViewCreated != null)
|
||||
_webview!.onWebViewCreated!(this);
|
||||
break;
|
||||
case "onLoadStart":
|
||||
if ((_webview != null && _webview!.onLoadStart != null) ||
|
||||
_inAppBrowser != null) {
|
||||
@ -361,13 +355,17 @@ class InAppWebViewController {
|
||||
?.toMap();
|
||||
}
|
||||
break;
|
||||
case "onScaleChanged":
|
||||
if ((_webview != null && _webview!.androidOnScaleChanged != null) ||
|
||||
case "onZoomScaleChanged":
|
||||
if ((_webview != null && (_webview!.androidOnScaleChanged != null || _webview!.onZoomScaleChanged != null)) ||
|
||||
_inAppBrowser != null) {
|
||||
double oldScale = call.arguments["oldScale"];
|
||||
double newScale = call.arguments["newScale"];
|
||||
if (_webview != null && _webview!.androidOnScaleChanged != null)
|
||||
_webview!.androidOnScaleChanged!(this, oldScale, newScale);
|
||||
if (_webview != null) {
|
||||
if (_webview!.onZoomScaleChanged != null)
|
||||
_webview!.onZoomScaleChanged!(this, oldScale, newScale);
|
||||
else
|
||||
_webview!.androidOnScaleChanged!(this, oldScale, newScale);
|
||||
}
|
||||
else
|
||||
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
|
||||
}
|
||||
@ -1703,16 +1701,18 @@ class InAppWebViewController {
|
||||
return await _channel.invokeMethod('zoomBy', args);
|
||||
}
|
||||
|
||||
///Gets the current scale of this WebView.
|
||||
///
|
||||
///**Official Android API**:
|
||||
///- https://developer.android.com/reference/android/util/DisplayMetrics#density
|
||||
///- https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||
///Gets the current zoom scale of the WebView.
|
||||
///
|
||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollview/1619419-zoomscale
|
||||
Future<double?> getScale() async {
|
||||
Future<double?> getZoomScale() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _channel.invokeMethod('getScale', args);
|
||||
return await _channel.invokeMethod('getZoomScale', args);
|
||||
}
|
||||
|
||||
///Use [getZoomScale] instead.
|
||||
@Deprecated('Use `getZoomScale` instead')
|
||||
Future<double?> getScale() async {
|
||||
return await getZoomScale();
|
||||
}
|
||||
|
||||
///Gets the selected text.
|
||||
|
@ -401,6 +401,21 @@ abstract class WebView {
|
||||
final void Function(InAppWebViewController controller, int x, int y,
|
||||
bool clampedX, bool clampedY)? onOverScrolled;
|
||||
|
||||
///Event fired when the zoom scale of the WebView has changed.
|
||||
///
|
||||
///[oldScale] The old zoom scale factor.
|
||||
///
|
||||
///[newScale] The new zoom scale factor.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||
///
|
||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619409-scrollviewdidzoom
|
||||
final void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
onZoomScaleChanged;
|
||||
|
||||
///Event fired when the webview notifies that a loading URL has been flagged by Safe Browsing.
|
||||
///The default behavior is to show an interstitial to the user, with the reporting checkbox visible.
|
||||
///
|
||||
@ -531,15 +546,8 @@ abstract class WebView {
|
||||
final Future<FormResubmissionAction?> Function(
|
||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||
|
||||
///Event fired when the scale applied to the WebView has changed.
|
||||
///
|
||||
///[oldScale] The old scale factor.
|
||||
///
|
||||
///[newScale] The new scale factor.
|
||||
///
|
||||
///**NOTE**: available only on Android.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)
|
||||
///Use [onZoomScaleChanged] instead.
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
final void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
androidOnScaleChanged;
|
||||
@ -702,6 +710,7 @@ abstract class WebView {
|
||||
this.onWindowFocus,
|
||||
this.onWindowBlur,
|
||||
this.onOverScrolled,
|
||||
this.onZoomScaleChanged,
|
||||
this.androidOnSafeBrowsingHit,
|
||||
this.androidOnPermissionRequest,
|
||||
this.androidOnGeolocationPermissionsShowPrompt,
|
||||
@ -711,6 +720,7 @@ abstract class WebView {
|
||||
this.androidOnRenderProcessResponsive,
|
||||
this.androidOnRenderProcessUnresponsive,
|
||||
this.androidOnFormResubmission,
|
||||
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||
this.androidOnScaleChanged,
|
||||
this.androidOnReceivedIcon,
|
||||
this.androidOnReceivedTouchIconUrl,
|
||||
|
@ -485,3 +485,23 @@ extension HexColor on Color {
|
||||
'${green.toRadixString(16).padLeft(2, '0')}'
|
||||
'${blue.toRadixString(16).padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
extension MapSize on Size {
|
||||
static Size? fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
return Size(map["width"] ?? -1.0, map["height"] ?? -1.0);
|
||||
}
|
||||
|
||||
Map<String, double> toJson() {
|
||||
return toMap();
|
||||
}
|
||||
|
||||
Map<String, double> toMap() {
|
||||
return {
|
||||
'width': width,
|
||||
'height': height
|
||||
};
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
name: flutter_inappwebview
|
||||
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
|
||||
version: 5.2.1+1
|
||||
version: 5.3.0
|
||||
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||
|
||||
environment:
|
||||
|
Loading…
x
Reference in New Issue
Block a user