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">
|
<component name="libraryTable">
|
||||||
<library name="Flutter Plugins">
|
<library name="Flutter Plugins">
|
||||||
<CLASSES />
|
<CLASSES>
|
||||||
|
<root url="file://$PROJECT_DIR$" />
|
||||||
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</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
|
## 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
|
- 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.credential_database.CredentialDatabaseHandler;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserManager;
|
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.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.ActivityAware;
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||||
|
@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview;
|
|||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
|
||||||
import android.webkit.ValueCallback;
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
@ -332,8 +331,8 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
|||||||
case "getOriginalUrl":
|
case "getOriginalUrl":
|
||||||
result.success((webView != null) ? webView.getOriginalUrl() : null);
|
result.success((webView != null) ? webView.getOriginalUrl() : null);
|
||||||
break;
|
break;
|
||||||
case "getScale":
|
case "getZoomScale":
|
||||||
result.success((webView != null) ? webView.getUpdatedScale() : null);
|
result.success((webView != null) ? webView.zoomScale : null);
|
||||||
break;
|
break;
|
||||||
case "getSelectedText":
|
case "getSelectedText":
|
||||||
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.pichillilorenzo.flutter_inappwebview;
|
package com.pichillilorenzo.flutter_inappwebview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.net.http.SslCertificate;
|
import android.net.http.SslCertificate;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -287,4 +288,8 @@ public class Util {
|
|||||||
} while (i < newline);
|
} 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;
|
package com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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;
|
||||||
import io.flutter.plugin.common.MethodChannel.Result;
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
|
|
||||||
/**
|
|
||||||
* InAppBrowserManager
|
|
||||||
*/
|
|
||||||
public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHandler {
|
public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
public MethodChannel channel;
|
|
||||||
protected static final String LOG_TAG = "HeadlessInAppWebViewManager";
|
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) {
|
public HeadlessInAppWebViewManager(BinaryMessenger messenger) {
|
||||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview");
|
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview");
|
||||||
@ -49,40 +45,34 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMethodCall(final MethodCall call, final Result result) {
|
public void onMethodCall(final MethodCall call, final Result result) {
|
||||||
final Activity activity = Shared.activity;
|
|
||||||
final String id = (String) call.argument("id");
|
final String id = (String) call.argument("id");
|
||||||
|
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "createHeadlessWebView":
|
case "run":
|
||||||
{
|
{
|
||||||
HashMap<String, Object> params = (HashMap<String, Object>) call.argument("params");
|
HashMap<String, Object> params = (HashMap<String, Object>) call.argument("params");
|
||||||
createHeadlessWebView(activity, id, params);
|
HeadlessInAppWebViewManager.run(id, params);
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
case "disposeHeadlessWebView":
|
|
||||||
disposeHeadlessWebView(id);
|
|
||||||
result.success(true);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createHeadlessWebView(Activity activity, String id, HashMap<String, Object> params) {
|
public static void run(String id, HashMap<String, Object> params) {
|
||||||
FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, activity, id, params, null);
|
FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, Shared.activity, id, params, null);
|
||||||
flutterWebViews.put(id, flutterWebView);
|
HeadlessInAppWebView headlessInAppWebView = new HeadlessInAppWebView(Shared.messenger, id, flutterWebView);
|
||||||
}
|
HeadlessInAppWebViewManager.webViews.put(id, headlessInAppWebView);
|
||||||
|
|
||||||
public void disposeHeadlessWebView(String id) {
|
headlessInAppWebView.prepare(params);
|
||||||
if (flutterWebViews.containsKey(id)) {
|
headlessInAppWebView.onWebViewCreated();
|
||||||
flutterWebViews.get(id).dispose();
|
flutterWebView.makeInitialLoad(params);
|
||||||
flutterWebViews.remove(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
HeadlessInAppWebViewManager.webViews.clear();
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,16 +44,14 @@ public class FlutterWebView implements PlatformView {
|
|||||||
public InAppWebViewMethodHandler methodCallDelegate;
|
public InAppWebViewMethodHandler methodCallDelegate;
|
||||||
public PullToRefreshLayout pullToRefreshLayout;
|
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);
|
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
|
||||||
|
|
||||||
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
|
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
|
||||||
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
||||||
displayListenerProxy.onPreWebViewInitialization(displayManager);
|
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> initialOptions = (Map<String, Object>) params.get("initialOptions");
|
||||||
Map<String, Object> contextMenu = (Map<String, Object>) params.get("contextMenu");
|
Map<String, Object> contextMenu = (Map<String, Object>) params.get("contextMenu");
|
||||||
Integer windowId = (Integer) params.get("windowId");
|
Integer windowId = (Integer) params.get("windowId");
|
||||||
@ -95,6 +93,18 @@ public class FlutterWebView implements PlatformView {
|
|||||||
channel.setMethodCallHandler(methodCallDelegate);
|
channel.setMethodCallHandler(methodCallDelegate);
|
||||||
|
|
||||||
webView.prepare();
|
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) {
|
if (windowId != null) {
|
||||||
Message resultMsg = InAppWebViewChromeClient.windowWebViewMessages.get(windowId);
|
Message resultMsg = InAppWebViewChromeClient.windowWebViewMessages.get(windowId);
|
||||||
@ -109,7 +119,6 @@ public class FlutterWebView implements PlatformView {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Log.e(LOG_TAG, initialFile + " asset file cannot be found!", e);
|
Log.e(LOG_TAG, initialFile + " asset file cannot be found!", e);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (initialData != null) {
|
else if (initialData != null) {
|
||||||
@ -125,16 +134,6 @@ public class FlutterWebView implements PlatformView {
|
|||||||
webView.loadUrl(urlRequest);
|
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
|
@Override
|
||||||
|
@ -23,7 +23,9 @@ public class FlutterWebViewFactory extends PlatformViewFactory {
|
|||||||
@Override
|
@Override
|
||||||
public PlatformView create(Context context, int id, Object args) {
|
public PlatformView create(Context context, int id, Object args) {
|
||||||
HashMap<String, Object> params = (HashMap<String, 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 InAppWebViewOptions options;
|
||||||
public boolean isLoading = false;
|
public boolean isLoading = false;
|
||||||
public OkHttpClient httpClient;
|
public OkHttpClient httpClient;
|
||||||
public float scale = getResources().getDisplayMetrics().density;
|
public float zoomScale = 1.0f;
|
||||||
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
||||||
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
||||||
public Pattern regexToCancelSubFramesLoadingCompiled;
|
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) {
|
public void takeScreenshot(final @Nullable Map<String, Object> screenshotConfiguration, final MethodChannel.Result result) {
|
||||||
|
final float pixelDensity = Util.getPixelDensity(getContext());
|
||||||
|
|
||||||
headlessHandler.post(new Runnable() {
|
headlessHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -595,10 +597,10 @@ final public class InAppWebView extends InputAwareWebView {
|
|||||||
if (screenshotConfiguration != null) {
|
if (screenshotConfiguration != null) {
|
||||||
Map<String, Double> rect = (Map<String, Double>) screenshotConfiguration.get("rect");
|
Map<String, Double> rect = (Map<String, Double>) screenshotConfiguration.get("rect");
|
||||||
if (rect != null) {
|
if (rect != null) {
|
||||||
int rectX = (int) Math.floor(rect.get("x") * scale + 0.5);
|
int rectX = (int) Math.floor(rect.get("x") * pixelDensity + 0.5);
|
||||||
int rectY = (int) Math.floor(rect.get("y") * scale + 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") * scale + 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") * scale + 0.5));
|
int rectHeight = Math.min(resized.getHeight(), (int) Math.floor(rect.get("height") * pixelDensity + 0.5));
|
||||||
resized = Bitmap.createBitmap(
|
resized = Bitmap.createBitmap(
|
||||||
resized,
|
resized,
|
||||||
rectX,
|
rectX,
|
||||||
@ -609,7 +611,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||||||
|
|
||||||
Double snapshotWidth = (Double) screenshotConfiguration.get("snapshotWidth");
|
Double snapshotWidth = (Double) screenshotConfiguration.get("snapshotWidth");
|
||||||
if (snapshotWidth != null) {
|
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();
|
float ratioBitmap = (float) resized.getWidth() / (float) resized.getHeight();
|
||||||
int dstHeight = (int) ((float) dstWidth / ratioBitmap);
|
int dstHeight = (int) ((float) dstWidth / ratioBitmap);
|
||||||
resized = Bitmap.createScaledBitmap(resized, dstWidth, dstHeight, true);
|
resized = Bitmap.createScaledBitmap(resized, dstWidth, dstHeight, true);
|
||||||
@ -1222,10 +1224,6 @@ final public class InAppWebView extends InputAwareWebView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Float getUpdatedScale() {
|
|
||||||
return scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu) {
|
public void onCreateContextMenu(ContextMenu menu) {
|
||||||
super.onCreateContextMenu(menu);
|
super.onCreateContextMenu(menu);
|
||||||
@ -1509,7 +1507,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||||||
if (floatingContextMenu != null) {
|
if (floatingContextMenu != null) {
|
||||||
if (value != null && !value.equalsIgnoreCase("null")) {
|
if (value != null && !value.equalsIgnoreCase("null")) {
|
||||||
int x = contextMenuPoint.x;
|
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;
|
contextMenuPoint.y = y;
|
||||||
onFloatingActionGlobalLayout(x, y);
|
onFloatingActionGlobalLayout(x, y);
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,6 +23,7 @@ import android.webkit.WebViewClient;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabase;
|
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabase;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
|
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) {
|
public void onScaleChanged(WebView view, float oldScale, float newScale) {
|
||||||
super.onScaleChanged(view, oldScale, newScale);
|
super.onScaleChanged(view, oldScale, newScale);
|
||||||
final InAppWebView webView = (InAppWebView) view;
|
final InAppWebView webView = (InAppWebView) view;
|
||||||
webView.scale = newScale;
|
webView.zoomScale = newScale / Util.getPixelDensity(webView.getContext());
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
obj.put("oldScale", oldScale);
|
obj.put("oldScale", oldScale);
|
||||||
obj.put("newScale", newScale);
|
obj.put("newScale", newScale);
|
||||||
channel.invokeMethod("onScaleChanged", obj);
|
channel.invokeMethod("onZoomScaleChanged", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O_MR1)
|
@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);
|
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 {
|
testWidgets('androidOnPermissionRequest', (WidgetTester tester) async {
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
final Completer<void> pageLoaded = Completer<void>();
|
final Completer<void> pageLoaded = Completer<void>();
|
||||||
@ -3341,50 +3380,6 @@ setTimeout(function() {
|
|||||||
expect(resourceLoaded, containsAll(resourceList));
|
expect(resourceLoaded, containsAll(resourceList));
|
||||||
}, skip: !Platform.isAndroid);
|
}, 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 {
|
testWidgets('androidOnReceivedIcon', (WidgetTester tester) async {
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
final Completer<void> pageLoaded = Completer<void>();
|
final Completer<void> pageLoaded = Completer<void>();
|
||||||
@ -4540,7 +4535,7 @@ setTimeout(function() {
|
|||||||
controller.zoomBy(zoomFactor: 3.0, iosAnimated: true), completes);
|
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 controllerCompleter = Completer<InAppWebViewController>();
|
||||||
final Completer<void> pageLoaded = Completer<void>();
|
final Completer<void> pageLoaded = Completer<void>();
|
||||||
|
|
||||||
@ -4565,7 +4560,7 @@ setTimeout(function() {
|
|||||||
await controllerCompleter.future;
|
await controllerCompleter.future;
|
||||||
await pageLoaded.future;
|
await pageLoaded.future;
|
||||||
|
|
||||||
final scale = await controller.getScale();
|
final scale = await controller.getZoomScale();
|
||||||
expect(scale, isNonZero);
|
expect(scale, isNonZero);
|
||||||
expect(scale, isPositive);
|
expect(scale, isPositive);
|
||||||
});
|
});
|
||||||
|
@ -80,6 +80,5 @@
|
|||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||||
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
||||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</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 {
|
public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
||||||
static var registrar: FlutterPluginRegistrar?
|
static var registrar: FlutterPluginRegistrar?
|
||||||
static var channel: FlutterMethodChannel?
|
static var channel: FlutterMethodChannel?
|
||||||
var flutterWebViews: [String: FlutterWebViewController] = [:]
|
static var webViews: [String: HeadlessInAppWebView] = [:]
|
||||||
|
|
||||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
|
||||||
@ -34,13 +34,9 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
|||||||
let id: String = arguments!["id"] as! String
|
let id: String = arguments!["id"] as! String
|
||||||
|
|
||||||
switch call.method {
|
switch call.method {
|
||||||
case "createHeadlessWebView":
|
case "run":
|
||||||
let params = arguments!["params"] as! [String: Any?]
|
let params = arguments!["params"] as! [String: Any?]
|
||||||
createHeadlessWebView(id: id, params: params)
|
HeadlessInAppWebViewManager.run(id: id, params: params)
|
||||||
result(true)
|
|
||||||
break
|
|
||||||
case "disposeHeadlessWebView":
|
|
||||||
disposeHeadlessWebView(id: id)
|
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
@ -49,17 +45,16 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createHeadlessWebView(id: String, params: [String: Any?]) {
|
public static func run(id: String, params: [String: Any?]) {
|
||||||
let controller = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
|
let flutterWebView = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
|
||||||
withFrame: CGRect.zero,
|
withFrame: CGRect.zero,
|
||||||
viewIdentifier: id,
|
viewIdentifier: id,
|
||||||
arguments: params as NSDictionary)
|
params: params as NSDictionary)
|
||||||
flutterWebViews[id] = controller
|
let headlessInAppWebView = HeadlessInAppWebView(id: id, flutterWebView: flutterWebView)
|
||||||
}
|
HeadlessInAppWebViewManager.webViews[id] = headlessInAppWebView
|
||||||
|
|
||||||
public func disposeHeadlessWebView(id: String) {
|
headlessInAppWebView.prepare(params: params as NSDictionary)
|
||||||
if let _ = flutterWebViews[id] {
|
headlessInAppWebView.onWebViewCreated()
|
||||||
flutterWebViews.removeValue(forKey: id)
|
flutterWebView.makeInitialLoad(params: params as NSDictionary)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||||||
var myView: UIView?
|
var myView: UIView?
|
||||||
var methodCallDelegate: InAppWebViewMethodHandler?
|
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()
|
super.init()
|
||||||
|
|
||||||
self.registrar = registrar
|
self.registrar = registrar
|
||||||
@ -29,14 +29,11 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||||||
myView = UIView(frame: frame)
|
myView = UIView(frame: frame)
|
||||||
myView!.clipsToBounds = true
|
myView!.clipsToBounds = true
|
||||||
|
|
||||||
let initialUrlRequest = args["initialUrlRequest"] as? [String: Any?]
|
let initialOptions = params["initialOptions"] as! [String: Any?]
|
||||||
let initialFile = args["initialFile"] as? String
|
let contextMenu = params["contextMenu"] as? [String: Any]
|
||||||
let initialData = args["initialData"] as? [String: String]
|
let windowId = params["windowId"] as? Int64
|
||||||
let initialOptions = args["initialOptions"] as! [String: Any?]
|
let initialUserScripts = params["initialUserScripts"] as? [[String: Any]]
|
||||||
let contextMenu = args["contextMenu"] as? [String: Any]
|
let pullToRefreshInitialOptions = params["pullToRefreshOptions"] as! [String: Any?]
|
||||||
let windowId = args["windowId"] as? Int64
|
|
||||||
let initialUserScripts = args["initialUserScripts"] as? [[String: Any]]
|
|
||||||
let pullToRefreshInitialOptions = args["pullToRefreshOptions"] as! [String: Any?]
|
|
||||||
|
|
||||||
var userScripts: [UserScript] = []
|
var userScripts: [UserScript] = []
|
||||||
if let initialUserScripts = initialUserScripts {
|
if let initialUserScripts = initialUserScripts {
|
||||||
@ -83,6 +80,17 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||||||
webView!.options = options
|
webView!.options = options
|
||||||
webView!.prepare()
|
webView!.prepare()
|
||||||
webView!.windowCreated = true
|
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 windowId == nil {
|
||||||
if #available(iOS 11.0, *) {
|
if #available(iOS 11.0, *) {
|
||||||
@ -116,37 +124,9 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||||||
else if let wId = windowId, let webViewTransport = InAppWebView.windowWebViews[wId] {
|
else if let wId = windowId, let webViewTransport = InAppWebView.windowWebViews[wId] {
|
||||||
webView!.load(webViewTransport.request)
|
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 {
|
func load(initialUrlRequest: [String:Any?]?, initialFile: String?, initialData: [String: String]?) {
|
||||||
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]?) {
|
|
||||||
if let initialFile = initialFile {
|
if let initialFile = initialFile {
|
||||||
do {
|
do {
|
||||||
try webView?.loadFile(assetFilePath: initialFile)
|
try webView?.loadFile(assetFilePath: initialFile)
|
||||||
@ -174,4 +154,18 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||||||
webView?.loadUrl(urlRequest: urlRequest, allowingReadAccessTo: allowingReadAccessToURL)
|
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!,
|
let webviewController = FlutterWebViewController(registrar: registrar!,
|
||||||
withFrame: frame,
|
withFrame: frame,
|
||||||
viewIdentifier: viewId,
|
viewIdentifier: viewId,
|
||||||
arguments: arguments!)
|
params: arguments!)
|
||||||
|
webviewController.makeInitialLoad(params: arguments!)
|
||||||
return webviewController
|
return webviewController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||||||
|
|
||||||
var callAsyncJavaScriptBelowIOS14Results: [String:((Any?) -> Void)] = [:]
|
var callAsyncJavaScriptBelowIOS14Results: [String:((Any?) -> Void)] = [:]
|
||||||
|
|
||||||
|
var oldZoomScale = Float(1.0)
|
||||||
|
|
||||||
init(frame: CGRect, configuration: WKWebViewConfiguration, contextMenu: [String: Any]?, channel: FlutterMethodChannel?, userScripts: [UserScript] = []) {
|
init(frame: CGRect, configuration: WKWebViewConfiguration, contextMenu: [String: Any]?, channel: FlutterMethodChannel?, userScripts: [UserScript] = []) {
|
||||||
super.init(frame: frame, configuration: configuration)
|
super.init(frame: frame, configuration: configuration)
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
@ -270,6 +272,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||||||
scrollView.addGestureRecognizer(self.longPressRecognizer)
|
scrollView.addGestureRecognizer(self.longPressRecognizer)
|
||||||
scrollView.addGestureRecognizer(self.recognizerForDisablingContextMenuOnLinks)
|
scrollView.addGestureRecognizer(self.recognizerForDisablingContextMenuOnLinks)
|
||||||
scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset), options: [.new, .old], context: nil)
|
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,
|
addObserver(self,
|
||||||
forKeyPath: #keyPath(WKWebView.estimatedProgress),
|
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,
|
public func webView(_ webView: WKWebView,
|
||||||
createWebViewWith configuration: WKWebViewConfiguration,
|
createWebViewWith configuration: WKWebViewConfiguration,
|
||||||
for navigationAction: WKNavigationAction,
|
for navigationAction: WKNavigationAction,
|
||||||
@ -2306,6 +2317,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||||||
channel?.invokeMethod("onScrollChanged", arguments: arguments)
|
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) {
|
public func onOverScrolled(x: Int, y: Int, clampedX: Bool, clampedY: Bool) {
|
||||||
let arguments: [String: Any] = ["x": x, "y": y, "clampedX": clampedX, "clampedY": clampedY]
|
let arguments: [String: Any] = ["x": x, "y": y, "clampedX": clampedX, "clampedY": clampedY]
|
||||||
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
||||||
@ -2678,7 +2694,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||||||
scrollView.setZoomScale(currentZoomScale * CGFloat(zoomFactor), animated: animated)
|
scrollView.setZoomScale(currentZoomScale * CGFloat(zoomFactor), animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getScale() -> Float {
|
public func getZoomScale() -> Float {
|
||||||
return Float(scrollView.zoomScale)
|
return Float(scrollView.zoomScale)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2869,6 +2885,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||||||
imp_removeBlock(imp)
|
imp_removeBlock(imp)
|
||||||
}
|
}
|
||||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
||||||
|
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
||||||
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
||||||
longPressRecognizer.delegate = nil
|
longPressRecognizer.delegate = nil
|
||||||
scrollView.removeGestureRecognizer(longPressRecognizer)
|
scrollView.removeGestureRecognizer(longPressRecognizer)
|
||||||
|
@ -293,8 +293,8 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
|||||||
webView?.reloadFromOrigin()
|
webView?.reloadFromOrigin()
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "getScale":
|
case "getZoomScale":
|
||||||
result(webView?.getScale())
|
result(webView?.getZoomScale())
|
||||||
break
|
break
|
||||||
case "hasOnlySecureContent":
|
case "hasOnlySecureContent":
|
||||||
result(webView?.hasOnlySecureContent ?? false)
|
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');
|
const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
||||||
|
|
||||||
/// WebView Controller that can be used to access the [InAppWebViewController] API.
|
/// 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].
|
///The window id of a [CreateWindowAction.windowId].
|
||||||
final int? 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)
|
///**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) {}
|
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.
|
///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.
|
///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)
|
///**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) {}
|
Future<FormResubmissionAction?>? androidOnFormResubmission(Uri? url) {}
|
||||||
|
|
||||||
///Event fired when the scale applied to the WebView has changed.
|
///Use [onZoomScaleChanged] instead.
|
||||||
///
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
///[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)
|
|
||||||
void androidOnScaleChanged(double oldScale, double newScale) {}
|
void androidOnScaleChanged(double oldScale, double newScale) {}
|
||||||
|
|
||||||
///Event fired when there is new favicon for the current page.
|
///Event fired when there is new favicon for the current page.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/src/util.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 'in_app_webview_options.dart';
|
||||||
import '../pull_to_refresh/pull_to_refresh_controller.dart';
|
import '../pull_to_refresh/pull_to_refresh_controller.dart';
|
||||||
import '../pull_to_refresh/pull_to_refresh_options.dart';
|
import '../pull_to_refresh/pull_to_refresh_options.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
|
||||||
///Class that represents a WebView in headless mode.
|
///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.
|
///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 _started = false;
|
||||||
bool _running = false;
|
bool _running = false;
|
||||||
|
|
||||||
static const MethodChannel _sharedChannel =
|
static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
||||||
const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
|
late MethodChannel _channel;
|
||||||
|
|
||||||
///WebView Controller that can be used to access the [InAppWebViewController] API.
|
///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].
|
///The window id of a [CreateWindowAction.windowId].
|
||||||
final int? 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(
|
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.onWebViewCreated,
|
||||||
this.onLoadStart,
|
this.onLoadStart,
|
||||||
this.onLoadStop,
|
this.onLoadStop,
|
||||||
@ -78,6 +96,7 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
this.androidOnRenderProcessResponsive,
|
this.androidOnRenderProcessResponsive,
|
||||||
this.androidOnRenderProcessUnresponsive,
|
this.androidOnRenderProcessUnresponsive,
|
||||||
this.androidOnFormResubmission,
|
this.androidOnFormResubmission,
|
||||||
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
this.androidOnScaleChanged,
|
this.androidOnScaleChanged,
|
||||||
this.androidOnReceivedIcon,
|
this.androidOnReceivedIcon,
|
||||||
this.androidOnReceivedTouchIconUrl,
|
this.androidOnReceivedTouchIconUrl,
|
||||||
@ -86,29 +105,26 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
this.iosOnWebContentProcessDidTerminate,
|
this.iosOnWebContentProcessDidTerminate,
|
||||||
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
|
this.iosOnDidReceiveServerRedirectForProvisionalNavigation,
|
||||||
this.iosOnNavigationResponse,
|
this.iosOnNavigationResponse,
|
||||||
this.iosShouldAllowDeprecatedTLS,
|
this.iosShouldAllowDeprecatedTLS}) {
|
||||||
this.initialUrlRequest,
|
|
||||||
this.initialFile,
|
|
||||||
this.initialData,
|
|
||||||
this.initialOptions,
|
|
||||||
this.contextMenu,
|
|
||||||
this.initialUserScripts,
|
|
||||||
this.pullToRefreshController}) {
|
|
||||||
id = IdGenerator.generate();
|
id = IdGenerator.generate();
|
||||||
webViewController = new InAppWebViewController(id, this);
|
webViewController = new InAppWebViewController(id, this);
|
||||||
|
this._channel = MethodChannel(
|
||||||
|
'com.pichillilorenzo/flutter_headless_inappwebview_$id');
|
||||||
|
this._channel.setMethodCallHandler(handleMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> handleMethod(MethodCall call) async {
|
Future<dynamic> handleMethod(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "onHeadlessWebViewCreated":
|
case "onWebViewCreated":
|
||||||
pullToRefreshController?.initMethodChannel(id);
|
pullToRefreshController?.initMethodChannel(id);
|
||||||
if (onWebViewCreated != null) {
|
if (onWebViewCreated != null) {
|
||||||
onWebViewCreated!(webViewController);
|
onWebViewCreated!(webViewController);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return webViewController.handleMethod(call);
|
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Runs the headless WebView.
|
///Runs the headless WebView.
|
||||||
@ -134,9 +150,10 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
this.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
this.initialUserScripts?.map((e) => e.toMap()).toList() ?? [],
|
||||||
'pullToRefreshOptions':
|
'pullToRefreshOptions':
|
||||||
this.pullToRefreshController?.options.toMap() ??
|
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;
|
_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +163,7 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('id', () => id);
|
await _channel.invokeMethod('dispose', args);
|
||||||
await _sharedChannel.invokeMethod('disposeHeadlessWebView', args);
|
|
||||||
_started = false;
|
_started = false;
|
||||||
_running = false;
|
_running = false;
|
||||||
}
|
}
|
||||||
@ -157,26 +173,24 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
return _running;
|
return _running;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
///Set the size of the WebView in pixels.
|
||||||
final void Function(InAppWebViewController controller)?
|
///
|
||||||
androidOnGeolocationPermissionsHidePrompt;
|
///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
|
///Gets the current size in pixels of the WebView.
|
||||||
final Future<GeolocationPermissionShowPromptResponse?> Function(
|
Future<Size?> getSize() async {
|
||||||
InAppWebViewController controller, String origin)?
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
androidOnGeolocationPermissionsShowPrompt;
|
Map<String, dynamic> sizeMap = (await _channel.invokeMethod('getSize', args))?.cast<String, dynamic>();
|
||||||
|
return MapSize.fromMap(sizeMap);
|
||||||
@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;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final InAppWebViewInitialData? initialData;
|
final InAppWebViewInitialData? initialData;
|
||||||
@ -200,211 +214,239 @@ class HeadlessInAppWebView implements WebView {
|
|||||||
final PullToRefreshController? pullToRefreshController;
|
final PullToRefreshController? pullToRefreshController;
|
||||||
|
|
||||||
@override
|
@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;
|
onPageCommitVisible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, String? title)?
|
void Function(InAppWebViewController controller, String? title)?
|
||||||
onTitleChanged;
|
onTitleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)?
|
void Function(InAppWebViewController controller)?
|
||||||
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
iosOnDidReceiveServerRedirectForProvisionalNavigation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)?
|
void Function(InAppWebViewController controller)?
|
||||||
iosOnWebContentProcessDidTerminate;
|
iosOnWebContentProcessDidTerminate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<IOSNavigationResponseAction?> Function(
|
Future<IOSNavigationResponseAction?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
IOSWKNavigationResponse navigationResponse)? iosOnNavigationResponse;
|
IOSWKNavigationResponse navigationResponse)? iosOnNavigationResponse;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<IOSShouldAllowDeprecatedTLSAction?> Function(
|
Future<IOSShouldAllowDeprecatedTLSAction?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
URLAuthenticationChallenge challenge)? iosShouldAllowDeprecatedTLS;
|
URLAuthenticationChallenge challenge)? iosShouldAllowDeprecatedTLS;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction> Function(
|
Future<AjaxRequestAction> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxProgress;
|
onAjaxProgress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequestAction?> Function(
|
Future<AjaxRequestAction?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
onAjaxReadyStateChange;
|
onAjaxReadyStateChange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
InAppWebViewController controller, ConsoleMessage consoleMessage)?
|
||||||
onConsoleMessage;
|
onConsoleMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<bool?> Function(InAppWebViewController controller,
|
Future<bool?> Function(InAppWebViewController controller,
|
||||||
CreateWindowAction createWindowAction)? onCreateWindow;
|
CreateWindowAction createWindowAction)? onCreateWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onCloseWindow;
|
void Function(InAppWebViewController controller)? onCloseWindow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onWindowFocus;
|
void Function(InAppWebViewController controller)? onWindowFocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onWindowBlur;
|
void Function(InAppWebViewController controller)? onWindowBlur;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri url)?
|
void Function(InAppWebViewController controller, Uri url)?
|
||||||
onDownloadStart;
|
onDownloadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
void Function(InAppWebViewController controller, int activeMatchOrdinal,
|
||||||
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
int numberOfMatches, bool isDoneCounting)? onFindResultReceived;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsAlertResponse?> Function(
|
Future<JsAlertResponse?> Function(
|
||||||
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
InAppWebViewController controller, JsAlertRequest jsAlertRequest)?
|
||||||
onJsAlert;
|
onJsAlert;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsConfirmResponse?> Function(
|
Future<JsConfirmResponse?> Function(
|
||||||
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
InAppWebViewController controller, JsConfirmRequest jsConfirmRequest)?
|
||||||
onJsConfirm;
|
onJsConfirm;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsPromptResponse?> Function(
|
Future<JsPromptResponse?> Function(
|
||||||
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
InAppWebViewController controller, JsPromptRequest jsPromptRequest)?
|
||||||
onJsPrompt;
|
onJsPrompt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri? url, int code,
|
void Function(InAppWebViewController controller, Uri? url, int code,
|
||||||
String message)? onLoadError;
|
String message)? onLoadError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri? url,
|
void Function(InAppWebViewController controller, Uri? url,
|
||||||
int statusCode, String description)? onLoadHttpError;
|
int statusCode, String description)? onLoadHttpError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, LoadedResource resource)?
|
InAppWebViewController controller, LoadedResource resource)?
|
||||||
onLoadResource;
|
onLoadResource;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<CustomSchemeResponse?> Function(
|
Future<CustomSchemeResponse?> Function(
|
||||||
InAppWebViewController controller, Uri url)? onLoadResourceCustomScheme;
|
InAppWebViewController controller, Uri url)? onLoadResourceCustomScheme;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri? url)? onLoadStart;
|
void Function(InAppWebViewController controller, Uri? url)? onLoadStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri? url)? onLoadStop;
|
void Function(InAppWebViewController controller, Uri? url)? onLoadStop;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller,
|
void Function(InAppWebViewController controller,
|
||||||
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
InAppWebViewHitTestResult hitTestResult)? onLongPressHitTestResult;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uri? url)? onPrint;
|
void Function(InAppWebViewController controller, Uri? url)? onPrint;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int progress)?
|
void Function(InAppWebViewController controller, int progress)?
|
||||||
onProgressChanged;
|
onProgressChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ClientCertResponse?> Function(InAppWebViewController controller,
|
Future<ClientCertResponse?> Function(InAppWebViewController controller,
|
||||||
URLAuthenticationChallenge challenge)? onReceivedClientCertRequest;
|
URLAuthenticationChallenge challenge)? onReceivedClientCertRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<HttpAuthResponse?> Function(InAppWebViewController controller,
|
Future<HttpAuthResponse?> Function(InAppWebViewController controller,
|
||||||
URLAuthenticationChallenge challenge)? onReceivedHttpAuthRequest;
|
URLAuthenticationChallenge challenge)? onReceivedHttpAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<ServerTrustAuthResponse?> Function(
|
Future<ServerTrustAuthResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
URLAuthenticationChallenge challenge)? onReceivedServerTrustAuthRequest;
|
URLAuthenticationChallenge challenge)? onReceivedServerTrustAuthRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int x, int y)?
|
void Function(InAppWebViewController controller, int x, int y)?
|
||||||
onScrollChanged;
|
onScrollChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, Uri? url, bool? androidIsReload)?
|
InAppWebViewController controller, Uri? url, bool? androidIsReload)?
|
||||||
onUpdateVisitedHistory;
|
onUpdateVisitedHistory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onWebViewCreated;
|
void Function(InAppWebViewController controller)? onWebViewCreated;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<AjaxRequest?> Function(
|
Future<AjaxRequest?> Function(
|
||||||
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
InAppWebViewController controller, AjaxRequest ajaxRequest)?
|
||||||
shouldInterceptAjaxRequest;
|
shouldInterceptAjaxRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FetchRequest?> Function(
|
Future<FetchRequest?> Function(
|
||||||
InAppWebViewController controller, FetchRequest fetchRequest)?
|
InAppWebViewController controller, FetchRequest fetchRequest)?
|
||||||
shouldInterceptFetchRequest;
|
shouldInterceptFetchRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<NavigationActionPolicy?> Function(
|
Future<NavigationActionPolicy?> Function(
|
||||||
InAppWebViewController controller, NavigationAction navigationAction)?
|
InAppWebViewController controller, NavigationAction navigationAction)?
|
||||||
shouldOverrideUrlLoading;
|
shouldOverrideUrlLoading;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, int x, int y,
|
void Function(InAppWebViewController controller, int x, int y,
|
||||||
bool clampedX, bool clampedY)? onOverScrolled;
|
bool clampedX, bool clampedY)? onOverScrolled;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebResourceResponse?> Function(
|
void Function(
|
||||||
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
|
onZoomScaleChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WebResourceResponse?> Function(
|
||||||
InAppWebViewController controller, WebResourceRequest request)?
|
InAppWebViewController controller, WebResourceRequest request)?
|
||||||
androidShouldInterceptRequest;
|
androidShouldInterceptRequest;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction?> Function(
|
Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, Uri? url)?
|
InAppWebViewController controller, Uri? url)?
|
||||||
androidOnRenderProcessUnresponsive;
|
androidOnRenderProcessUnresponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebViewRenderProcessAction?> Function(
|
Future<WebViewRenderProcessAction?> Function(
|
||||||
InAppWebViewController controller, Uri? url)?
|
InAppWebViewController controller, Uri? url)?
|
||||||
androidOnRenderProcessResponsive;
|
androidOnRenderProcessResponsive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
InAppWebViewController controller, RenderProcessGoneDetail detail)?
|
||||||
androidOnRenderProcessGone;
|
androidOnRenderProcessGone;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<FormResubmissionAction?> Function(
|
Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
|
///Use [onZoomScaleChanged] instead.
|
||||||
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)?
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
androidOnScaleChanged;
|
androidOnScaleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(InAppWebViewController controller, Uint8List icon)?
|
void Function(InAppWebViewController controller, Uint8List icon)?
|
||||||
androidOnReceivedIcon;
|
androidOnReceivedIcon;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, Uri url, bool precomposed)?
|
InAppWebViewController controller, Uri url, bool precomposed)?
|
||||||
androidOnReceivedTouchIconUrl;
|
androidOnReceivedTouchIconUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<JsBeforeUnloadResponse?> Function(
|
Future<JsBeforeUnloadResponse?> Function(
|
||||||
InAppWebViewController controller,
|
InAppWebViewController controller,
|
||||||
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final void Function(
|
void Function(
|
||||||
InAppWebViewController controller, LoginRequest loginRequest)?
|
InAppWebViewController controller, LoginRequest loginRequest)?
|
||||||
androidOnReceivedLoginRequest;
|
androidOnReceivedLoginRequest;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||||||
this.onWindowFocus,
|
this.onWindowFocus,
|
||||||
this.onWindowBlur,
|
this.onWindowBlur,
|
||||||
this.onOverScrolled,
|
this.onOverScrolled,
|
||||||
|
this.onZoomScaleChanged,
|
||||||
this.androidOnSafeBrowsingHit,
|
this.androidOnSafeBrowsingHit,
|
||||||
this.androidOnPermissionRequest,
|
this.androidOnPermissionRequest,
|
||||||
this.androidOnGeolocationPermissionsShowPrompt,
|
this.androidOnGeolocationPermissionsShowPrompt,
|
||||||
@ -86,6 +87,7 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||||||
this.androidOnRenderProcessResponsive,
|
this.androidOnRenderProcessResponsive,
|
||||||
this.androidOnRenderProcessUnresponsive,
|
this.androidOnRenderProcessUnresponsive,
|
||||||
this.androidOnFormResubmission,
|
this.androidOnFormResubmission,
|
||||||
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
this.androidOnScaleChanged,
|
this.androidOnScaleChanged,
|
||||||
this.androidOnReceivedIcon,
|
this.androidOnReceivedIcon,
|
||||||
this.androidOnReceivedTouchIconUrl,
|
this.androidOnReceivedTouchIconUrl,
|
||||||
@ -313,6 +315,11 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||||||
final void Function(InAppWebViewController controller, int x, int y,
|
final void Function(InAppWebViewController controller, int x, int y,
|
||||||
bool clampedX, bool clampedY)? onOverScrolled;
|
bool clampedX, bool clampedY)? onOverScrolled;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final void Function(
|
||||||
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
|
onZoomScaleChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Future<WebResourceResponse?> Function(
|
final Future<WebResourceResponse?> Function(
|
||||||
InAppWebViewController controller, WebResourceRequest request)?
|
InAppWebViewController controller, WebResourceRequest request)?
|
||||||
@ -337,6 +344,8 @@ class InAppWebView extends StatefulWidget implements WebView {
|
|||||||
final Future<FormResubmissionAction?> Function(
|
final Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
|
///Use [onZoomScaleChanged] instead.
|
||||||
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
@override
|
@override
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)?
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
|
@ -101,12 +101,6 @@ class InAppWebViewController {
|
|||||||
|
|
||||||
Future<dynamic> handleMethod(MethodCall call) async {
|
Future<dynamic> handleMethod(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "onHeadlessWebViewCreated":
|
|
||||||
if (_webview != null &&
|
|
||||||
_webview is HeadlessInAppWebView &&
|
|
||||||
_webview!.onWebViewCreated != null)
|
|
||||||
_webview!.onWebViewCreated!(this);
|
|
||||||
break;
|
|
||||||
case "onLoadStart":
|
case "onLoadStart":
|
||||||
if ((_webview != null && _webview!.onLoadStart != null) ||
|
if ((_webview != null && _webview!.onLoadStart != null) ||
|
||||||
_inAppBrowser != null) {
|
_inAppBrowser != null) {
|
||||||
@ -361,13 +355,17 @@ class InAppWebViewController {
|
|||||||
?.toMap();
|
?.toMap();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "onScaleChanged":
|
case "onZoomScaleChanged":
|
||||||
if ((_webview != null && _webview!.androidOnScaleChanged != null) ||
|
if ((_webview != null && (_webview!.androidOnScaleChanged != null || _webview!.onZoomScaleChanged != null)) ||
|
||||||
_inAppBrowser != null) {
|
_inAppBrowser != null) {
|
||||||
double oldScale = call.arguments["oldScale"];
|
double oldScale = call.arguments["oldScale"];
|
||||||
double newScale = call.arguments["newScale"];
|
double newScale = call.arguments["newScale"];
|
||||||
if (_webview != null && _webview!.androidOnScaleChanged != null)
|
if (_webview != null) {
|
||||||
_webview!.androidOnScaleChanged!(this, oldScale, newScale);
|
if (_webview!.onZoomScaleChanged != null)
|
||||||
|
_webview!.onZoomScaleChanged!(this, oldScale, newScale);
|
||||||
|
else
|
||||||
|
_webview!.androidOnScaleChanged!(this, oldScale, newScale);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
|
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
|
||||||
}
|
}
|
||||||
@ -1703,16 +1701,18 @@ class InAppWebViewController {
|
|||||||
return await _channel.invokeMethod('zoomBy', args);
|
return await _channel.invokeMethod('zoomBy', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets the current scale of this WebView.
|
///Gets the current zoom scale of the 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)
|
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollview/1619419-zoomscale
|
///**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>{};
|
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.
|
///Gets the selected text.
|
||||||
|
@ -401,6 +401,21 @@ abstract class WebView {
|
|||||||
final void Function(InAppWebViewController controller, int x, int y,
|
final void Function(InAppWebViewController controller, int x, int y,
|
||||||
bool clampedX, bool clampedY)? onOverScrolled;
|
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.
|
///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.
|
///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(
|
final Future<FormResubmissionAction?> Function(
|
||||||
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
InAppWebViewController controller, Uri? url)? androidOnFormResubmission;
|
||||||
|
|
||||||
///Event fired when the scale applied to the WebView has changed.
|
///Use [onZoomScaleChanged] instead.
|
||||||
///
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
///[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)
|
|
||||||
final void Function(
|
final void Function(
|
||||||
InAppWebViewController controller, double oldScale, double newScale)?
|
InAppWebViewController controller, double oldScale, double newScale)?
|
||||||
androidOnScaleChanged;
|
androidOnScaleChanged;
|
||||||
@ -702,6 +710,7 @@ abstract class WebView {
|
|||||||
this.onWindowFocus,
|
this.onWindowFocus,
|
||||||
this.onWindowBlur,
|
this.onWindowBlur,
|
||||||
this.onOverScrolled,
|
this.onOverScrolled,
|
||||||
|
this.onZoomScaleChanged,
|
||||||
this.androidOnSafeBrowsingHit,
|
this.androidOnSafeBrowsingHit,
|
||||||
this.androidOnPermissionRequest,
|
this.androidOnPermissionRequest,
|
||||||
this.androidOnGeolocationPermissionsShowPrompt,
|
this.androidOnGeolocationPermissionsShowPrompt,
|
||||||
@ -711,6 +720,7 @@ abstract class WebView {
|
|||||||
this.androidOnRenderProcessResponsive,
|
this.androidOnRenderProcessResponsive,
|
||||||
this.androidOnRenderProcessUnresponsive,
|
this.androidOnRenderProcessUnresponsive,
|
||||||
this.androidOnFormResubmission,
|
this.androidOnFormResubmission,
|
||||||
|
@Deprecated('Use `onZoomScaleChanged` instead')
|
||||||
this.androidOnScaleChanged,
|
this.androidOnScaleChanged,
|
||||||
this.androidOnReceivedIcon,
|
this.androidOnReceivedIcon,
|
||||||
this.androidOnReceivedTouchIconUrl,
|
this.androidOnReceivedTouchIconUrl,
|
||||||
|
@ -485,3 +485,23 @@ extension HexColor on Color {
|
|||||||
'${green.toRadixString(16).padLeft(2, '0')}'
|
'${green.toRadixString(16).padLeft(2, '0')}'
|
||||||
'${blue.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
|
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.
|
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
|
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user