updated shouldOverrideUrlLoading event for #146, added print method and event #128, fix #123 javascript handler for Android API <= 22, renamed onTargetBlank to onCreateWindow event, deleted useOnTargetBlank option, added supportMultipleWindows android option, added getDefaultUserAgent static method, Updated default value for domStorageEnabled option to true
This commit is contained in:
parent
3fd1f9552b
commit
aa20beafb1
|
@ -15,14 +15,72 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/BUG_REPORT.md" beforeDir="false" afterPath="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/BUG_REPORT.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md" beforeDir="false" afterPath="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/InAppWebViewStatic.swift" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/ios/Classes/InAppWebViewStatic.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebView.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowserActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowserActivity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/CHANGELOG.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebView.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowser.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowserActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppBrowserActivity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebView.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewOptions.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/flutter_export_environment.sh" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/flutter_export_environment.sh" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/in_app_webiew_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/in_app_webiew_example.screen.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/lib/main.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/pubspec.yaml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_assets/in_app_webview_on_target_blank_test.html" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_assets/in_app_webview_on_create_window_test.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/in_app_webview_on_target_blank_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/in_app_webview_on_create_window_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/in_app_webview_should_override_url_loading_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/in_app_webview_should_override_url_loading_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/main_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/test_driver/main_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/flutter_inappwebview.iml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/flutter_inappwebview.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/FlutterWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/FlutterWebViewController.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/InAppWebView.swift" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/InAppWebView.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/InAppWebViewOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/InAppWebViewOptions.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/in_app_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/in_app_browser.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/in_app_webview.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/in_app_webview.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/types.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/types.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/webview_options.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/lib/src/webview_options.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/pubspec.yaml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Flutter/flutter_export_environment.sh" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Flutter/flutter_export_environment.sh" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/lib/in_app_browser_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/in_app_browser_example.screen.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/lib/in_app_webiew_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/in_app_webiew_example.screen.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/pubspec.yaml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/test_assets/in_app_webview_on_target_blank_test.html" beforeDir="false" afterPath="$PROJECT_DIR$/example/test_assets/in_app_webview_on_create_window_test.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/test_driver/in_app_webview_on_target_blank_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/test_driver/in_app_webview_on_create_window_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/test_driver/main_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/test_driver/main_test.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/flutter_inappwebview.iml" beforeDir="false" afterPath="$PROJECT_DIR$/flutter_inappwebview.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/FlutterWebViewController.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppWebViewOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppWebViewOptions.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/src/in_app_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_browser.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/src/in_app_webview.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/in_app_webview.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/src/types.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/types.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/src/webview_options.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/webview_options.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
||||
<ignored path="$PROJECT_DIR$/.idea/" />
|
||||
|
@ -45,20 +103,20 @@
|
|||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="480">
|
||||
<caret line="94" column="30" selection-start-line="94" selection-start-column="20" selection-end-line="94" selection-end-column="36" />
|
||||
<state relative-caret-position="194">
|
||||
<caret line="229" column="55" selection-start-line="229" selection-start-column="26" selection-end-line="229" selection-end-column="55" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
<element signature="e#1907#1927#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="185">
|
||||
<caret line="415" column="31" selection-start-line="415" selection-start-column="15" selection-end-line="415" selection-end-column="31" />
|
||||
<state relative-caret-position="328">
|
||||
<caret line="409" column="28" selection-start-line="409" selection-start-column="2" selection-end-line="409" selection-end-column="28" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -67,32 +125,25 @@
|
|||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="142">
|
||||
<caret line="18" column="14" selection-start-line="18" selection-start-column="14" selection-end-line="18" selection-end-column="14" />
|
||||
<state relative-caret-position="235">
|
||||
<caret line="78" column="45" selection-start-line="78" selection-start-column="15" selection-end-line="78" selection-end-column="45" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/AndroidManifest.xml">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="105">
|
||||
<caret line="7" column="4" selection-start-line="7" selection-start-column="4" selection-end-line="7" selection-end-column="65" />
|
||||
<state relative-caret-position="100">
|
||||
<caret line="2026" column="38" selection-start-line="2026" selection-start-column="38" selection-end-line="2026" selection-end-column="38" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -100,8 +151,8 @@
|
|||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="2490">
|
||||
<caret line="176" column="39" selection-start-line="176" selection-start-column="6" selection-end-line="176" selection-end-column="39" />
|
||||
<state relative-caret-position="209">
|
||||
<caret line="359" column="113" selection-start-line="359" selection-start-column="113" selection-end-line="359" selection-end-column="113" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -109,6 +160,28 @@
|
|||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="294">
|
||||
<caret line="78" selection-start-line="78" selection-end-line="80" selection-end-column="134" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="120">
|
||||
<caret line="8" column="160" selection-start-line="8" selection-start-column="160" selection-end-line="8" selection-end-column="160" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
|
@ -121,36 +194,36 @@
|
|||
</component>
|
||||
<component name="FindInProjectRecents">
|
||||
<findStrings>
|
||||
<find>[InAppBrowser] web</find>
|
||||
<find>WebView</find>
|
||||
<find>[InAppBrowser]</find>
|
||||
<find>Response({</find>
|
||||
<find>flutter_inappbrowser</find>
|
||||
<find>InAppBrowser</find>
|
||||
<find>PlatformRead</find>
|
||||
<find>flutterInAppBrowserPlatformReady</find>
|
||||
<find>llowContentAccess</find>
|
||||
<find>ppCache</find>
|
||||
<find>onReceivedClientCertRequest</find>
|
||||
<find>a SSL</find>
|
||||
<find>iltInZoomControls</find>
|
||||
<find>databaseEnabled</find>
|
||||
<find>Cookie</find>
|
||||
<find>\</find>
|
||||
<find>`shouldOverrideUrlLoading</find>
|
||||
<find>useshouldOverrideUrlLoading</find>
|
||||
<find>initiald</find>
|
||||
<find>long</find>
|
||||
<find>should</find>
|
||||
<find>allowunivers</find>
|
||||
<find>onNavigationStateChange</find>
|
||||
<find>_channel</find>
|
||||
<find>default</find>
|
||||
<find>_staticChannel</find>
|
||||
<find>defa</find>
|
||||
<find>InAppWebViewStatic</find>
|
||||
<find>removeFromSuperview</find>
|
||||
<find>onCall</find>
|
||||
<find>onLoad</find>
|
||||
<find>printCu</find>
|
||||
<find>onLoadRe</find>
|
||||
<find>onPrint</find>
|
||||
<find>ontARGET</find>
|
||||
<find>onCreateWindow</find>
|
||||
<find>javaScriptHandlerForbiddenNames</find>
|
||||
<find>supportMultipleWindows</find>
|
||||
<find>ajaxRequest</find>
|
||||
<find>onTarget</find>
|
||||
<find>AjaxR</find>
|
||||
<find>print</find>
|
||||
<find>shouldOver</find>
|
||||
<find>ShouldOverrideUrlLoadingAction</find>
|
||||
<find>headers</find>
|
||||
<find>domStorageEnabled</find>
|
||||
<find>fromValue</find>
|
||||
<find>shouldOv</find>
|
||||
<find>shouldOverrideUrlLoading</find>
|
||||
<find>BAAAAACK</find>
|
||||
<find>loadData</find>
|
||||
<find>iNitialData</find>
|
||||
<find>data</find>
|
||||
<find>pauseTimers</find>
|
||||
<find>openData</find>
|
||||
<find>historyUrl</find>
|
||||
<find>baseUrl</find>
|
||||
<find>onWebViewCreated</find>
|
||||
<find>Note for an</find>
|
||||
</findStrings>
|
||||
<replaceStrings>
|
||||
<replace>activity.getPreferences(0)</replace>
|
||||
|
@ -173,13 +246,6 @@
|
|||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/example/test_driver/custom_widget_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_ajax_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_content_blocker_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_cookie_manager_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_fetch_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_http_auth_credential_database_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_initial_data_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_initial_file_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_initial_url_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_javascript_handler_test.dart" />
|
||||
|
@ -196,7 +262,6 @@
|
|||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_on_safe_browsing_hit_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_on_scroll_changed_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_on_target_blank_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_ssl_request_test.dart" />
|
||||
<option value="$PROJECT_DIR$/ios/Classes/InAppBrowserFlutterPlugin.m" />
|
||||
<option value="$PROJECT_DIR$/ios/Classes/InAppWebViewFlutterPlugin.h" />
|
||||
|
@ -207,22 +272,30 @@
|
|||
<option value="$PROJECT_DIR$/.git/config" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_on_load_error_test.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/channel_manager.dart" />
|
||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/css/style.css" />
|
||||
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.html" />
|
||||
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/js/main.js" />
|
||||
<option value="$PROJECT_DIR$/nodejs_server_test_auth_basic_and_ssl/index.js" />
|
||||
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
||||
<option value="$PROJECT_DIR$/example/assets/js/main.js" />
|
||||
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||
<option value="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/BUG_REPORT.md" />
|
||||
<option value="$PROJECT_DIR$/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md" />
|
||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||
<option value="$PROJECT_DIR$/example/lib/in_app_browser_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/android/src/main/res/values/styles.xml" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/example/lib/in_app_webiew_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/example/assets/css/style.css" />
|
||||
<option value="$PROJECT_DIR$/example/test_assets/in_app_webview_on_create_window_test.html" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/main_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_on_create_window_test.dart" />
|
||||
<option value="$PROJECT_DIR$/example/assets/js/main.js" />
|
||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
||||
<option value="$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
</list>
|
||||
</option>
|
||||
|
@ -250,55 +323,6 @@
|
|||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="android" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="android" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="app" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="android" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="app" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="main" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="AndroidView">
|
||||
<subPane>
|
||||
<expand>
|
||||
|
@ -328,6 +352,29 @@
|
|||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappwebview" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappwebview" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
|
@ -477,7 +524,7 @@
|
|||
</todo-panel>
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="-1" y="23" width="1920" height="1057" extended-state="6" />
|
||||
<frame x="-1" y="23" width="1920" height="1057" extended-state="0" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.6177474" visible="true" weight="0.20766774" />
|
||||
|
@ -491,7 +538,7 @@
|
|||
<window_info id="Resources Explorer" order="8" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" weight="0.32745314" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49478307" weight="0.59378237" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49478307" visible="true" weight="0.4787565" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.34196892" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
|
@ -499,7 +546,7 @@
|
|||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50532484" side_tool="true" weight="0.35751295" />
|
||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4946752" visible="true" weight="0.35336787" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4946752" weight="0.35336787" />
|
||||
<window_info anchor="bottom" id="Logcat" order="11" weight="0.32953367" />
|
||||
<window_info anchor="bottom" id="Messages" order="12" sideWeight="0.4968051" weight="0.33782384" />
|
||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
||||
|
@ -516,6 +563,7 @@
|
|||
<window_info anchor="right" id="Theme Preview" order="7" />
|
||||
<window_info anchor="right" id="Assistant" order="8" weight="0.3290735" />
|
||||
<window_info anchor="right" id="Palette	" order="9" />
|
||||
<window_info anchor="right" id="Preview" order="10" weight="0.32960597" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="UnknownFeatures">
|
||||
|
@ -529,90 +577,6 @@
|
|||
</ignored-roots>
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_js_dialog_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_load_http_error_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_load_resource_custom_scheme_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="45">
|
||||
<caret line="3" column="57" selection-start-line="3" selection-start-column="57" selection-end-line="3" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_load_resource_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_navigation_state_change_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_progress_changed_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_received_http_auth_request_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_safe_browsing_hit_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="60">
|
||||
<caret line="4" column="57" selection-start-line="4" selection-start-column="57" selection-end-line="4" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_scroll_changed_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_target_blank_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="57" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/in_app_webiew_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="15">
|
||||
<caret line="1" column="57" selection-start-line="1" selection-start-column="57" selection-end-line="1" selection-end-column="57" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppWebViewFlutterPlugin.h">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="285">
|
||||
|
@ -634,16 +598,6 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/cookie_manager.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="180">
|
||||
<caret line="12" column="101" selection-start-line="12" selection-start-column="101" selection-end-line="12" selection-end-column="101" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="195">
|
||||
|
@ -776,81 +730,6 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="73">
|
||||
<caret line="606" column="28" lean-forward="true" selection-start-line="606" selection-start-column="28" selection-end-line="606" selection-end-column="28" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/js/main.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="45">
|
||||
<caret line="3" column="25" selection-start-line="3" selection-start-column="25" selection-end-line="3" selection-end-column="25" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="459">
|
||||
<caret line="39" column="38" selection-start-line="39" selection-start-column="38" selection-end-line="39" selection-end-column="38" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="540">
|
||||
<caret line="36" column="27" lean-forward="true" selection-start-line="36" selection-start-column="27" selection-end-line="36" selection-end-column="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="16" selection-start-line="2" selection-start-column="16" selection-end-line="2" selection-end-column="16" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="195">
|
||||
<caret line="13" lean-forward="true" selection-start-line="13" selection-end-line="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="405">
|
||||
<caret line="98" column="19" selection-start-line="98" selection-start-column="9" selection-end-line="98" selection-end-column="19" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="2490">
|
||||
<caret line="176" column="39" selection-start-line="176" selection-start-column="6" selection-end-line="176" selection-end-column="39" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="480">
|
||||
<caret line="94" column="30" selection-start-line="94" selection-start-column="20" selection-end-line="94" selection-end-column="36" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="120">
|
||||
|
@ -865,26 +744,6 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/AndroidManifest.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="105">
|
||||
<caret line="7" column="4" selection-start-line="7" selection-start-column="4" selection-end-line="7" selection-end-column="65" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="185">
|
||||
<caret line="415" column="31" selection-start-line="415" selection-start-column="15" selection-end-line="415" selection-end-column="31" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/android/app/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="-230" />
|
||||
|
@ -893,12 +752,214 @@
|
|||
<entry file="file://$PROJECT_DIR$/example/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_ajax_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="151">
|
||||
<caret line="32" selection-start-line="32" selection-end-line="55" selection-end-column="7" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/chrome_safari_browser_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state>
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/src/main/res/layout/chrome_custom_tabs_layout.xml">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/src/main/res/layout/activity_web_view.xml">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/src/main/res/values/styles.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="44" selection-start-line="2" selection-start-column="44" selection-end-line="2" selection-end-column="44" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/AndroidManifest.xml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="52">
|
||||
<caret line="36" column="39" lean-forward="true" selection-start-line="36" selection-start-column="39" selection-end-line="36" selection-end-column="39" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="77">
|
||||
<caret line="14" column="24" selection-start-line="14" selection-start-column="24" selection-end-line="14" selection-end-column="24" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/cookie_manager.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="203">
|
||||
<caret line="38" column="10" selection-start-line="38" selection-start-column="10" selection-end-line="38" selection-end-column="10" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/css/style.css">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="215">
|
||||
<caret line="31" selection-start-line="31" selection-end-line="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_assets/in_app_webview_on_create_window_test.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="135">
|
||||
<caret line="9" column="42" selection-start-line="9" selection-start-column="42" selection-end-line="9" selection-end-column="42" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_on_create_window_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="345">
|
||||
<caret line="23" column="24" lean-forward="true" selection-start-line="23" selection-start-column="24" selection-end-line="23" selection-end-column="24" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/main_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="690">
|
||||
<caret line="46" column="56" lean-forward="true" selection-start-line="46" selection-start-column="56" selection-end-line="46" selection-end-column="56" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/in_app_webiew_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="487">
|
||||
<caret line="73" column="39" selection-start-line="73" selection-start-column="39" selection-end-line="73" selection-end-column="39" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/in_app_browser_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="178">
|
||||
<caret line="39" column="71" selection-start-line="39" selection-start-column="42" selection-end-line="39" selection-end-column="71" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="165">
|
||||
<caret line="11" column="10" selection-start-line="11" selection-start-column="10" selection-end-line="11" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="454">
|
||||
<caret line="58" column="49" selection-start-line="58" selection-start-column="49" selection-end-line="58" selection-end-column="49" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/js/main.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="45">
|
||||
<caret line="3" column="25" selection-start-line="3" selection-start-column="25" selection-end-line="3" selection-end-column="25" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="100">
|
||||
<caret line="2026" column="38" selection-start-line="2026" selection-start-column="38" selection-end-line="2026" selection-end-column="38" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="194">
|
||||
<caret line="229" column="55" selection-start-line="229" selection-start-column="26" selection-end-line="229" selection-end-column="55" />
|
||||
<folding>
|
||||
<element signature="e#1907#1927#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="328">
|
||||
<caret line="409" column="28" selection-start-line="409" selection-start-column="2" selection-end-line="409" selection-end-column="28" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="209">
|
||||
<caret line="359" column="113" selection-start-line="359" selection-start-column="113" selection-end-line="359" selection-end-column="113" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/test_driver/in_app_webview_should_override_url_loading_test.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="329">
|
||||
<caret line="49" column="68" lean-forward="true" selection-start-line="49" selection-start-column="68" selection-end-line="49" selection-end-column="68" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="235">
|
||||
<caret line="78" column="45" selection-start-line="78" selection-start-column="15" selection-end-line="78" selection-end-column="45" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="120">
|
||||
<caret line="8" column="160" selection-start-line="8" selection-start-column="160" selection-end-line="8" selection-end-column="160" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="142">
|
||||
<caret line="18" column="14" selection-start-line="18" selection-start-column="14" selection-end-line="18" selection-end-column="14" />
|
||||
<state relative-caret-position="294">
|
||||
<caret line="78" selection-start-line="78" selection-end-line="80" selection-end-column="134" />
|
||||
<folding>
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
<element signature="e#0#39#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
|
|
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -1,3 +1,23 @@
|
|||
## 2.2.0
|
||||
|
||||
- Updated `clearCache` for Android
|
||||
- Added `Promise` javascript [polyfill](https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js) for webviews that doesn't support it for `window.flutter_inappwebview.callHandler`
|
||||
- Added `getDefaultUserAgent` static method to `InAppWebViewController`
|
||||
- Added `printCurrentPage` method to `InAppWebViewController`
|
||||
- Added `onPrint` event
|
||||
- Added `supportMultipleWindows` webview option for Android
|
||||
- Added `regexToCancelSubFramesLoading` webview option for Android to cancel subframe requests on `shouldOverrideUrlLoading` event based on a Regular Expression
|
||||
- Updated default value for `domStorageEnabled` option to `true` for Android
|
||||
- Fix for Android `InAppBrowser` for some controller methods not exposed.
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- Updated `shouldOverrideUrlLoading` event:
|
||||
- the `url` parameter has been moved inside an instance of `ShouldOverrideUrlLoadingRequest` class
|
||||
- it has a return type `ShouldOverrideUrlLoadingAction` to allow or cancel navigation instead of cancel every time the request
|
||||
- Renamed `onTargetBlank` to `onCreateWindow`
|
||||
- Deleted `useOnTargetBlank` webview option
|
||||
|
||||
## 2.1.0+1
|
||||
|
||||
- Fix docs
|
||||
|
|
23
README.md
23
README.md
|
@ -76,6 +76,10 @@ Classes:
|
|||
|
||||
See the online [API Reference](https://pub.dartlang.org/documentation/flutter_inappwebview/latest/) to get the full documentation.
|
||||
|
||||
The API showed in this `README.md` file shows only a part of the documentation that conforms to the master branch only.
|
||||
So, here you could have methods, options, and events that aren't published yet.
|
||||
If you need a specific version, change the **GitHub branch** to your version or use the **online API Reference** (recommended).
|
||||
|
||||
### Load a file inside `assets` folder
|
||||
|
||||
To be able to load your local files (assets, js, css, etc.), you need to add them in the `assets` section of the `pubspec.yaml` file, otherwise they cannot be found!
|
||||
|
@ -286,6 +290,8 @@ Screenshots:
|
|||
* `getTRexRunnerCss`: Gets the css of the Chromium's t-rex runner game. Used in combination with `getTRexRunnerHtml()`.
|
||||
* `scrollTo({@required int x, @required int y})`: Scrolls the WebView to the position.
|
||||
* `scrollBy({@required int x, @required int y})`: Moves the scrolled position of the WebView.
|
||||
* `printCurrentPage`: Prints the current page.
|
||||
* `static getDefaultUserAgent`: Gets the default user agent.
|
||||
|
||||
##### About the JavaScript handler
|
||||
|
||||
|
@ -339,7 +345,6 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
|||
* `useShouldOverrideUrlLoading`: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`.
|
||||
* `useOnLoadResource`: Set to `true` to be able to listen at the `onLoadResource` event. The default value is `false`.
|
||||
* `useOnDownloadStart`: Set to `true` to be able to listen at the `onDownloadStart` event. The default value is `false`.
|
||||
* `useOnTargetBlank`: Set to `true` to be able to listen at the `onTargetBlank` event. The default value is `false`.
|
||||
* `clearCache`: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
||||
* `userAgent`: Sets the user-agent for the WebView.
|
||||
* `applicationNameForUserAgent`: Append to the existing user-agent. Setting userAgent will override this.
|
||||
|
@ -369,7 +374,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
|||
* `displayZoomControls`: Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`.
|
||||
* `supportZoom`: Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`.
|
||||
* `databaseEnabled`: Set to `true` if you want the database storage API is enabled. The default value is `false`.
|
||||
* `domStorageEnabled`: Set to `true` if you want the DOM storage API is enabled. The default value is `false`.
|
||||
* `domStorageEnabled`: Set to `true` if you want the DOM storage API is enabled. The default value is `true`.
|
||||
* `useWideViewPort`: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport.
|
||||
* `safeBrowsingEnabled`: Sets whether Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links.
|
||||
* `mixedContentMode`: Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin.
|
||||
|
@ -403,6 +408,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
|||
* `saveFormData`: Sets whether the WebView should save form data. In Android O, the platform has implemented a fully functional Autofill feature to store form data.
|
||||
* `thirdPartyCookiesEnabled`: Boolean value to enable third party cookies in the WebView.
|
||||
* `hardwareAcceleration`: Boolean value to enable Hardware Acceleration in the WebView.
|
||||
* `supportMultipleWindows`: Sets whether the WebView whether supports multiple windows.
|
||||
|
||||
##### `InAppWebView` iOS-specific options
|
||||
|
||||
|
@ -429,12 +435,13 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
|||
* `onLoadHttpError`: Event fired when the InAppWebView main page receives an HTTP error.
|
||||
* `onProgressChanged`: Event fired when the current progress of loading a page is changed.
|
||||
* `onConsoleMessage`: Event fired when the InAppWebView receives a ConsoleMessage.
|
||||
* `shouldOverrideUrlLoading`: Give the host application a chance to take control when a URL is about to be loaded in the current WebView (to use this event, the `useShouldOverrideUrlLoading` option must be `true`).
|
||||
* `shouldOverrideUrlLoading`: Give the host application a chance to take control when a URL is about to be loaded in the current WebView (to use this event, the `useShouldOverrideUrlLoading` option must be `true`). This event is not called on the initial load of the WebView.
|
||||
* `onNavigationStateChange`: Event fired when the navigation state of the InAppWebView changes, for example through the usage of the javascript **[History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API)** functions.
|
||||
* `onLoadResource`: Event fired when the InAppWebView loads a resource (to use this event, the `useOnLoadResource` option must be `true`).
|
||||
* `onScrollChanged`: Event fired when the InAppWebView scrolls.
|
||||
* `onDownloadStart`: Event fired when InAppWebView recognizes and starts a downloadable file (to use this event, the `useOnDownloadStart` option must be `true`).
|
||||
* `onLoadResourceCustomScheme`: Event fired when the InAppWebView finds the `custom-scheme` while loading a resource. Here you can handle the url request and return a CustomSchemeResponse to load a specific resource encoded to `base64`.
|
||||
* `onTargetBlank`: Event fired when the InAppWebView tries to open a link with `target="_blank"` (to use this event, the `useOnTargetBlank` option must be `true`).
|
||||
* `onCreateWindow`: Event fired when the InAppWebView requests the host application to create a new window, for example when trying to open a link with `target="_blank"` or when `window.open()` is called by JavaScript side.
|
||||
* `onGeolocationPermissionsShowPrompt`: Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin (available only on Android).
|
||||
* `onJsAlert`: Event fired when javascript calls the `alert()` method to display an alert dialog.
|
||||
* `onJsConfirm`: Event fired when javascript calls the `confirm()` method to display a confirm dialog.
|
||||
|
@ -448,8 +455,8 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly:
|
|||
* `onAjaxReadyStateChange`: Event fired whenever the `readyState` attribute of an `XMLHttpRequest` changes (to use this event, the `useShouldInterceptAjaxRequest` option must be `true`).
|
||||
* `onAjaxProgress`: Event fired as an `XMLHttpRequest` progress (to use this event, the `useShouldInterceptAjaxRequest` option must be `true`).
|
||||
* `shouldInterceptFetchRequest`: Event fired when a request is sent to a server through [Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API) (to use this event, the `useShouldInterceptFetchRequest` option must be `true`).
|
||||
* `onNavigationStateChange`: Event fired when the navigation state of the InAppWebView changes.
|
||||
* `onPermissionRequest`: Event fired when the webview is requesting permission to access the specified resources and the permission currently isn't granted or denied (available only on Android).
|
||||
* `onPrint`: Event fired when `window.print()` is called from JavaScript side.
|
||||
|
||||
### `InAppBrowser` class
|
||||
|
||||
|
@ -495,9 +502,9 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
}
|
||||
|
||||
@override
|
||||
void shouldOverrideUrlLoading(String url) {
|
||||
print("\n\n override $url\n\n");
|
||||
this.webViewController.loadUrl(url: url);
|
||||
void shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) {
|
||||
print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
||||
this.webViewController.loadUrl(url: shouldOverrideUrlLoadingRequest.url);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -334,6 +334,14 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
|||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "printCurrentPage":
|
||||
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
webView.printCurrentPage();
|
||||
result.success(true);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.app.Activity;
|
|||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.Browser;
|
||||
import android.net.Uri;
|
||||
|
@ -34,6 +35,8 @@ import android.webkit.WebView;
|
|||
import android.webkit.WebViewClient;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ChromeCustomTabsActivity;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CustomTabActivityHelper;
|
||||
|
||||
|
@ -307,13 +310,51 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
|||
case "clearMatches":
|
||||
clearMatches(uuid, result);
|
||||
break;
|
||||
case "scrollTo":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollTo(uuid, x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "scrollBy":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollBy(uuid, x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "pause":
|
||||
onPause(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "resume":
|
||||
onResume(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "pauseTimers":
|
||||
pauseTimers(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "resumeTimers":
|
||||
resumeTimers(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "printCurrentPage":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
printCurrentPage(uuid);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void evaluateJavascript(String uuid, String source, final Result result) {
|
||||
public void evaluateJavascript(String uuid, String source, final Result result) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.evaluateJavascript(source, result);
|
||||
|
@ -322,21 +363,21 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private void injectJavascriptFileFromUrl(String uuid, String urlFile) {
|
||||
public void injectJavascriptFileFromUrl(String uuid, String urlFile) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectJavascriptFileFromUrl(urlFile);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectCSSCode(String uuid, String source) {
|
||||
public void injectCSSCode(String uuid, String source) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectCSSCode(source);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectCSSFileFromUrl(String uuid, String urlFile) {
|
||||
public void injectCSSFileFromUrl(String uuid, String urlFile) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectCSSFileFromUrl(urlFile);
|
||||
|
@ -386,7 +427,7 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
|||
* Opens the intent, providing a chooser that excludes the current app to avoid
|
||||
* circular loops.
|
||||
*/
|
||||
private void openExternalExcludeCurrentApp(Activity activity, Intent intent) {
|
||||
public void openExternalExcludeCurrentApp(Activity activity, Intent intent) {
|
||||
String currentPackage = activity.getPackageName();
|
||||
boolean hasCurrentPackage = false;
|
||||
PackageManager pm = activity.getPackageManager();
|
||||
|
@ -479,21 +520,21 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
|||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
private String getUrl(String uuid) {
|
||||
public String getUrl(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getUrl();
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getTitle(String uuid) {
|
||||
public String getTitle(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getWebViewTitle();
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer getProgress(String uuid) {
|
||||
public Integer getProgress(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getProgress();
|
||||
|
@ -730,6 +771,49 @@ public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
|||
result.success(false);
|
||||
}
|
||||
|
||||
public void scrollTo(String uuid, Integer x, Integer y) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.scrollTo(x, y);
|
||||
}
|
||||
|
||||
public void scrollBy(String uuid, Integer x, Integer y) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.scrollBy(x, y);
|
||||
}
|
||||
|
||||
public void onPause(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.onPauseWebView();
|
||||
}
|
||||
|
||||
public void onResume(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.onResumeWebView();
|
||||
}
|
||||
|
||||
public void pauseTimers(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.pauseTimers();
|
||||
}
|
||||
|
||||
public void resumeTimers(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.resumeTimers();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void printCurrentPage(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.printCurrentPage();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
for ( InAppBrowserActivity activity : webViewActivities.values()) {
|
||||
|
|
|
@ -6,6 +6,8 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
|
@ -537,4 +539,41 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
webView.loadUrl("about:blank");
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollTo(Integer x, Integer y) {
|
||||
if (webView != null)
|
||||
webView.scrollTo(x, y);
|
||||
}
|
||||
|
||||
public void scrollBy(Integer x, Integer y) {
|
||||
if (webView != null)
|
||||
webView.scrollBy(x, y);
|
||||
}
|
||||
|
||||
public void onPauseWebView() {
|
||||
if (webView != null)
|
||||
webView.onPause();
|
||||
}
|
||||
|
||||
public void onResumeWebView() {
|
||||
if (webView != null)
|
||||
webView.onResume();
|
||||
}
|
||||
|
||||
public void pauseTimers() {
|
||||
if (webView != null)
|
||||
webView.pauseTimers();
|
||||
}
|
||||
|
||||
public void resumeTimers() {
|
||||
if (webView != null)
|
||||
webView.resumeTimers();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void printCurrentPage() {
|
||||
if (webView != null)
|
||||
webView.printCurrentPage();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import android.graphics.Bitmap;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
import android.print.PrintManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -18,6 +21,8 @@ import android.webkit.WebHistoryItem;
|
|||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebStorage;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlocker;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerAction;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerHandler;
|
||||
|
@ -34,12 +39,13 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.*;
|
||||
import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.fromValue;
|
||||
|
||||
final public class InAppWebView extends InputAwareWebView {
|
||||
|
||||
|
@ -57,6 +63,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
public float scale = getResources().getDisplayMetrics().density;
|
||||
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
||||
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
||||
public Pattern regexToCancelSubFramesLoadingCompiled;
|
||||
|
||||
static final String consoleLogJS = "(function(console) {" +
|
||||
" var oldLogs = {" +
|
||||
|
@ -84,6 +91,10 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
" }" +
|
||||
"})(window.console);";
|
||||
|
||||
static final String printJS = "window.print = function() {" +
|
||||
" window." + JavaScriptBridgeInterface.name + ".callHandler('onPrint', window.location.href);" +
|
||||
"}";
|
||||
|
||||
static final String platformReadyJS = "window.dispatchEvent(new Event('flutterInAppWebViewPlatformReady'));";
|
||||
|
||||
static final String variableForOnLoadResourceJS = "window._flutter_inappwebview_useOnLoadResource";
|
||||
|
@ -554,7 +565,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
settings.setJavaScriptCanOpenWindowsAutomatically(options.javaScriptCanOpenWindowsAutomatically);
|
||||
settings.setBuiltInZoomControls(options.builtInZoomControls);
|
||||
settings.setDisplayZoomControls(options.displayZoomControls);
|
||||
settings.setSupportMultipleWindows(options.useOnTargetBlank);
|
||||
settings.setSupportMultipleWindows(options.supportMultipleWindows);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
settings.setSafeBrowsingEnabled(options.safeBrowsingEnabled);
|
||||
|
@ -571,7 +582,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
|
||||
if (options.applicationNameForUserAgent != null && !options.applicationNameForUserAgent.isEmpty()) {
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
String userAgent = (options.userAgent != null && !options.userAgent.isEmpty()) ? options.userAgent :WebSettings.getDefaultUserAgent(getContext());
|
||||
String userAgent = (options.userAgent != null && !options.userAgent.isEmpty()) ? options.userAgent : WebSettings.getDefaultUserAgent(getContext());
|
||||
String userAgentWithApplicationName = userAgent + " " + options.applicationNameForUserAgent;
|
||||
settings.setUserAgentString(userAgentWithApplicationName);
|
||||
}
|
||||
|
@ -655,6 +666,9 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
else
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
if (options.regexToCancelSubFramesLoading != null) {
|
||||
regexToCancelSubFramesLoadingCompiled = Pattern.compile(options.regexToCancelSubFramesLoading);
|
||||
}
|
||||
|
||||
contentBlockerHandler.getRuleList().clear();
|
||||
for (Map<String, Map<String, Object>> contentBlocker : options.contentBlockers) {
|
||||
|
@ -996,8 +1010,8 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
if (newOptionsMap.get("mixedContentMode") != null && !options.mixedContentMode.equals(newOptions.mixedContentMode))
|
||||
settings.setMixedContentMode(newOptions.mixedContentMode);
|
||||
|
||||
if (newOptionsMap.get("useOnTargetBlank") != null && options.useOnTargetBlank != newOptions.useOnTargetBlank)
|
||||
settings.setSupportMultipleWindows(newOptions.useOnTargetBlank);
|
||||
if (newOptionsMap.get("supportMultipleWindows") != null && options.supportMultipleWindows != newOptions.supportMultipleWindows)
|
||||
settings.setSupportMultipleWindows(newOptions.supportMultipleWindows);
|
||||
|
||||
if (newOptionsMap.get("useOnDownloadStart") != null && options.useOnDownloadStart != newOptions.useOnDownloadStart) {
|
||||
if (newOptions.useOnDownloadStart) {
|
||||
|
@ -1127,6 +1141,13 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
if (newOptionsMap.get("regexToCancelSubFramesLoading") != null && options.regexToCancelSubFramesLoading != newOptions.regexToCancelSubFramesLoading) {
|
||||
if (newOptions.regexToCancelSubFramesLoading == null)
|
||||
regexToCancelSubFramesLoadingCompiled = null;
|
||||
else
|
||||
regexToCancelSubFramesLoadingCompiled = Pattern.compile(options.regexToCancelSubFramesLoading);
|
||||
}
|
||||
|
||||
if (newOptions.contentBlockers != null) {
|
||||
contentBlockerHandler.getRuleList().clear();
|
||||
for (Map<String, Map<String, Object>> contentBlocker : newOptions.contentBlockers) {
|
||||
|
@ -1304,6 +1325,22 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
webSettings.setBuiltInZoomControls(enabled);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void printCurrentPage() {
|
||||
// Get a PrintManager instance
|
||||
PrintManager printManager = (PrintManager) registrar.activity()
|
||||
.getSystemService(Context.PRINT_SERVICE);
|
||||
|
||||
String jobName = getTitle() + " Document";
|
||||
|
||||
// Get a printCurrentPage adapter instance
|
||||
PrintDocumentAdapter printAdapter = createPrintDocumentAdapter(jobName);
|
||||
|
||||
// Create a printCurrentPage job with name and adapter instance
|
||||
printManager.print(jobName, printAdapter,
|
||||
new PrintAttributes.Builder().build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
|
|
@ -418,16 +418,16 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
|
||||
if (data == null) {
|
||||
// to get the URL, create a temp weview
|
||||
final WebView newWebView = new WebView(view.getContext());
|
||||
final WebView tempWebView = new WebView(view.getContext());
|
||||
// disable javascript
|
||||
newWebView.getSettings().setJavaScriptEnabled(false);
|
||||
newWebView.setWebViewClient(new WebViewClient(){
|
||||
tempWebView.getSettings().setJavaScriptEnabled(false);
|
||||
tempWebView.setWebViewClient(new WebViewClient(){
|
||||
@Override
|
||||
public void onPageStarted(WebView v, String url, Bitmap favicon) {
|
||||
super.onPageStarted(v, url, favicon);
|
||||
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("onTargetBlank", obj);
|
||||
getChannel().invokeMethod("onCreateWindow", obj);
|
||||
|
||||
// stop webview loading
|
||||
v.stopLoading();
|
||||
|
@ -437,13 +437,13 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
v.destroy();
|
||||
}
|
||||
});
|
||||
((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);
|
||||
((WebView.WebViewTransport) resultMsg.obj).setWebView(tempWebView);
|
||||
resultMsg.sendToTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
obj.put("url", data);
|
||||
getChannel().invokeMethod("onTargetBlank", obj);
|
||||
getChannel().invokeMethod("onCreateWindow", obj);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.webkit.ClientCertRequest;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
|
@ -43,6 +44,7 @@ import java.security.cert.X509Certificate;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
|
@ -51,7 +53,6 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
protected static final String LOG_TAG = "IABWebViewClient";
|
||||
private FlutterWebView flutterWebView;
|
||||
private InAppBrowserActivity inAppBrowserActivity;
|
||||
Map<Integer, String> statusCodeMapping = new HashMap<Integer, String>();
|
||||
private static int previousAuthRequestFailureCount = 0;
|
||||
private static List<Credential> credentialsProposed = null;
|
||||
private String onPageStartedURL = "";
|
||||
|
@ -63,72 +64,105 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
else if (obj instanceof FlutterWebView)
|
||||
this.flutterWebView = (FlutterWebView) obj;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
InAppWebView webView = (InAppWebView) view;
|
||||
if (webView.options.useShouldOverrideUrlLoading) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
onShouldOverrideUrlLoading(
|
||||
request.getUrl().toString(),
|
||||
request.getMethod(),
|
||||
request.getRequestHeaders(),
|
||||
request.isForMainFrame(),
|
||||
request.hasGesture(),
|
||||
request.isRedirect());
|
||||
} else {
|
||||
onShouldOverrideUrlLoading(
|
||||
request.getUrl().toString(),
|
||||
request.getMethod(),
|
||||
request.getRequestHeaders(),
|
||||
request.isForMainFrame(),
|
||||
request.hasGesture(),
|
||||
false);
|
||||
}
|
||||
if (webView.regexToCancelSubFramesLoadingCompiled != null) {
|
||||
if (request.isForMainFrame())
|
||||
return true;
|
||||
else {
|
||||
Matcher m = webView.regexToCancelSubFramesLoadingCompiled.matcher(request.getUrl().toString());
|
||||
if (m.matches())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// There isn't any way to load an URL for a frame that is not the main frame,
|
||||
// so if the request is not for the main frame, the navigation is allowed.
|
||||
return request.isForMainFrame();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
|
||||
|
||||
if (((inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView).options.useShouldOverrideUrlLoading) {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("shouldOverrideUrlLoading", obj);
|
||||
onShouldOverrideUrlLoading(url, "GET", null,true, false, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url != null) {
|
||||
if (url.startsWith(WebView.SCHEME_TEL)) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse(url));
|
||||
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivity(intent);
|
||||
return true;
|
||||
} catch (android.content.ActivityNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||
}
|
||||
} else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(url));
|
||||
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivity(intent);
|
||||
return true;
|
||||
} catch (android.content.ActivityNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Error with " + url + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
// If sms:5551212?body=This is the message
|
||||
else if (url.startsWith("sms:")) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
// Get address
|
||||
String address;
|
||||
int parmIndex = url.indexOf('?');
|
||||
if (parmIndex == -1) {
|
||||
address = url.substring(4);
|
||||
} else {
|
||||
address = url.substring(4, parmIndex);
|
||||
|
||||
// If body, then set sms body
|
||||
Uri uri = Uri.parse(url);
|
||||
String query = uri.getQuery();
|
||||
if (query != null) {
|
||||
if (query.startsWith("body=")) {
|
||||
intent.putExtra("sms_body", query.substring(5));
|
||||
}
|
||||
public void onShouldOverrideUrlLoading(final String url, final String method, final Map<String, String> headers, final boolean isForMainFrame, boolean hasGesture, boolean isRedirect) {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
obj.put("method", method);
|
||||
obj.put("headers", headers);
|
||||
obj.put("isForMainFrame", isForMainFrame);
|
||||
obj.put("androidHasGesture", hasGesture);
|
||||
obj.put("androidIsRedirect", isRedirect);
|
||||
obj.put("iosWKNavigationType", null);
|
||||
getChannel().invokeMethod("shouldOverrideUrlLoading", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
Map<String, Object> responseMap = (Map<String, Object>) response;
|
||||
Integer action = (Integer) responseMap.get("action");
|
||||
if (action != null) {
|
||||
switch (action) {
|
||||
case 1:
|
||||
if (isForMainFrame) {
|
||||
// There isn't any way to load an URL for a frame that is not the main frame,
|
||||
// so call this only on main frame.
|
||||
InAppWebView webView = ((inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
webView.loadUrl(url, headers);
|
||||
else
|
||||
webView.loadUrl(url);
|
||||
}
|
||||
return;
|
||||
case 0:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
intent.setData(Uri.parse("sms:" + address));
|
||||
intent.putExtra("address", address);
|
||||
intent.setType("vnd.android-dir/mms-sms");
|
||||
((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivity(intent);
|
||||
return true;
|
||||
} catch (android.content.ActivityNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.shouldOverrideUrlLoading(webView, url);
|
||||
@Override
|
||||
public void error(String s, String s1, Object o) {
|
||||
Log.d(LOG_TAG, "ERROR: " + s + " " + s1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notImplemented() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,7 +172,6 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
|
||||
String js = InAppWebView.consoleLogJS.replaceAll("[\r\n]+", "");
|
||||
js += JavaScriptBridgeInterface.flutterInAppBroserJSClass.replaceAll("[\r\n]+", "");
|
||||
|
||||
if (webView.options.useShouldInterceptAjaxRequest) {
|
||||
js += InAppWebView.interceptAjaxRequestsJS.replaceAll("[\r\n]+", "");
|
||||
}
|
||||
|
@ -148,6 +181,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
if (webView.options.useOnLoadResource) {
|
||||
js += InAppWebView.resourceObserverJS.replaceAll("[\r\n]+", "");
|
||||
}
|
||||
js += InAppWebView.printJS.replaceAll("[\r\n]+", "");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
webView.evaluateJavascript(js, (ValueCallback<String>) null);
|
||||
|
@ -667,6 +701,11 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
return shouldInterceptRequest(view, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
|
||||
|
||||
}
|
||||
|
||||
private MethodChannel getChannel() {
|
||||
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ public class InAppWebViewOptions extends Options {
|
|||
public Boolean useShouldOverrideUrlLoading = false;
|
||||
public Boolean useOnLoadResource = false;
|
||||
public Boolean useOnDownloadStart = false;
|
||||
public Boolean useOnTargetBlank = false;
|
||||
public Boolean clearCache = false;
|
||||
public String userAgent = "";
|
||||
public String applicationNameForUserAgent = "";
|
||||
|
@ -48,7 +47,7 @@ public class InAppWebViewOptions extends Options {
|
|||
public Boolean displayZoomControls = false;
|
||||
public Boolean supportZoom = true;
|
||||
public Boolean databaseEnabled = false;
|
||||
public Boolean domStorageEnabled = false;
|
||||
public Boolean domStorageEnabled = true;
|
||||
public Boolean useWideViewPort = true;
|
||||
public Boolean safeBrowsingEnabled = true;
|
||||
public Integer mixedContentMode;
|
||||
|
@ -82,6 +81,8 @@ public class InAppWebViewOptions extends Options {
|
|||
public Boolean saveFormData = true;
|
||||
public Boolean thirdPartyCookiesEnabled = true;
|
||||
public Boolean hardwareAcceleration = true;
|
||||
public Boolean supportMultipleWindows = false;
|
||||
public String regexToCancelSubFramesLoading;
|
||||
|
||||
@Override
|
||||
public Object onParse(Map.Entry<String, Object> pair) {
|
||||
|
|
|
@ -15,6 +15,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
|
|||
protected static final String LOG_TAG = "InAppWebViewFlutterPlugin";
|
||||
|
||||
public static InAppBrowser inAppBrowser;
|
||||
public static InAppWebViewStatic inAppWebViewStatic;
|
||||
public static MyCookieManager myCookieManager;
|
||||
public static CredentialDatabaseHandler credentialDatabaseHandler;
|
||||
public static ValueCallback<Uri[]> uploadMessageArray;
|
||||
|
@ -28,6 +29,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
|
|||
.platformViewRegistry()
|
||||
.registerViewFactory(
|
||||
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(registrar, registrar.view()));
|
||||
new InAppWebViewStatic(registrar);
|
||||
new MyCookieManager(registrar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
new CredentialDatabaseHandler(registrar);
|
||||
|
@ -44,6 +46,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
|
|||
.getRegistry()
|
||||
.registerViewFactory(
|
||||
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(registrar,null));
|
||||
inAppWebViewStatic = new InAppWebViewStatic(registrar);
|
||||
myCookieManager = new MyCookieManager(registrar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
credentialDatabaseHandler = new CredentialDatabaseHandler(registrar);
|
||||
|
@ -64,6 +67,10 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin {
|
|||
credentialDatabaseHandler.dispose();
|
||||
credentialDatabaseHandler = null;
|
||||
}
|
||||
if (inAppWebViewStatic != null) {
|
||||
inAppWebViewStatic.dispose();
|
||||
inAppWebViewStatic = null;
|
||||
}
|
||||
uploadMessageArray = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview;
|
||||
|
||||
import android.util.Log;
|
||||
import android.webkit.WebSettings;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
|
||||
public PluginRegistry.Registrar registrar;
|
||||
public MethodChannel channel;
|
||||
|
||||
protected static final String LOG_TAG = "InAppWebViewStatic";
|
||||
|
||||
public InAppWebViewStatic(PluginRegistry.Registrar r) {
|
||||
registrar = r;
|
||||
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_static");
|
||||
channel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
|
||||
Log.d(LOG_TAG, call.method);
|
||||
switch (call.method) {
|
||||
case "getDefaultUserAgent":
|
||||
result.success(WebSettings.getDefaultUserAgent(registrar.activeContext()));
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,222 @@ public class JavaScriptBridgeInterface {
|
|||
private FlutterWebView flutterWebView;
|
||||
private InAppBrowserActivity inAppBrowserActivity;
|
||||
|
||||
public static final String flutterInAppBroserJSClass = "window." + name + ".callHandler = function() {" +
|
||||
// https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js
|
||||
public static final String promisePolyfillJS = "if (window.Promise == null) {" +
|
||||
" var setTimeoutFunc = setTimeout;" +
|
||||
" function isArray(x) {" +
|
||||
" return Boolean(x && typeof x.length !== \"undefined\");" +
|
||||
" };" +
|
||||
" function noop() {}" +
|
||||
" function bind(fn, thisArg) {" +
|
||||
" return function() {" +
|
||||
" fn.apply(thisArg, arguments);" +
|
||||
" };" +
|
||||
" };" +
|
||||
" function Promise(fn) {" +
|
||||
" if (!(this instanceof Promise))" +
|
||||
" throw new TypeError(\"Promises must be constructed via new\");" +
|
||||
" if (typeof fn !== \"function\") throw new TypeError(\"not a function\");" +
|
||||
" this._state = 0;" +
|
||||
" this._handled = false;" +
|
||||
" this._value = undefined;" +
|
||||
" this._deferreds = [];" +
|
||||
" doResolve(fn, this);" +
|
||||
" };" +
|
||||
" function handle(self, deferred) {" +
|
||||
" while (self._state === 3) {" +
|
||||
" self = self._value;" +
|
||||
" }" +
|
||||
" if (self._state === 0) {" +
|
||||
" self._deferreds.push(deferred);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" self._handled = true;" +
|
||||
" Promise._immediateFn(function() {" +
|
||||
" var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;" +
|
||||
" if (cb === null) {" +
|
||||
" (self._state === 1 ? resolve : reject)(deferred.promise, self._value);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" var ret;" +
|
||||
" try {" +
|
||||
" ret = cb(self._value);" +
|
||||
" } catch (e) {" +
|
||||
" reject(deferred.promise, e);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" resolve(deferred.promise, ret);" +
|
||||
" });" +
|
||||
" };" +
|
||||
" function resolve(self, newValue) {" +
|
||||
" try {" +
|
||||
" if (newValue === self)" +
|
||||
" throw new TypeError(\"A promise cannot be resolved with itself.\");" +
|
||||
" if (" +
|
||||
" newValue &&" +
|
||||
" (typeof newValue === \"object\" || typeof newValue === \"function\")" +
|
||||
" ) {" +
|
||||
" var then = newValue.then;" +
|
||||
" if (newValue instanceof Promise) {" +
|
||||
" self._state = 3;" +
|
||||
" self._value = newValue;" +
|
||||
" finale(self);" +
|
||||
" return;" +
|
||||
" } else if (typeof then === \"function\") {" +
|
||||
" doResolve(bind(then, newValue), self);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" }" +
|
||||
" self._state = 1;" +
|
||||
" self._value = newValue;" +
|
||||
" finale(self);" +
|
||||
" } catch (e) {" +
|
||||
" reject(self, e);" +
|
||||
" }" +
|
||||
" };" +
|
||||
" function reject(self, newValue) {" +
|
||||
" self._state = 2;" +
|
||||
" self._value = newValue;" +
|
||||
" finale(self);" +
|
||||
" };" +
|
||||
" function finale(self) {" +
|
||||
" if (self._state === 2 && self._deferreds.length === 0) {" +
|
||||
" Promise._immediateFn(function() {" +
|
||||
" if (!self._handled) {" +
|
||||
" Promise._unhandledRejectionFn(self._value);" +
|
||||
" }" +
|
||||
" });" +
|
||||
" }" +
|
||||
" for (var i = 0, len = self._deferreds.length; i < len; i++) {" +
|
||||
" handle(self, self._deferreds[i]);" +
|
||||
" }" +
|
||||
" self._deferreds = null;" +
|
||||
" };" +
|
||||
" function Handler(onFulfilled, onRejected, promise) {" +
|
||||
" this.onFulfilled = typeof onFulfilled === \"function\" ? onFulfilled : null;" +
|
||||
" this.onRejected = typeof onRejected === \"function\" ? onRejected : null;" +
|
||||
" this.promise = promise;" +
|
||||
" };" +
|
||||
" function doResolve(fn, self) {" +
|
||||
" var done = false;" +
|
||||
" try {" +
|
||||
" fn(" +
|
||||
" function(value) {" +
|
||||
" if (done) return;" +
|
||||
" done = true;" +
|
||||
" resolve(self, value);" +
|
||||
" }," +
|
||||
" function(reason) {" +
|
||||
" if (done) return;" +
|
||||
" done = true;" +
|
||||
" reject(self, reason);" +
|
||||
" }" +
|
||||
" );" +
|
||||
" } catch (ex) {" +
|
||||
" if (done) return;" +
|
||||
" done = true;" +
|
||||
" reject(self, ex);" +
|
||||
" }" +
|
||||
" };" +
|
||||
" Promise.prototype[\"catch\"] = function(onRejected) {" +
|
||||
" return this.then(null, onRejected);" +
|
||||
" };" +
|
||||
" Promise.prototype.then = function(onFulfilled, onRejected) {" +
|
||||
" var prom = new this.constructor(noop);" +
|
||||
" handle(this, new Handler(onFulfilled, onRejected, prom));" +
|
||||
" return prom;" +
|
||||
" };" +
|
||||
" Promise.prototype[\"finally\"] = function finallyConstructor(callback) {" +
|
||||
" var constructor = this.constructor;" +
|
||||
" return this.then(" +
|
||||
" function(value) {" +
|
||||
" return constructor.resolve(callback()).then(function() {" +
|
||||
" return value;" +
|
||||
" });" +
|
||||
" }," +
|
||||
" function(reason) {" +
|
||||
" return constructor.resolve(callback()).then(function() {" +
|
||||
" return constructor.reject(reason);" +
|
||||
" });" +
|
||||
" }" +
|
||||
" );" +
|
||||
" };" +
|
||||
" Promise.all = function(arr) {" +
|
||||
" return new Promise(function(resolve, reject) {" +
|
||||
" if (!isArray(arr)) {" +
|
||||
" return reject(new TypeError(\"Promise.all accepts an array\"));" +
|
||||
" }" +
|
||||
" var args = Array.prototype.slice.call(arr);" +
|
||||
" if (args.length === 0) return resolve([]);" +
|
||||
" var remaining = args.length;" +
|
||||
" function res(i, val) {" +
|
||||
" try {" +
|
||||
" if (val && (typeof val === \"object\" || typeof val === \"function\")) {" +
|
||||
" var then = val.then;" +
|
||||
" if (typeof then === \"function\") {" +
|
||||
" then.call(" +
|
||||
" val," +
|
||||
" function(val) {" +
|
||||
" res(i, val);" +
|
||||
" }," +
|
||||
" reject" +
|
||||
" );" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" }" +
|
||||
" args[i] = val;" +
|
||||
" if (--remaining === 0) {" +
|
||||
" resolve(args);" +
|
||||
" }" +
|
||||
" } catch (ex) {" +
|
||||
" reject(ex);" +
|
||||
" }" +
|
||||
" }" +
|
||||
" for (var i = 0; i < args.length; i++) {" +
|
||||
" res(i, args[i]);" +
|
||||
" }" +
|
||||
" });" +
|
||||
" };" +
|
||||
" Promise.resolve = function(value) {" +
|
||||
" if (value && typeof value === \"object\" && value.constructor === Promise) {" +
|
||||
" return value;" +
|
||||
" }" +
|
||||
"" +
|
||||
" return new Promise(function(resolve) {" +
|
||||
" resolve(value);" +
|
||||
" });" +
|
||||
" };" +
|
||||
" Promise.reject = function(value) {" +
|
||||
" return new Promise(function(resolve, reject) {" +
|
||||
" reject(value);" +
|
||||
" });" +
|
||||
" };" +
|
||||
" Promise.race = function(arr) {" +
|
||||
" return new Promise(function(resolve, reject) {" +
|
||||
" if (!isArray(arr)) {" +
|
||||
" return reject(new TypeError(\"Promise.race accepts an array\"));" +
|
||||
" }" +
|
||||
" for (var i = 0, len = arr.length; i < len; i++) {" +
|
||||
" Promise.resolve(arr[i]).then(resolve, reject);" +
|
||||
" }" +
|
||||
" });" +
|
||||
" };" +
|
||||
" Promise._immediateFn =" +
|
||||
" (typeof setImmediate === \"function\" &&" +
|
||||
" function(fn) {" +
|
||||
" setImmediate(fn);" +
|
||||
" }) ||" +
|
||||
" function(fn) {" +
|
||||
" setTimeoutFunc(fn, 0);" +
|
||||
" };" +
|
||||
" Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {" +
|
||||
" if (typeof console !== \"undefined\" && console) {" +
|
||||
" console.warn(\"Possible Unhandled Promise Rejection:\", err);" +
|
||||
" }" +
|
||||
" };" +
|
||||
"}";
|
||||
|
||||
public static final String flutterInAppBroserJSClass = promisePolyfillJS + " " + "window." + name + ".callHandler = function() {" +
|
||||
"var _callHandlerID = setTimeout(function(){});" +
|
||||
"window." + name + "._callHandler(arguments[0], _callHandlerID, JSON.stringify(Array.prototype.slice.call(arguments, 1)));" +
|
||||
"return new Promise(function(resolve, reject) {" +
|
||||
|
@ -37,6 +252,8 @@ public class JavaScriptBridgeInterface {
|
|||
|
||||
@JavascriptInterface
|
||||
public void _callHandler(final String handlerName, final String _callHandlerID, String args) {
|
||||
final InAppWebView webView = (inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView;
|
||||
|
||||
final Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
|
@ -49,11 +266,13 @@ public class JavaScriptBridgeInterface {
|
|||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (handlerName.equals("onPrint") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
webView.printCurrentPage();
|
||||
}
|
||||
|
||||
getChannel().invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object json) {
|
||||
InAppWebView webView = (inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView;
|
||||
|
||||
if (webView == null) {
|
||||
// The webview has already been disposed, ignore.
|
||||
return;
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
# This is a generated file; do not edit or check into version control.
|
||||
export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
|
||||
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
|
||||
export "FLUTTER_TARGET=lib/main.dart"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
|
||||
export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios"
|
||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||
export "FLUTTER_BUILD_NUMBER=1"
|
||||
export "TRACK_WIDGET_CREATION=true"
|
||||
|
|
|
@ -37,7 +37,7 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
}
|
||||
|
||||
@override
|
||||
void shouldOverrideUrlLoading(String url) {
|
||||
void shouldOverrideUrlLoading(String url, Map<String, String> headers, bool isForMainFrame) {
|
||||
print("\n\n override $url\n\n");
|
||||
this.webViewController.loadUrl(url: url);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
title: Text("InAppWebView")
|
||||
),
|
||||
drawer: myDrawer(context: context),
|
||||
body: Container(
|
||||
body: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
|
@ -69,6 +69,11 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
this.url = url;
|
||||
});
|
||||
},
|
||||
onNavigationStateChange: (InAppWebViewController controller, String url) async {
|
||||
setState(() {
|
||||
this.url = url;
|
||||
});
|
||||
},
|
||||
onProgressChanged: (InAppWebViewController controller, int progress) {
|
||||
setState(() {
|
||||
this.progress = progress / 100;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'dart:async';
|
||||
/*import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:flutter_inappwebview_example/chrome_safari_browser_example.screen.dart';
|
||||
import 'package:flutter_inappwebview_example/in_app_webiew_example.screen.dart';
|
||||
import 'package:flutter_inappwebview_example/in_app_browser_example.screen.dart';
|
||||
import 'chrome_safari_browser_example.screen.dart';
|
||||
import 'in_app_webiew_example.screen.dart';
|
||||
import 'in_app_browser_example.screen.dart';
|
||||
|
||||
// InAppLocalhostServer localhostServer = new InAppLocalhostServer();
|
||||
|
||||
|
@ -76,4 +76,279 @@ class _MyAppState extends State<MyApp> {
|
|||
}
|
||||
);
|
||||
}
|
||||
}*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
|
||||
Future main() async {
|
||||
runApp(new MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
@override
|
||||
_MyAppState createState() => new _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: InAppWebViewPage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InAppWebViewPage extends StatefulWidget {
|
||||
|
||||
@override
|
||||
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
|
||||
}
|
||||
|
||||
class _InAppWebViewPageState extends State<InAppWebViewPage> with WidgetsBindingObserver {
|
||||
InAppWebViewController webView;
|
||||
String defaultUserAgent;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
print(state);
|
||||
if (webView != null) {
|
||||
if (Platform.isAndroid) {
|
||||
if (state == AppLifecycleState.paused) {
|
||||
webView.pause();
|
||||
} else if (state == AppLifecycleState.resumed) {
|
||||
webView.resume();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == AppLifecycleState.paused) {
|
||||
webView.pauseTimers();
|
||||
} else if (state == AppLifecycleState.resumed) {
|
||||
webView.resumeTimers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("InAppWebView")
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: InAppWebView(
|
||||
//initialUrl: "https:/flutter.dev",
|
||||
//initialFile: "assets/index.html",
|
||||
initialData: InAppWebViewInitialData(
|
||||
data: """
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Flutter InAppWebView</title>
|
||||
<link rel="stylesheet" href="https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
</head>
|
||||
<body class="text-center">
|
||||
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
|
||||
<header class="masthead mb-auto">
|
||||
<div class="inner">
|
||||
<h3 class="masthead-brand">Flutter InAppWebView</h3>
|
||||
<nav class="nav nav-masthead justify-content-center">
|
||||
<a class="nav-link active" href="index.html">Home</a>
|
||||
<a class="nav-link" href="page-1.html">Page 1</a>
|
||||
<a class="nav-link" href="page-2.html">Page 2</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<form action="https://example.org/" method="POST">
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
<main role="main" class="inner cover">
|
||||
<h1 class="cover-heading">Inline WebView</h1>
|
||||
<img src="images/flutter-logo.svg" alt="flutter logo">
|
||||
<p class="lead">Cover is a one-page template for building simple and beautiful home pages. Download, edit the text, and add your own fullscreen background photo to make it your own.</p>
|
||||
</main>
|
||||
|
||||
<footer class="mastfoot mt-auto">
|
||||
<div class="inner">
|
||||
<p>Cover template for <a target="_blank" href="https://getbootstrap.com/">Bootstrap</a>, by <a href="https://twitter.com/mdo">@mdo</a>.</p>
|
||||
<p>Phone link example <a href="tel:1-408-555-5555">1-408-555-5555</a></p>
|
||||
<p>Email link example <a href="mailto:example@gmail.com">example@gmail.com</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
),
|
||||
initialHeaders: {},
|
||||
initialOptions: InAppWebViewWidgetOptions(
|
||||
inAppWebViewOptions: InAppWebViewOptions(
|
||||
debuggingEnabled: true,
|
||||
useShouldOverrideUrlLoading: true
|
||||
),
|
||||
androidInAppWebViewOptions: AndroidInAppWebViewOptions(
|
||||
domStorageEnabled: true,
|
||||
regexToCancelSubFramesLoading: ""
|
||||
)
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
},
|
||||
onLoadStart: (InAppWebViewController controller, String url) {
|
||||
print("start $url");
|
||||
},
|
||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
||||
print("stop $url");
|
||||
},
|
||||
onPrint: (InAppWebViewController controller, String url) async {
|
||||
print("print $url");
|
||||
},
|
||||
onCreateWindow: (InAppWebViewController controller, String url) async {
|
||||
print("target blank $url");
|
||||
},
|
||||
shouldOverrideUrlLoading: (InAppWebViewController controller, ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
||||
print("overidde url ${shouldOverrideUrlLoadingRequest.url}, method: ${shouldOverrideUrlLoadingRequest.method}, headers: ${shouldOverrideUrlLoadingRequest.headers}, isForMainFrame: ${shouldOverrideUrlLoadingRequest.isForMainFrame}");
|
||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
||||
},
|
||||
),
|
||||
)
|
||||
/*Container(
|
||||
child: InAppWebView(
|
||||
initialUrl: "about:blank",
|
||||
//initialUrl: "https://www.youtube.com/embed/fq4N0hgOWzU",
|
||||
initialHeaders: {},
|
||||
initialOptions: InAppWebViewWidgetOptions(
|
||||
inAppWebViewOptions: InAppWebViewOptions(
|
||||
debuggingEnabled: true,
|
||||
)
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
},
|
||||
onLoadStart: (InAppWebViewController controller, String url) {
|
||||
|
||||
},
|
||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
||||
|
||||
if (url == "about:blank" && defaultUserAgent == null) {
|
||||
defaultUserAgent = await controller.evaluateJavascript(
|
||||
source: "navigator.userAgent");
|
||||
|
||||
webView.setOptions(options: InAppWebViewWidgetOptions(
|
||||
inAppWebViewOptions: InAppWebViewOptions(
|
||||
userAgent: defaultUserAgent + " my-custom-value",
|
||||
)
|
||||
));
|
||||
|
||||
webView.loadUrl(url: "https://flutter.dev");
|
||||
}
|
||||
|
||||
print(await controller.evaluateJavascript(
|
||||
source: "navigator.userAgent"));
|
||||
},
|
||||
),
|
||||
)*/
|
||||
/*child: FutureBuilder(
|
||||
future: InAppWebViewController.getDefaultUserAgent(),
|
||||
builder: (context, projectSnap) {
|
||||
if (!projectSnap.hasData) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
return Container(
|
||||
child: InAppWebView(
|
||||
initialUrl: "https://flutter.dev",
|
||||
//initialUrl: "https://www.youtube.com/embed/fq4N0hgOWzU",
|
||||
initialHeaders: {},
|
||||
initialOptions: InAppWebViewWidgetOptions(
|
||||
inAppWebViewOptions: InAppWebViewOptions(
|
||||
debuggingEnabled: true,
|
||||
userAgent: projectSnap.data.toString() + "; my-value"
|
||||
)
|
||||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
},
|
||||
onLoadStart: (InAppWebViewController controller, String url) {
|
||||
|
||||
},
|
||||
onLoadStop: (InAppWebViewController controller, String url) async {
|
||||
print(await controller.evaluateJavascript(source: "navigator.userAgent"));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
),*/
|
||||
),
|
||||
ButtonBar(
|
||||
alignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
RaisedButton(
|
||||
child: Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
if (webView != null) {
|
||||
webView.goBack();
|
||||
}
|
||||
},
|
||||
),
|
||||
RaisedButton(
|
||||
child: Icon(Icons.arrow_forward),
|
||||
onPressed: () {
|
||||
if (webView != null) {
|
||||
webView.goForward();
|
||||
}
|
||||
},
|
||||
),
|
||||
RaisedButton(
|
||||
child: Icon(Icons.refresh),
|
||||
onPressed: () {
|
||||
if (webView != null) {
|
||||
webView.reload();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
]))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ flutter:
|
|||
- test_assets/in_app_webview_javascript_handler_test.html
|
||||
- test_assets/in_app_webview_on_load_resource_custom_scheme_test.html
|
||||
- test_assets/in_app_webview_on_console_message_test.html
|
||||
- test_assets/in_app_webview_on_target_blank_test.html
|
||||
- test_assets/in_app_webview_on_create_window_test.html
|
||||
- test_assets/in_app_webview_on_js_dialog_test.html
|
||||
- test_assets/css/
|
||||
- test_assets/images/
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>InAppWebViewOnTargetBlankTest</title>
|
||||
<title>InAppWebViewOnCreateWindowTest</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>InAppWebViewOnTargetBlankTest</h1>
|
||||
<h1>InAppWebViewOnCreateWindowTest</h1>
|
||||
<a id="target-blank" href="https://flutter.dev/" target="_blank">target blank</a>
|
||||
<script>
|
||||
document.querySelector('#target-blank').click();
|
|
@ -5,15 +5,15 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|||
import 'main_test.dart';
|
||||
import 'custom_widget_test.dart';
|
||||
|
||||
class InAppWebViewOnTargetBlankTest extends WidgetTest {
|
||||
final InAppWebViewOnTargetBlankTestState state = InAppWebViewOnTargetBlankTestState();
|
||||
class InAppWebViewOnCreateWindowTest extends WidgetTest {
|
||||
final InAppWebViewOnCreateWindowTestState state = InAppWebViewOnCreateWindowTestState();
|
||||
|
||||
@override
|
||||
InAppWebViewOnTargetBlankTestState createState() => state;
|
||||
InAppWebViewOnCreateWindowTestState createState() => state;
|
||||
}
|
||||
|
||||
class InAppWebViewOnTargetBlankTestState extends WidgetTestState {
|
||||
String appBarTitle = "InAppWebViewOnTargetBlankTest";
|
||||
class InAppWebViewOnCreateWindowTestState extends WidgetTestState {
|
||||
String appBarTitle = "InAppWebViewOnCreateWindowTest";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -26,13 +26,12 @@ class InAppWebViewOnTargetBlankTestState extends WidgetTestState {
|
|||
Expanded(
|
||||
child: Container(
|
||||
child: InAppWebView(
|
||||
initialFile: "test_assets/in_app_webview_on_target_blank_test.html",
|
||||
initialFile: "test_assets/in_app_webview_on_create_window_test.html",
|
||||
initialHeaders: {},
|
||||
initialOptions: InAppWebViewWidgetOptions(
|
||||
inAppWebViewOptions: InAppWebViewOptions(
|
||||
clearCache: true,
|
||||
debuggingEnabled: true,
|
||||
useOnTargetBlank: true,
|
||||
javaScriptCanOpenWindowsAutomatically: true,
|
||||
)
|
||||
),
|
||||
|
@ -49,7 +48,7 @@ class InAppWebViewOnTargetBlankTestState extends WidgetTestState {
|
|||
});
|
||||
}
|
||||
},
|
||||
onTargetBlank: (InAppWebViewController controller, String url) {
|
||||
onCreateWindow: (InAppWebViewController controller, String url) {
|
||||
controller.loadUrl(url: url);
|
||||
},
|
||||
),
|
|
@ -50,8 +50,9 @@ class InAppWebViewShouldOverrideUrlLoadingTestState extends WidgetTestState {
|
|||
controller.evaluateJavascript(source: "document.querySelector('#link').click();");
|
||||
}
|
||||
},
|
||||
shouldOverrideUrlLoading: (InAppWebViewController controller, String url) {
|
||||
shouldOverrideUrlLoading: (InAppWebViewController controller, ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
||||
controller.loadUrl(url: "https://flutter.dev/");
|
||||
return ShouldOverrideUrlLoadingAction.CANCEL;
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -25,7 +25,7 @@ import 'in_app_webview_on_progress_changed_test.dart';
|
|||
import 'in_app_webview_on_received_http_auth_request_test.dart';
|
||||
import 'in_app_webview_on_safe_browsing_hit_test.dart';
|
||||
import 'in_app_webview_on_scroll_changed_test.dart';
|
||||
import 'in_app_webview_on_target_blank_test.dart';
|
||||
import 'in_app_webview_on_create_window_test.dart';
|
||||
import 'in_app_webview_should_override_url_loading_test.dart';
|
||||
import 'in_app_webview_ssl_request_test.dart';
|
||||
|
||||
|
@ -44,7 +44,7 @@ Map<String, WidgetBuilder> getTestRoutes({@required BuildContext context}) {
|
|||
'/InAppWebViewShouldOverrideUrlLoadingTest': (context) => InAppWebViewShouldOverrideUrlLoadingTest(),
|
||||
'/InAppWebViewOnConsoleMessageTest': (context) => InAppWebViewOnConsoleMessageTest(),
|
||||
'/InAppWebViewOnDownloadStartTest': (context) => InAppWebViewOnDownloadStartTest(),
|
||||
'/InAppWebViewOnTargetBlankTest': (context) => InAppWebViewOnTargetBlankTest(),
|
||||
'/InAppWebViewOnCreateWindowTest': (context) => InAppWebViewOnCreateWindowTest(),
|
||||
'/InAppWebViewOnJsDialogTest': (context) => InAppWebViewOnJsDialogTest(),
|
||||
'/InAppWebViewOnSafeBrowsingHitTest': (context) => InAppWebViewOnSafeBrowsingHitTest(),
|
||||
'/InAppWebViewOnReceivedHttpAuthRequestTest': (context) => InAppWebViewOnReceivedHttpAuthRequestTest(),
|
||||
|
|
|
@ -20,7 +20,13 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
|
||||
|
|
|
@ -330,6 +330,20 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||
}
|
||||
result(true)
|
||||
break
|
||||
case "printCurrentPage":
|
||||
if webView != nil {
|
||||
webView!.printCurrentPage(printCompletionHandler: {(completed, error) in
|
||||
if !completed, let e = error {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "removeFromSuperview":
|
||||
webView!.removeFromSuperview()
|
||||
result(true)
|
||||
|
|
|
@ -41,6 +41,234 @@ func JSONStringify(value: Any, prettyPrinted: Bool = false) -> String {
|
|||
|
||||
let JAVASCRIPT_BRIDGE_NAME = "flutter_inappwebview"
|
||||
|
||||
// https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js
|
||||
let promisePolyfillJS = """
|
||||
if (window.Promise == null) {
|
||||
var setTimeoutFunc = setTimeout;
|
||||
function isArray(x) {
|
||||
return Boolean(x && typeof x.length !== "undefined");
|
||||
};
|
||||
function noop() {}
|
||||
function bind(fn, thisArg) {
|
||||
return function() {
|
||||
fn.apply(thisArg, arguments);
|
||||
};
|
||||
};
|
||||
function Promise(fn) {
|
||||
if (!(this instanceof Promise))
|
||||
throw new TypeError("Promises must be constructed via new");
|
||||
if (typeof fn !== "function") throw new TypeError("not a function");
|
||||
this._state = 0;
|
||||
this._handled = false;
|
||||
this._value = undefined;
|
||||
this._deferreds = [];
|
||||
doResolve(fn, this);
|
||||
};
|
||||
function handle(self, deferred) {
|
||||
while (self._state === 3) {
|
||||
self = self._value;
|
||||
}
|
||||
if (self._state === 0) {
|
||||
self._deferreds.push(deferred);
|
||||
return;
|
||||
}
|
||||
self._handled = true;
|
||||
Promise._immediateFn(function() {
|
||||
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
|
||||
if (cb === null) {
|
||||
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
|
||||
return;
|
||||
}
|
||||
var ret;
|
||||
try {
|
||||
ret = cb(self._value);
|
||||
} catch (e) {
|
||||
reject(deferred.promise, e);
|
||||
return;
|
||||
}
|
||||
resolve(deferred.promise, ret);
|
||||
});
|
||||
};
|
||||
function resolve(self, newValue) {
|
||||
try {
|
||||
if (newValue === self)
|
||||
throw new TypeError("A promise cannot be resolved with itself.");
|
||||
if (
|
||||
newValue &&
|
||||
(typeof newValue === "object" || typeof newValue === "function")
|
||||
) {
|
||||
var then = newValue.then;
|
||||
if (newValue instanceof Promise) {
|
||||
self._state = 3;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
return;
|
||||
} else if (typeof then === "function") {
|
||||
doResolve(bind(then, newValue), self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self._state = 1;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
} catch (e) {
|
||||
reject(self, e);
|
||||
}
|
||||
};
|
||||
function reject(self, newValue) {
|
||||
self._state = 2;
|
||||
self._value = newValue;
|
||||
finale(self);
|
||||
};
|
||||
function finale(self) {
|
||||
if (self._state === 2 && self._deferreds.length === 0) {
|
||||
Promise._immediateFn(function() {
|
||||
if (!self._handled) {
|
||||
Promise._unhandledRejectionFn(self._value);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (var i = 0, len = self._deferreds.length; i < len; i++) {
|
||||
handle(self, self._deferreds[i]);
|
||||
}
|
||||
self._deferreds = null;
|
||||
};
|
||||
function Handler(onFulfilled, onRejected, promise) {
|
||||
this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null;
|
||||
this.onRejected = typeof onRejected === "function" ? onRejected : null;
|
||||
this.promise = promise;
|
||||
};
|
||||
function doResolve(fn, self) {
|
||||
var done = false;
|
||||
try {
|
||||
fn(
|
||||
function(value) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
resolve(self, value);
|
||||
},
|
||||
function(reason) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, reason);
|
||||
}
|
||||
);
|
||||
} catch (ex) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
reject(self, ex);
|
||||
}
|
||||
};
|
||||
Promise.prototype["catch"] = function(onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
Promise.prototype.then = function(onFulfilled, onRejected) {
|
||||
var prom = new this.constructor(noop);
|
||||
handle(this, new Handler(onFulfilled, onRejected, prom));
|
||||
return prom;
|
||||
};
|
||||
Promise.prototype["finally"] = function finallyConstructor(callback) {
|
||||
var constructor = this.constructor;
|
||||
return this.then(
|
||||
function(value) {
|
||||
return constructor.resolve(callback()).then(function() {
|
||||
return value;
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
return constructor.resolve(callback()).then(function() {
|
||||
return constructor.reject(reason);
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
Promise.all = function(arr) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (!isArray(arr)) {
|
||||
return reject(new TypeError("Promise.all accepts an array"));
|
||||
}
|
||||
var args = Array.prototype.slice.call(arr);
|
||||
if (args.length === 0) return resolve([]);
|
||||
var remaining = args.length;
|
||||
function res(i, val) {
|
||||
try {
|
||||
if (val && (typeof val === "object" || typeof val === "function")) {
|
||||
var then = val.then;
|
||||
if (typeof then === "function") {
|
||||
then.call(
|
||||
val,
|
||||
function(val) {
|
||||
res(i, val);
|
||||
},
|
||||
reject
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
args[i] = val;
|
||||
if (--remaining === 0) {
|
||||
resolve(args);
|
||||
}
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
res(i, args[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
Promise.resolve = function(value) {
|
||||
if (value && typeof value === "object" && value.constructor === Promise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
Promise.reject = function(value) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
reject(value);
|
||||
});
|
||||
};
|
||||
Promise.race = function(arr) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (!isArray(arr)) {
|
||||
return reject(new TypeError("Promise.race accepts an array"));
|
||||
}
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
Promise.resolve(arr[i]).then(resolve, reject);
|
||||
}
|
||||
});
|
||||
};
|
||||
Promise._immediateFn =
|
||||
(typeof setImmediate === "function" &&
|
||||
function(fn) {
|
||||
setImmediate(fn);
|
||||
}) ||
|
||||
function(fn) {
|
||||
setTimeoutFunc(fn, 0);
|
||||
};
|
||||
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
|
||||
if (typeof console !== "undefined" && console) {
|
||||
console.warn("Possible Unhandled Promise Rejection:", err);
|
||||
}
|
||||
};
|
||||
}
|
||||
"""
|
||||
|
||||
let javaScriptBridgeJS = """
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
|
||||
var _callHandlerID = setTimeout(function(){});
|
||||
window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': arguments[0], '_callHandlerID': _callHandlerID, 'args': JSON.stringify(Array.prototype.slice.call(arguments, 1))} );
|
||||
return new Promise(function(resolve, reject) {
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME)[_callHandlerID] = resolve;
|
||||
});
|
||||
}
|
||||
"""
|
||||
|
||||
// the message needs to be concatenated with '' in order to have the same behavior like on Android
|
||||
let consoleLogJS = """
|
||||
(function(console) {
|
||||
|
@ -71,14 +299,9 @@ let consoleLogJS = """
|
|||
})(window.console);
|
||||
"""
|
||||
|
||||
let javaScriptBridgeJS = """
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME) = {};
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function() {
|
||||
var _callHandlerID = setTimeout(function(){});
|
||||
window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': arguments[0], '_callHandlerID': _callHandlerID, 'args': JSON.stringify(Array.prototype.slice.call(arguments, 1))} );
|
||||
return new Promise(function(resolve, reject) {
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME)[_callHandlerID] = resolve;
|
||||
});
|
||||
let printJS = """
|
||||
window.print = function() {
|
||||
window.\(JAVASCRIPT_BRIDGE_NAME).callHandler("onPrint", window.location.href);
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -691,6 +914,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
var lastScrollY: CGFloat = 0
|
||||
var isPausedTimers = false
|
||||
var isPausedTimersCompletionHandler: (() -> Void)?
|
||||
var webViewForUserAgent: WKWebView?
|
||||
var defaultUserAgent: String?
|
||||
// This flag is used to block the "shouldOverrideUrlLoading" event when the WKWebView is loading the first time,
|
||||
// in order to have the same behavior as Android
|
||||
var activateShouldOverrideUrlLoading = false
|
||||
|
||||
init(frame: CGRect, configuration: WKWebViewConfiguration, IABController: InAppBrowserWebViewController?, IAWController: FlutterWebViewController?) {
|
||||
|
||||
|
@ -700,6 +928,23 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
uiDelegate = self
|
||||
navigationDelegate = self
|
||||
scrollView.delegate = self
|
||||
webViewForUserAgent = WKWebView()
|
||||
|
||||
webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (result, error) in
|
||||
|
||||
if error != nil {
|
||||
print("Error occured to get userAgent")
|
||||
self.webViewForUserAgent = nil
|
||||
return
|
||||
}
|
||||
|
||||
if let unwrappedUserAgent = result as? String {
|
||||
self.defaultUserAgent = unwrappedUserAgent
|
||||
} else {
|
||||
print("Failed to get userAgent")
|
||||
}
|
||||
self.webViewForUserAgent = nil
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
|
@ -746,6 +991,13 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
|
||||
configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
|
||||
|
||||
let promisePolyfillJSScript = WKUserScript(source: promisePolyfillJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
configuration.userContentController.addUserScript(promisePolyfillJSScript)
|
||||
|
||||
let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
||||
configuration.userContentController.add(self, name: "callHandler")
|
||||
|
||||
let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
configuration.userContentController.addUserScript(consoleLogJSScript)
|
||||
configuration.userContentController.add(self, name: "consoleLog")
|
||||
|
@ -754,9 +1006,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
configuration.userContentController.add(self, name: "consoleInfo")
|
||||
configuration.userContentController.add(self, name: "consoleWarn")
|
||||
|
||||
let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
|
||||
configuration.userContentController.add(self, name: "callHandler")
|
||||
let printJSScript = WKUserScript(source: printJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
configuration.userContentController.addUserScript(printJSScript)
|
||||
|
||||
if (options?.useOnLoadResource)! {
|
||||
let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||
|
@ -1300,46 +1551,63 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
decidePolicyFor navigationAction: WKNavigationAction,
|
||||
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
|
||||
let app = UIApplication.shared
|
||||
|
||||
if let url = navigationAction.request.url {
|
||||
// Handle target="_blank"
|
||||
if navigationAction.targetFrame == nil && (options?.useOnTargetBlank)! {
|
||||
onTargetBlank(url: url)
|
||||
decisionHandler(.cancel)
|
||||
return
|
||||
}
|
||||
|
||||
if navigationAction.navigationType == .linkActivated && (options?.useShouldOverrideUrlLoading)! {
|
||||
shouldOverrideUrlLoading(url: url)
|
||||
decisionHandler(.cancel)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle phone and email links
|
||||
if url.scheme == "tel" || url.scheme == "mailto" {
|
||||
if app.canOpenURL(url) {
|
||||
if #available(iOS 10.0, *) {
|
||||
app.open(url)
|
||||
} else {
|
||||
app.openURL(url)
|
||||
if activateShouldOverrideUrlLoading && (options?.useShouldOverrideUrlLoading)! {
|
||||
|
||||
let isForMainFrame = navigationAction.targetFrame?.isMainFrame ?? false
|
||||
|
||||
shouldOverrideUrlLoading(url: url, method: navigationAction.request.httpMethod, headers: navigationAction.request.allHTTPHeaderFields, isForMainFrame: isForMainFrame, navigationType: navigationAction.navigationType, result: { (result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
}
|
||||
}
|
||||
decisionHandler(.cancel)
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
self.updateUrlTextFieldForIABController(navigationAction: navigationAction)
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
else {
|
||||
var response: [String: Any]
|
||||
if let r = result {
|
||||
response = r as! [String: Any]
|
||||
var action = response["action"] as? Int
|
||||
action = action != nil ? action : 0;
|
||||
switch action {
|
||||
case 1:
|
||||
self.updateUrlTextFieldForIABController(navigationAction: navigationAction)
|
||||
decisionHandler(.allow)
|
||||
break
|
||||
default:
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
return;
|
||||
}
|
||||
self.updateUrlTextFieldForIABController(navigationAction: navigationAction)
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
})
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
|
||||
currentURL = url
|
||||
if IABController != nil {
|
||||
IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
|
||||
}
|
||||
}
|
||||
updateUrlTextFieldForIABController(navigationAction: navigationAction)
|
||||
}
|
||||
|
||||
if !activateShouldOverrideUrlLoading {
|
||||
activateShouldOverrideUrlLoading = true
|
||||
}
|
||||
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
|
||||
public func updateUrlTextFieldForIABController(navigationAction: WKNavigationAction) {
|
||||
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
|
||||
currentURL = url
|
||||
if IABController != nil {
|
||||
IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func webView(_ webView: WKWebView,
|
||||
decidePolicyFor navigationResponse: WKNavigationResponse,
|
||||
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||
|
@ -1839,6 +2107,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
lastScrollY = scrollView.contentOffset.y
|
||||
}
|
||||
|
||||
public func webView(_ webView: WKWebView,
|
||||
createWebViewWith configuration: WKWebViewConfiguration,
|
||||
for navigationAction: WKNavigationAction,
|
||||
windowFeatures: WKWindowFeatures) -> WKWebView? {
|
||||
onCreateWindow(url: navigationAction.request.url!)
|
||||
return nil
|
||||
}
|
||||
|
||||
public func onLoadStart(url: String) {
|
||||
var arguments: [String: Any] = ["url": url]
|
||||
if IABController != nil {
|
||||
|
@ -1945,23 +2221,31 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
}
|
||||
}
|
||||
|
||||
public func shouldOverrideUrlLoading(url: URL) {
|
||||
var arguments: [String: Any] = ["url": url.absoluteString]
|
||||
public func shouldOverrideUrlLoading(url: URL, method: String?, headers: [String: String]?, isForMainFrame: Bool, navigationType: WKNavigationType, result: FlutterResult?) {
|
||||
var arguments: [String: Any?] = [
|
||||
"url": url.absoluteString,
|
||||
"method": method,
|
||||
"headers": headers,
|
||||
"isForMainFrame": isForMainFrame,
|
||||
"androidHasGesture": nil,
|
||||
"androidIsRedirect": nil,
|
||||
"iosWKNavigationType": navigationType.rawValue
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("shouldOverrideUrlLoading", arguments: arguments)
|
||||
channel.invokeMethod("shouldOverrideUrlLoading", arguments: arguments, result: result)
|
||||
}
|
||||
}
|
||||
|
||||
public func onTargetBlank(url: URL) {
|
||||
public func onCreateWindow(url: URL) {
|
||||
var arguments: [String: Any] = ["url": url.absoluteString]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onTargetBlank", arguments: arguments)
|
||||
channel.invokeMethod("onCreateWindow", arguments: arguments)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2091,32 +2375,34 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
if message.name.starts(with: "console") {
|
||||
var messageLevel = 1
|
||||
switch (message.name) {
|
||||
case "consoleLog":
|
||||
messageLevel = 1
|
||||
break;
|
||||
case "consoleDebug":
|
||||
// on Android, console.debug is TIP
|
||||
messageLevel = 0
|
||||
break;
|
||||
case "consoleError":
|
||||
messageLevel = 3
|
||||
break;
|
||||
case "consoleInfo":
|
||||
// on Android, console.info is LOG
|
||||
messageLevel = 1
|
||||
break;
|
||||
case "consoleWarn":
|
||||
messageLevel = 2
|
||||
break;
|
||||
default:
|
||||
messageLevel = 1
|
||||
break;
|
||||
case "consoleLog":
|
||||
messageLevel = 1
|
||||
break;
|
||||
case "consoleDebug":
|
||||
// on Android, console.debug is TIP
|
||||
messageLevel = 0
|
||||
break;
|
||||
case "consoleError":
|
||||
messageLevel = 3
|
||||
break;
|
||||
case "consoleInfo":
|
||||
// on Android, console.info is LOG
|
||||
messageLevel = 1
|
||||
break;
|
||||
case "consoleWarn":
|
||||
messageLevel = 2
|
||||
break;
|
||||
default:
|
||||
messageLevel = 1
|
||||
break;
|
||||
}
|
||||
onConsoleMessage(message: message.body as! String, messageLevel: messageLevel)
|
||||
}
|
||||
else if message.name == "callHandler" {
|
||||
} else if message.name == "callHandler" {
|
||||
let body = message.body as! [String: Any]
|
||||
let handlerName = body["handlerName"] as! String
|
||||
if handlerName == "onPrint" {
|
||||
printCurrentPage(printCompletionHandler: nil)
|
||||
}
|
||||
let _callHandlerID = body["_callHandlerID"] as! Int64
|
||||
let args = body["args"] as! String
|
||||
onCallJsHandler(handlerName: handlerName, _callHandlerID: _callHandlerID, args: args)
|
||||
|
@ -2180,6 +2466,27 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
isPausedTimers = false
|
||||
}
|
||||
|
||||
public func printCurrentPage(printCompletionHandler: ((_ completed: Bool, _ error: Error?) -> Void)?) {
|
||||
let printController = UIPrintInteractionController.shared
|
||||
let printFormatter = self.viewPrintFormatter()
|
||||
printController.printFormatter = printFormatter
|
||||
|
||||
let completionHandler: UIPrintInteractionController.CompletionHandler = { (printController, completed, error) in
|
||||
if !completed {
|
||||
if let e = error {
|
||||
print("[PRINT] Failed: \(e.localizedDescription)")
|
||||
} else {
|
||||
print("[PRINT] Canceled")
|
||||
}
|
||||
}
|
||||
if let callback = printCompletionHandler {
|
||||
callback(completed, error)
|
||||
}
|
||||
}
|
||||
|
||||
printController.present(animated: true, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
public override func removeFromSuperview() {
|
||||
configuration.userContentController.removeScriptMessageHandler(forName: "consoleLog")
|
||||
configuration.userContentController.removeScriptMessageHandler(forName: "consoleDebug")
|
||||
|
|
|
@ -14,7 +14,6 @@ public class InAppWebViewOptions: Options {
|
|||
var useShouldOverrideUrlLoading = false
|
||||
var useOnLoadResource = false
|
||||
var useOnDownloadStart = false
|
||||
var useOnTargetBlank = false
|
||||
var clearCache = false
|
||||
var userAgent = ""
|
||||
var applicationNameForUserAgent = ""
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// InAppWebViewStatic.swift
|
||||
// flutter_inappwebview
|
||||
//
|
||||
// Created by Lorenzo Pichilli on 08/12/2019.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WebKit
|
||||
|
||||
class InAppWebViewStatic: NSObject, FlutterPlugin {
|
||||
static var registrar: FlutterPluginRegistrar?
|
||||
static var channel: FlutterMethodChannel?
|
||||
static var webViewForUserAgent: WKWebView?
|
||||
static var defaultUserAgent: String?
|
||||
|
||||
static func register(with registrar: FlutterPluginRegistrar) {
|
||||
|
||||
}
|
||||
|
||||
init(registrar: FlutterPluginRegistrar) {
|
||||
super.init()
|
||||
InAppWebViewStatic.registrar = registrar
|
||||
InAppWebViewStatic.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_static", binaryMessenger: registrar.messenger())
|
||||
registrar.addMethodCallDelegate(self, channel: InAppWebViewStatic.channel!)
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
//let arguments = call.arguments as? NSDictionary
|
||||
switch call.method {
|
||||
case "getDefaultUserAgent":
|
||||
InAppWebViewStatic.getDefaultUserAgent(completionHandler: { (value) in
|
||||
result(value)
|
||||
})
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
static public func getDefaultUserAgent(completionHandler: @escaping (_ value: String?) -> Void) {
|
||||
if defaultUserAgent == nil {
|
||||
InAppWebViewStatic.webViewForUserAgent = WKWebView()
|
||||
InAppWebViewStatic.webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (value, error) in
|
||||
|
||||
if error != nil {
|
||||
print("Error occured to get userAgent")
|
||||
self.webViewForUserAgent = nil
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
if let unwrappedUserAgent = value as? String {
|
||||
InAppWebViewStatic.defaultUserAgent = unwrappedUserAgent
|
||||
completionHandler(defaultUserAgent)
|
||||
} else {
|
||||
print("Failed to get userAgent")
|
||||
}
|
||||
self.webViewForUserAgent = nil
|
||||
}
|
||||
} else {
|
||||
completionHandler(defaultUserAgent)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,12 +57,10 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||
SwiftFlutterPlugin.instance = SwiftFlutterPlugin(with: registrar)
|
||||
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: "com.pichillilorenzo/flutter_inappwebview")
|
||||
|
||||
InAppWebViewStatic(registrar: registrar)
|
||||
if #available(iOS 11.0, *) {
|
||||
MyCookieManager(registrar: registrar)
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
CredentialDatabase(registrar: registrar)
|
||||
}
|
||||
|
||||
|
|
|
@ -357,10 +357,19 @@ class InAppBrowser {
|
|||
///Event fired when the [InAppBrowser] webview receives a [ConsoleMessage].
|
||||
void onConsoleMessage(ConsoleMessage consoleMessage) {}
|
||||
|
||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView. This event is not called on the initial load of the WebView.
|
||||
///
|
||||
///Note that on Android there isn't any way to load an URL for a frame that is not the main frame, so if the request is not for the main frame, the navigation is allowed by default.
|
||||
///However, if you want to cancel requests for subframes, you can use the [AndroidInAppWebViewOptions.regexToCancelSubFramesLoading] option
|
||||
///to write a Regular Expression that, if the url request of a subframe matches, then the request of that subframe is canceled.
|
||||
///
|
||||
///Also, on Android, this method is not called for POST requests.
|
||||
///
|
||||
///[shouldOverrideUrlLoadingRequest] represents the navigation request.
|
||||
///
|
||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldOverrideUrlLoading] option to `true`.
|
||||
void shouldOverrideUrlLoading(String url) {}
|
||||
// ignore: missing_return
|
||||
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) {}
|
||||
|
||||
///Event fired when the [InAppBrowser] webview loads a resource.
|
||||
///
|
||||
|
@ -390,12 +399,13 @@ class InAppBrowser {
|
|||
Future<CustomSchemeResponse> onLoadResourceCustomScheme(
|
||||
String scheme, String url) {}
|
||||
|
||||
///Event fired when the [InAppBrowser] webview tries to open a link with `target="_blank"`.
|
||||
///Event fired when the [InAppBrowser] webview requests the host application to create a new window,
|
||||
///for example when trying to open a link with `target="_blank"` or when `window.open()` is called by JavaScript side.
|
||||
///
|
||||
///[url] represents the url of the link.
|
||||
///[url] represents the url of the request.
|
||||
///
|
||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnTargetBlank] option to `true`.
|
||||
void onTargetBlank(String url) {}
|
||||
///**NOTE**: on Android you need to set [AndroidInAppWebViewOptions.supportMultipleWindows] option to `true`.
|
||||
void onCreateWindow(String url) {}
|
||||
|
||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
||||
|
@ -533,6 +543,13 @@ class InAppBrowser {
|
|||
Future<PermissionRequestResponse> onPermissionRequest(
|
||||
String origin, List<String> resources) {}
|
||||
|
||||
///Event fired when `window.print()` is called from JavaScript side.
|
||||
///
|
||||
///[url] represents the url on which is called.
|
||||
///
|
||||
///**NOTE**: available on Android 21+.
|
||||
void onPrint(String url) {}
|
||||
|
||||
void throwIsAlreadyOpened({String message = ''}) {
|
||||
if (this.isOpened()) {
|
||||
throw Exception([
|
||||
|
|
|
@ -16,12 +16,14 @@ import 'types.dart';
|
|||
import 'in_app_browser.dart';
|
||||
import 'webview_options.dart';
|
||||
|
||||
///List of forbidden names for JavaScript handlers.
|
||||
const javaScriptHandlerForbiddenNames = [
|
||||
"onLoadResource",
|
||||
"shouldInterceptAjaxRequest",
|
||||
"onAjaxReadyStateChange",
|
||||
"onAjaxProgress",
|
||||
"shouldInterceptFetchRequest"
|
||||
"shouldInterceptFetchRequest",
|
||||
"onPrint",
|
||||
];
|
||||
|
||||
///InAppWebView Widget class.
|
||||
|
@ -63,10 +65,18 @@ class InAppWebView extends StatefulWidget {
|
|||
InAppWebViewController controller, ConsoleMessage consoleMessage)
|
||||
onConsoleMessage;
|
||||
|
||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView. This event is not called on the initial load of the WebView.
|
||||
///
|
||||
///Note that on Android there isn't any way to load an URL for a frame that is not the main frame, so if the request is not for the main frame, the navigation is allowed by default.
|
||||
///However, if you want to cancel requests for subframes, you can use the [AndroidInAppWebViewOptions.regexToCancelSubFramesLoading] option
|
||||
///to write a Regular Expression that, if the url request of a subframe matches, then the request of that subframe is canceled.
|
||||
///
|
||||
///Also, on Android, this method is not called for POST requests.
|
||||
///
|
||||
///[shouldOverrideUrlLoadingRequest] represents the navigation request.
|
||||
///
|
||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useShouldOverrideUrlLoading] option to `true`.
|
||||
final void Function(InAppWebViewController controller, String url)
|
||||
final Future<ShouldOverrideUrlLoadingAction> Function(InAppWebViewController controller, ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest)
|
||||
shouldOverrideUrlLoading;
|
||||
|
||||
///Event fired when the [InAppWebView] loads a resource.
|
||||
|
@ -101,13 +111,14 @@ class InAppWebView extends StatefulWidget {
|
|||
InAppWebViewController controller, String scheme, String url)
|
||||
onLoadResourceCustomScheme;
|
||||
|
||||
///Event fired when the [InAppWebView] tries to open a link with `target="_blank"`.
|
||||
///Event fired when the [InAppWebView] requests the host application to create a new window,
|
||||
///for example when trying to open a link with `target="_blank"` or when `window.open()` is called by JavaScript side.
|
||||
///
|
||||
///[url] represents the url of the link.
|
||||
///[url] represents the url of the request.
|
||||
///
|
||||
///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewOptions.useOnTargetBlank] option to `true`.
|
||||
///**NOTE**: on Android you need to set [AndroidInAppWebViewOptions.supportMultipleWindows] option to `true`.
|
||||
final void Function(InAppWebViewController controller, String url)
|
||||
onTargetBlank;
|
||||
onCreateWindow;
|
||||
|
||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
||||
|
@ -246,7 +257,7 @@ class InAppWebView extends StatefulWidget {
|
|||
InAppWebViewController controller, FetchRequest fetchRequest)
|
||||
shouldInterceptFetchRequest;
|
||||
|
||||
///Event fired when the navigation state of the [InAppWebView] changes throught the usage of
|
||||
///Event fired when the navigation state of the [InAppWebView] changes through the usage of
|
||||
///javascript **[History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API)** functions (`pushState()`, `replaceState()`) and `onpopstate` event.
|
||||
///
|
||||
///Also, the event is fired when the javascript `window.location` changes without reloading the webview (for example appending or modifying an hash to the url).
|
||||
|
@ -267,6 +278,13 @@ class InAppWebView extends StatefulWidget {
|
|||
String origin,
|
||||
List<String> resources) onPermissionRequest;
|
||||
|
||||
///Event fired when `window.print()` is called from JavaScript side.
|
||||
///
|
||||
///[url] represents the url on which is called.
|
||||
///
|
||||
///**NOTE**: available on Android 21+.
|
||||
final void Function(InAppWebViewController controller, String url) onPrint;
|
||||
|
||||
///Initial url that will be loaded.
|
||||
final String initialUrl;
|
||||
|
||||
|
@ -310,7 +328,7 @@ class InAppWebView extends StatefulWidget {
|
|||
this.onScrollChanged,
|
||||
this.onDownloadStart,
|
||||
this.onLoadResourceCustomScheme,
|
||||
this.onTargetBlank,
|
||||
this.onCreateWindow,
|
||||
this.onGeolocationPermissionsShowPrompt,
|
||||
this.onJsAlert,
|
||||
this.onJsConfirm,
|
||||
|
@ -326,6 +344,7 @@ class InAppWebView extends StatefulWidget {
|
|||
this.shouldInterceptFetchRequest,
|
||||
this.onNavigationStateChange,
|
||||
this.onPermissionRequest,
|
||||
this.onPrint,
|
||||
this.gestureRecognizers,
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -426,6 +445,7 @@ class _InAppWebViewState extends State<InAppWebView> {
|
|||
class InAppWebViewController {
|
||||
InAppWebView _widget;
|
||||
MethodChannel _channel;
|
||||
static MethodChannel _staticChannel = MethodChannel('com.pichillilorenzo/flutter_inappwebview_static');
|
||||
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
|
||||
HashMap<String, JavaScriptHandlerCallback>();
|
||||
// ignore: unused_field
|
||||
|
@ -491,10 +511,20 @@ class InAppWebViewController {
|
|||
break;
|
||||
case "shouldOverrideUrlLoading":
|
||||
String url = call.arguments["url"];
|
||||
String method = call.arguments["method"];
|
||||
Map<String, String> headers = call.arguments["headers"]?.cast<String, String>();
|
||||
bool isForMainFrame = call.arguments["isForMainFrame"];
|
||||
bool androidHasGesture = call.arguments["androidHasGesture"];
|
||||
bool androidIsRedirect = call.arguments["androidIsRedirect"];
|
||||
int iosWKNavigationType = call.arguments["iosWKNavigationType"];
|
||||
|
||||
ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest = ShouldOverrideUrlLoadingRequest(url: url, method: method, headers: headers, isForMainFrame: isForMainFrame,
|
||||
androidHasGesture: androidHasGesture, androidIsRedirect: androidIsRedirect, iosWKNavigationType: IosWKNavigationType.fromValue(iosWKNavigationType));
|
||||
|
||||
if (_widget != null && _widget.shouldOverrideUrlLoading != null)
|
||||
_widget.shouldOverrideUrlLoading(this, url);
|
||||
return (await _widget.shouldOverrideUrlLoading(this, shouldOverrideUrlLoadingRequest))?.toMap();
|
||||
else if (_inAppBrowser != null)
|
||||
_inAppBrowser.shouldOverrideUrlLoading(url);
|
||||
return (await _inAppBrowser.shouldOverrideUrlLoading(shouldOverrideUrlLoadingRequest))?.toMap();
|
||||
break;
|
||||
case "onConsoleMessage":
|
||||
String message = call.arguments["message"];
|
||||
|
@ -543,11 +573,11 @@ class InAppWebViewController {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case "onTargetBlank":
|
||||
case "onCreateWindow":
|
||||
String url = call.arguments["url"];
|
||||
if (_widget != null && _widget.onTargetBlank != null)
|
||||
_widget.onTargetBlank(this, url);
|
||||
else if (_inAppBrowser != null) _inAppBrowser.onTargetBlank(url);
|
||||
if (_widget != null && _widget.onCreateWindow != null)
|
||||
_widget.onCreateWindow(this, url);
|
||||
else if (_inAppBrowser != null) _inAppBrowser.onCreateWindow(url);
|
||||
break;
|
||||
case "onGeolocationPermissionsShowPrompt":
|
||||
String origin = call.arguments["origin"];
|
||||
|
@ -875,6 +905,13 @@ class InAppWebViewController {
|
|||
return jsonEncode(
|
||||
await _inAppBrowser.shouldInterceptFetchRequest(request));
|
||||
return null;
|
||||
case "onPrint":
|
||||
String url = args[0];
|
||||
if (_widget != null && _widget.onPrint != null)
|
||||
_widget.onPrint(this, url);
|
||||
else if (_inAppBrowser != null)
|
||||
_inAppBrowser.onPrint(url);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (javaScriptHandlersMap.containsKey(handlerName)) {
|
||||
|
@ -1388,6 +1425,8 @@ class InAppWebViewController {
|
|||
/// });
|
||||
/// """);
|
||||
///```
|
||||
///
|
||||
///Forbidden names for JavaScript handlers are defined in [javaScriptHandlerForbiddenNames].
|
||||
void addJavaScriptHandler(
|
||||
{@required String handlerName,
|
||||
@required JavaScriptHandlerCallback callback}) {
|
||||
|
@ -1729,6 +1768,24 @@ class InAppWebViewController {
|
|||
await _channel.invokeMethod('resumeTimers', args);
|
||||
}
|
||||
|
||||
///Prints the current page.
|
||||
///
|
||||
///**NOTE**: available on Android 21+.
|
||||
Future<void> printCurrentPage() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||
_inAppBrowser.throwIsNotOpened();
|
||||
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
||||
}
|
||||
await _channel.invokeMethod('printCurrentPage', args);
|
||||
}
|
||||
|
||||
///Gets the default user agent.
|
||||
static Future<String> getDefaultUserAgent() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _staticChannel.invokeMethod('getDefaultUserAgent', args);
|
||||
}
|
||||
|
||||
/*Future<void> dispose() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
if (Platform.isIOS)
|
||||
|
|
|
@ -1966,3 +1966,94 @@ class PermissionRequestResponse {
|
|||
return {"resources": resources, "action": action?.toValue()};
|
||||
}
|
||||
}
|
||||
|
||||
///ShouldOverrideUrlLoadingAction class is used by [shouldOverrideUrlLoading] event.
|
||||
///It represents the policy to pass back to the decision handler.
|
||||
class ShouldOverrideUrlLoadingAction {
|
||||
final int _value;
|
||||
const ShouldOverrideUrlLoadingAction._internal(this._value);
|
||||
int toValue() => _value;
|
||||
|
||||
///Cancel the navigation.
|
||||
static const CANCEL = const ShouldOverrideUrlLoadingAction._internal(0);
|
||||
|
||||
///Allow the navigation to continue.
|
||||
static const ALLOW = const ShouldOverrideUrlLoadingAction._internal(1);
|
||||
|
||||
bool operator ==(value) => value == _value;
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"action": _value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
///IosWKNavigationType class represents the type of action triggering a navigation on iOS for the [shouldOverrideUrlLoading] event.
|
||||
class IosWKNavigationType {
|
||||
final int _value;
|
||||
const IosWKNavigationType._internal(this._value);
|
||||
int toValue() => _value;
|
||||
static IosWKNavigationType fromValue(int value) {
|
||||
if (value != null && ((value >= 0 && value <= 4) || value == -1))
|
||||
return IosWKNavigationType._internal(value);
|
||||
return null;
|
||||
}
|
||||
|
||||
///A link with an href attribute was activated by the user.
|
||||
static const LINK_ACTIVATED = const IosWKNavigationType._internal(0);
|
||||
|
||||
///A form was submitted.
|
||||
static const FORM_SUBMITTED = const IosWKNavigationType._internal(1);
|
||||
|
||||
///An item from the back-forward list was requested.
|
||||
static const BACK_FORWARD = const IosWKNavigationType._internal(2);
|
||||
|
||||
///The webpage was reloaded.
|
||||
static const RELOAD = const IosWKNavigationType._internal(3);
|
||||
|
||||
///A form was resubmitted (for example by going back, going forward, or reloading).
|
||||
static const FORM_RESUBMITTED = const IosWKNavigationType._internal(4);
|
||||
|
||||
///Navigation is taking place for some other reason.
|
||||
static const OTHER = const IosWKNavigationType._internal(-1);
|
||||
|
||||
bool operator ==(value) => value == _value;
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode;
|
||||
}
|
||||
|
||||
///ShouldOverrideUrlLoadingAction class represents the navigation request used by the [shouldOverrideUrlLoading] event.
|
||||
class ShouldOverrideUrlLoadingRequest {
|
||||
///Represents the url of the navigation request.
|
||||
String url;
|
||||
|
||||
///Represents the method of the navigation request. On Android < 21, this value is always `GET`.
|
||||
String method;
|
||||
|
||||
///Represents the headers of the navigation request. On Android < 21, this is always `null`.
|
||||
Map<String, String> headers;
|
||||
|
||||
///Indicates whether the request was made for the main frame. On Android < 21, this is always `true`.
|
||||
bool isForMainFrame;
|
||||
|
||||
///Gets whether the request was a result of a server-side redirect. Available only on Android. On Android < 21, this is always `false`.
|
||||
bool androidHasGesture;
|
||||
|
||||
///Gets whether a gesture (such as a click) was associated with the request.
|
||||
///For security reasons in certain situations this method may return `false` even though
|
||||
///the sequence of events which caused the request to be created was initiated by a user
|
||||
///gesture.
|
||||
///
|
||||
///Available only on Android. On Android < 24, this is always `false`.
|
||||
bool androidIsRedirect;
|
||||
|
||||
///The type of action triggering the navigation. Available only on iOS.
|
||||
IosWKNavigationType iosWKNavigationType;
|
||||
|
||||
ShouldOverrideUrlLoadingRequest({this.url, this.method, this.headers, this.isForMainFrame, this.androidHasGesture, this.androidIsRedirect, this.iosWKNavigationType});
|
||||
}
|
|
@ -49,9 +49,6 @@ class InAppWebViewOptions
|
|||
///Set to `true` to be able to listen at the [onDownloadStart] event. The default value is `false`.
|
||||
bool useOnDownloadStart;
|
||||
|
||||
///Set to `true` to be able to listen at the [onTargetBlank] event. The default value is `false`.
|
||||
bool useOnTargetBlank;
|
||||
|
||||
///Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
||||
bool clearCache;
|
||||
|
||||
|
@ -135,7 +132,6 @@ class InAppWebViewOptions
|
|||
{this.useShouldOverrideUrlLoading = false,
|
||||
this.useOnLoadResource = false,
|
||||
this.useOnDownloadStart = false,
|
||||
this.useOnTargetBlank = false,
|
||||
this.clearCache = false,
|
||||
this.userAgent = "",
|
||||
this.applicationNameForUserAgent = "",
|
||||
|
@ -174,7 +170,6 @@ class InAppWebViewOptions
|
|||
"useShouldOverrideUrlLoading": useShouldOverrideUrlLoading,
|
||||
"useOnLoadResource": useOnLoadResource,
|
||||
"useOnDownloadStart": useOnDownloadStart,
|
||||
"useOnTargetBlank": useOnTargetBlank,
|
||||
"clearCache": clearCache,
|
||||
"userAgent": userAgent,
|
||||
"applicationNameForUserAgent": applicationNameForUserAgent,
|
||||
|
@ -213,7 +208,6 @@ class InAppWebViewOptions
|
|||
options.useShouldOverrideUrlLoading = map["useShouldOverrideUrlLoading"];
|
||||
options.useOnLoadResource = map["useOnLoadResource"];
|
||||
options.useOnDownloadStart = map["useOnDownloadStart"];
|
||||
options.useOnTargetBlank = map["useOnTargetBlank"];
|
||||
options.clearCache = map["clearCache"];
|
||||
options.userAgent = map["userAgent"];
|
||||
options.applicationNameForUserAgent = map["applicationNameForUserAgent"];
|
||||
|
@ -265,7 +259,7 @@ class AndroidInAppWebViewOptions
|
|||
///Set to `true` if you want the database storage API is enabled. The default value is `false`.
|
||||
bool databaseEnabled;
|
||||
|
||||
///Set to `true` if you want the DOM storage API is enabled. The default value is `false`.
|
||||
///Set to `true` if you want the DOM storage API is enabled. The default value is `true`.
|
||||
bool domStorageEnabled;
|
||||
|
||||
///Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport.
|
||||
|
@ -392,6 +386,7 @@ class AndroidInAppWebViewOptions
|
|||
|
||||
///Sets whether the WebView should save form data. In Android O, the platform has implemented a fully functional Autofill feature to store form data.
|
||||
///Therefore, the Webview form data save feature is disabled. Note that the feature will continue to be supported on older versions of Android as before.
|
||||
///The default value is `true`.
|
||||
bool saveFormData;
|
||||
|
||||
///Boolean value to enable third party cookies in the WebView.
|
||||
|
@ -405,6 +400,13 @@ class AndroidInAppWebViewOptions
|
|||
///The default value is `true`.
|
||||
bool hardwareAcceleration;
|
||||
|
||||
///Sets whether the WebView whether supports multiple windows.
|
||||
///If set to `true`, [onCreateWindow] event must be implemented by the host application. The default value is `false`.
|
||||
bool supportMultipleWindows;
|
||||
|
||||
///Regular expression used by [shouldOverrideUrlLoading] event to cancel navigation for frames that are not the main frame.
|
||||
String regexToCancelSubFramesLoading;
|
||||
|
||||
AndroidInAppWebViewOptions(
|
||||
{this.textZoom = 100,
|
||||
this.clearSessionCache = false,
|
||||
|
@ -412,7 +414,7 @@ class AndroidInAppWebViewOptions
|
|||
this.displayZoomControls = false,
|
||||
this.supportZoom = true,
|
||||
this.databaseEnabled = false,
|
||||
this.domStorageEnabled = false,
|
||||
this.domStorageEnabled = true,
|
||||
this.useWideViewPort = true,
|
||||
this.safeBrowsingEnabled = true,
|
||||
this.mixedContentMode,
|
||||
|
@ -445,7 +447,9 @@ class AndroidInAppWebViewOptions
|
|||
this.saveFormData = true,
|
||||
this.thirdPartyCookiesEnabled = true,
|
||||
this.hardwareAcceleration = true,
|
||||
this.initialScale = 0});
|
||||
this.initialScale = 0,
|
||||
this.supportMultipleWindows = false,
|
||||
this.regexToCancelSubFramesLoading});
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
|
@ -489,7 +493,9 @@ class AndroidInAppWebViewOptions
|
|||
"standardFontFamily": standardFontFamily,
|
||||
"saveFormData": saveFormData,
|
||||
"thirdPartyCookiesEnabled": thirdPartyCookiesEnabled,
|
||||
"hardwareAcceleration": hardwareAcceleration
|
||||
"hardwareAcceleration": hardwareAcceleration,
|
||||
"supportMultipleWindows": supportMultipleWindows,
|
||||
"regexToCancelSubFramesLoading": regexToCancelSubFramesLoading
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -542,6 +548,8 @@ class AndroidInAppWebViewOptions
|
|||
options.saveFormData = map["saveFormData"];
|
||||
options.thirdPartyCookiesEnabled = map["thirdPartyCookiesEnabled"];
|
||||
options.hardwareAcceleration = map["hardwareAcceleration"];
|
||||
options.supportMultipleWindows = map["supportMultipleWindows"];
|
||||
options.regexToCancelSubFramesLoading = map["regexToCancelSubFramesLoading"];
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_inappwebview
|
||||
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window.
|
||||
version: 2.1.0+1
|
||||
version: 2.2.0
|
||||
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
||||
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||
|
||||
|
|
Loading…
Reference in New Issue