added HttpAuthCredentialDatabase class, clearCache method, onReceivedHttpAuthRequest event
This commit is contained in:
parent
fed99ec0e9
commit
68ff79c716
|
@ -15,20 +15,34 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/DisplayListenerProxy.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/Credential.java" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InputAwareWebView.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/CredentialContract.java" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/ThreadedInputConnectionProxyAdapterView.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/CredentialDao.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/CredentialDatabase.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/CredentialDatabaseHelper.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/ProtectionSpace.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/ProtectionSpaceContract.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabase/ProtectionSpaceDao.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/CredentialDatabaseHandler.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/ios/Classes/CredentialDatabase.swift" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebViewFactory.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebViewFactory.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebChromeClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebChromeClient.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewOptions.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewOptions.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/Util.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/Util.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/inline_example.screen.dart" 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/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/MyCookieManager.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/MyCookieManager.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/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/lib/src/cookie_manager.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/cookie_manager.dart" 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_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/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/types.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/types.dart" afterDir="false" />
|
||||||
|
@ -52,59 +66,11 @@
|
||||||
<component name="ExecutionTargetManager" SELECTED_TARGET="Pixel_3_XL_API_24" />
|
<component name="ExecutionTargetManager" SELECTED_TARGET="Pixel_3_XL_API_24" />
|
||||||
<component name="FileEditorManager">
|
<component name="FileEditorManager">
|
||||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||||
<file pinned="false" current-in-tab="true">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="557">
|
<state relative-caret-position="360">
|
||||||
<caret line="39" column="8" lean-forward="true" selection-start-line="39" selection-start-column="8" selection-end-line="39" selection-end-column="8" />
|
<caret line="24" column="42" selection-start-line="24" selection-start-column="42" selection-end-line="24" selection-end-column="42" />
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
</file>
|
|
||||||
<file pinned="false" current-in-tab="false">
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="150">
|
|
||||||
<caret line="10" column="22" selection-start-line="10" selection-start-column="22" selection-end-line="10" selection-end-column="22" />
|
|
||||||
<folding>
|
|
||||||
<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/lib/webview_example.screen.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="182">
|
|
||||||
<caret line="65" column="59" selection-start-line="65" selection-start-column="59" selection-end-line="65" selection-end-column="59" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#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">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="150">
|
|
||||||
<caret line="169" column="79" selection-start-line="169" selection-start-column="79" selection-end-line="169" selection-end-column="79" />
|
|
||||||
<folding>
|
|
||||||
<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$/lib/src/in_app_browser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="549">
|
|
||||||
<caret line="409" column="5" selection-start-line="409" selection-start-column="5" selection-end-line="409" selection-end-column="5" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -112,8 +78,8 @@
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="-453">
|
<state relative-caret-position="147">
|
||||||
<caret line="241" selection-start-line="241" selection-end-line="241" />
|
<caret line="327" column="89" selection-start-line="327" selection-start-column="89" selection-end-line="327" selection-end-column="89" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#32#0" expanded="true" />
|
<element signature="e#0#32#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -124,17 +90,50 @@
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="514">
|
<state relative-caret-position="416">
|
||||||
<caret line="73" column="12" selection-start-line="73" selection-start-column="12" selection-end-line="73" selection-end-column="12" />
|
<caret line="73" column="12" selection-start-line="73" selection-start-column="12" selection-end-line="73" selection-end-column="12" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
<file pinned="false" current-in-tab="false">
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-492">
|
||||||
|
<caret line="881" column="26" selection-start-line="881" selection-start-column="22" selection-end-line="881" selection-end-column="26" />
|
||||||
|
<folding>
|
||||||
|
<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$/lib/src/in_app_browser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="419">
|
||||||
|
<caret line="411" column="2" selection-start-line="411" selection-start-column="2" selection-end-line="411" selection-end-column="106" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/cookie_manager.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="395">
|
||||||
|
<caret line="61" column="51" selection-start-line="61" selection-start-column="21" selection-end-line="61" selection-end-column="51" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="1401">
|
<state relative-caret-position="253">
|
||||||
<caret line="222" column="12" selection-start-line="222" selection-start-column="12" selection-end-line="222" selection-end-column="12" />
|
<caret line="88" column="12" selection-start-line="88" selection-start-column="12" selection-end-line="88" selection-end-column="12" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#22#0" expanded="true" />
|
<element signature="e#0#22#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -142,6 +141,27 @@
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="256">
|
||||||
|
<caret line="43" column="9" selection-start-line="43" selection-start-column="9" selection-end-line="43" selection-end-column="9" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="60">
|
||||||
|
<caret line="4" column="32" selection-start-line="4" selection-start-column="6" selection-end-line="4" selection-end-column="32" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#10#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
</leaf>
|
</leaf>
|
||||||
</component>
|
</component>
|
||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
|
@ -154,16 +174,6 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="FindInProjectRecents">
|
<component name="FindInProjectRecents">
|
||||||
<findStrings>
|
<findStrings>
|
||||||
<find>defaultWebpagePreferences</find>
|
|
||||||
<find>contentBlockers</find>
|
|
||||||
<find>preferredContentMode</find>
|
|
||||||
<find>useOnLoadResource</find>
|
|
||||||
<find>safe</find>
|
|
||||||
<find>InAppWebViewController</find>
|
|
||||||
<find>safeBrowsingEnabled</find>
|
|
||||||
<find>only</find>
|
|
||||||
<find>///**NOTE**: available only for Android.</find>
|
|
||||||
<find>_inAppBrowser</find>
|
|
||||||
<find>_channel</find>
|
<find>_channel</find>
|
||||||
<find>uuid_</find>
|
<find>uuid_</find>
|
||||||
<find>javaScriptHandlersMap</find>
|
<find>javaScriptHandlersMap</find>
|
||||||
|
@ -182,8 +192,18 @@
|
||||||
<find>appCa</find>
|
<find>appCa</find>
|
||||||
<find>onSafeBrowsingHit</find>
|
<find>onSafeBrowsingHit</find>
|
||||||
<find>SafeBrowsingResponse</find>
|
<find>SafeBrowsingResponse</find>
|
||||||
<find>onReceivedHttpAuthRequest</find>
|
|
||||||
<find>iOSInAppWebViewUserPreferredContentMode</find>
|
<find>iOSInAppWebViewUserPreferredContentMode</find>
|
||||||
|
<find>getDomainName</find>
|
||||||
|
<find>a</find>
|
||||||
|
<find>as</find>
|
||||||
|
<find>IABWebViewClient</find>
|
||||||
|
<find>clearCache</find>
|
||||||
|
<find>Auth</find>
|
||||||
|
<find>onReceivedHttpAuthRequestCallback</find>
|
||||||
|
<find>onReceivedHttpAuthRequest</find>
|
||||||
|
<find>cast</find>
|
||||||
|
<find>Protection</find>
|
||||||
|
<find>clear</find>
|
||||||
</findStrings>
|
</findStrings>
|
||||||
<replaceStrings>
|
<replaceStrings>
|
||||||
<replace>activity.getPreferences(0)</replace>
|
<replace>activity.getPreferences(0)</replace>
|
||||||
|
@ -204,8 +224,6 @@
|
||||||
<component name="IdeDocumentHistory">
|
<component name="IdeDocumentHistory">
|
||||||
<option name="CHANGED_PATHS">
|
<option name="CHANGED_PATHS">
|
||||||
<list>
|
<list>
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_webview.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/example/ios/Flutter/Debug.xcconfig" />
|
|
||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowser.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowser.java" />
|
||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserClient.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserClient.java" />
|
||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserDialog.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserDialog.java" />
|
||||||
|
@ -236,10 +254,8 @@
|
||||||
<option value="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
<option value="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/in_app_localhost_server.dart" />
|
<option value="$PROJECT_DIR$/lib/src/in_app_localhost_server.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/channel_manager.dart" />
|
<option value="$PROJECT_DIR$/lib/src/channel_manager.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/cookie_manager.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/lib/src/web_history.dart" />
|
<option value="$PROJECT_DIR$/lib/src/web_history.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" />
|
<option value="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
||||||
|
@ -248,17 +264,21 @@
|
||||||
<option value="$PROJECT_DIR$/lib/src/content_blocker.dart" />
|
<option value="$PROJECT_DIR$/lib/src/content_blocker.dart" />
|
||||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
<option value="$PROJECT_DIR$/lib/src/cookie_manager.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
<option value="$PROJECT_DIR$/lib/src/credentials_database.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
<option value="$PROJECT_DIR$/lib/src/in_app_browser.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/src/http_auth_credentials_database.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds" extendedState="6">
|
<component name="ProjectFrameBounds">
|
||||||
<option name="y" value="23" />
|
<option name="y" value="23" />
|
||||||
<option name="width" value="1920" />
|
<option name="width" value="1920" />
|
||||||
<option name="height" value="1057" />
|
<option name="height" value="1057" />
|
||||||
|
@ -269,17 +289,6 @@
|
||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
<pane id="Scope">
|
|
||||||
<subPane subId="Project Files">
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="Root" type="cbb8eebc:String" user="Root" />
|
|
||||||
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</subPane>
|
|
||||||
</pane>
|
|
||||||
<pane id="AndroidView">
|
<pane id="AndroidView">
|
||||||
<subPane>
|
<subPane>
|
||||||
<expand>
|
<expand>
|
||||||
|
@ -322,6 +331,12 @@
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||||
</path>
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="assets" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
<path>
|
<path>
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
@ -347,6 +362,17 @@
|
||||||
<select />
|
<select />
|
||||||
</subPane>
|
</subPane>
|
||||||
</pane>
|
</pane>
|
||||||
|
<pane id="Scope">
|
||||||
|
<subPane subId="Project Files">
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="Root" type="cbb8eebc:String" user="Root" />
|
||||||
|
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
|
@ -358,7 +384,7 @@
|
||||||
<property name="android.project.structure.proportion" value="0.15" />
|
<property name="android.project.structure.proportion" value="0.15" />
|
||||||
<property name="dart.analysis.tool.window.force.activate" value="false" />
|
<property name="dart.analysis.tool.window.force.activate" value="false" />
|
||||||
<property name="io.flutter.reload.alreadyRun" value="true" />
|
<property name="io.flutter.reload.alreadyRun" value="true" />
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
<property name="last_opened_file_path" value="$PROJECT_DIR$/example/assets" />
|
||||||
<property name="project.structure.last.edited" value="SDK Location" />
|
<property name="project.structure.last.edited" value="SDK Location" />
|
||||||
<property name="project.structure.proportion" value="0.15" />
|
<property name="project.structure.proportion" value="0.15" />
|
||||||
<property name="project.structure.side.proportion" value="0.2" />
|
<property name="project.structure.side.proportion" value="0.2" />
|
||||||
|
@ -366,19 +392,19 @@
|
||||||
<property name="show.migrate.to.gradle.popup" value="false" />
|
<property name="show.migrate.to.gradle.popup" value="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/example/assets" />
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
<recent name="$PROJECT_DIR$/example" />
|
||||||
|
<recent name="$PROJECT_DIR$/example/assets/images" />
|
||||||
|
<recent name="$PROJECT_DIR$/android/libs" />
|
||||||
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/example/assets" />
|
||||||
<recent name="$PROJECT_DIR$/lib/src" />
|
<recent name="$PROJECT_DIR$/lib/src" />
|
||||||
<recent name="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
<recent name="$PROJECT_DIR$/lib/in_app_browser.dart" />
|
||||||
<recent name="$PROJECT_DIR$/lib" />
|
<recent name="$PROJECT_DIR$/lib" />
|
||||||
<recent name="$PROJECT_DIR$/example/assets/images" />
|
<recent name="$PROJECT_DIR$/example/assets/images" />
|
||||||
<recent name="$PROJECT_DIR$/android/src/main/java" />
|
|
||||||
</key>
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$" />
|
|
||||||
<recent name="$PROJECT_DIR$/example" />
|
|
||||||
<recent name="$PROJECT_DIR$/example/assets" />
|
|
||||||
<recent name="$PROJECT_DIR$/example/assets/images" />
|
|
||||||
<recent name="$PROJECT_DIR$/android/libs" />
|
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunDashboard">
|
<component name="RunDashboard">
|
||||||
|
@ -497,11 +523,11 @@
|
||||||
</todo-panel>
|
</todo-panel>
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="0" y="23" width="1920" height="1057" extended-state="6" />
|
<frame x="0" y="23" width="1920" height="1057" extended-state="0" />
|
||||||
<editor active="true" />
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.5961821" visible="true" weight="0.15867944" />
|
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.59210527" visible="true" weight="0.15867944" />
|
||||||
<window_info id="Structure" order="1" sideWeight="0.40381792" side_tool="true" visible="true" weight="0.15867944" />
|
<window_info id="Structure" order="1" sideWeight="0.40789473" side_tool="true" visible="true" weight="0.15867944" />
|
||||||
<window_info id="Designer" order="2" />
|
<window_info id="Designer" order="2" />
|
||||||
<window_info id="Build Variants" order="3" side_tool="true" />
|
<window_info id="Build Variants" order="3" side_tool="true" />
|
||||||
<window_info id="Captures" order="4" side_tool="true" weight="0.32936507" />
|
<window_info id="Captures" order="4" side_tool="true" weight="0.32936507" />
|
||||||
|
@ -511,7 +537,7 @@
|
||||||
<window_info id="Resources Explorer" order="8" />
|
<window_info id="Resources Explorer" order="8" />
|
||||||
<window_info anchor="bottom" id="Message" order="0" />
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
<window_info anchor="bottom" id="Find" order="1" weight="0.32642487" />
|
<window_info anchor="bottom" id="Find" order="1" weight="0.32642487" />
|
||||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49307775" weight="0.4580311" />
|
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49307775" visible="true" weight="0.5274611" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.34196892" />
|
<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="Cvs" order="4" weight="0.25" />
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
@ -519,7 +545,7 @@
|
||||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50692225" side_tool="true" weight="0.38445595" />
|
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50692225" side_tool="true" weight="0.38445595" />
|
||||||
<window_info anchor="bottom" id="Version Control" order="9" weight="0.32953367" />
|
<window_info anchor="bottom" id="Version Control" order="9" weight="0.32953367" />
|
||||||
<window_info active="true" anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" visible="true" weight="0.29430053" />
|
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.29430053" />
|
||||||
<window_info anchor="bottom" id="Logcat" order="11" weight="0.32953367" />
|
<window_info anchor="bottom" id="Logcat" order="11" weight="0.32953367" />
|
||||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.226943" />
|
<window_info anchor="bottom" id="Messages" order="12" weight="0.226943" />
|
||||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
||||||
|
@ -547,19 +573,6 @@
|
||||||
</ignored-roots>
|
</ignored-roots>
|
||||||
</component>
|
</component>
|
||||||
<component name="editorHistoryManager">
|
<component name="editorHistoryManager">
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/AppFrameworkInfo.plist">
|
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="211">
|
|
||||||
<caret line="453" column="10" selection-start-line="453" selection-start-column="10" selection-end-line="453" selection-end-column="10" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/.packages">
|
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/.idea/gradle.xml">
|
<entry file="file://$PROJECT_DIR$/android/.idea/gradle.xml">
|
||||||
<provider selected="true" editor-type-id="text-editor" />
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -697,13 +710,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/cookie_manager.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="2100">
|
|
||||||
<caret line="140" selection-start-line="140" selection-end-line="140" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/web_history.dart" />
|
<entry file="file://$PROJECT_DIR$/lib/src/web_history.dart" />
|
||||||
<entry file="file://$PROJECT_DIR$/README.md">
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
@ -738,23 +744,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="180">
|
|
||||||
<caret line="31" column="32" selection-start-line="31" selection-start-column="32" selection-end-line="31" selection-end-column="32" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/chrome_safari_browser.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="736">
|
|
||||||
<caret line="76" column="41" selection-start-line="76" selection-start-column="41" selection-end-line="76" selection-end-column="41" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="990">
|
<state relative-caret-position="990">
|
||||||
|
@ -807,53 +796,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="-453">
|
|
||||||
<caret line="241" selection-start-line="241" selection-end-line="241" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#32#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="1401">
|
|
||||||
<caret line="222" column="12" selection-start-line="222" selection-start-column="12" selection-end-line="222" selection-end-column="12" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#22#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="514">
|
|
||||||
<caret line="73" column="12" selection-start-line="73" selection-start-column="12" selection-end-line="73" selection-end-column="12" />
|
|
||||||
</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="549">
|
|
||||||
<caret line="409" column="5" selection-start-line="409" selection-start-column="5" selection-end-line="409" selection-end-column="5" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#20#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="150">
|
|
||||||
<caret line="169" column="79" selection-start-line="169" selection-start-column="79" selection-end-line="169" selection-end-column="79" />
|
|
||||||
<folding>
|
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="30">
|
<state relative-caret-position="30">
|
||||||
|
@ -861,10 +803,10 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="345">
|
<state relative-caret-position="195">
|
||||||
<caret line="23" column="28" selection-start-line="23" selection-start-column="28" selection-end-line="23" selection-end-column="28" />
|
<caret line="32" column="47" selection-start-line="32" selection-start-column="47" selection-end-line="32" selection-end-column="47" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -878,20 +820,111 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/chrome_safari_browser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="225">
|
||||||
|
<caret line="15" column="25" selection-start-line="15" selection-start-column="6" selection-end-line="15" selection-end-column="25" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="150">
|
<state relative-caret-position="4635">
|
||||||
<caret line="10" column="22" selection-start-line="10" selection-start-column="22" selection-end-line="10" selection-end-column="22" />
|
<caret line="309" column="1" selection-start-line="309" selection-start-column="1" selection-end-line="309" selection-end-column="1" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#17#0" expanded="true" />
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="419">
|
||||||
|
<caret line="411" column="2" selection-start-line="411" selection-start-column="2" selection-end-line="411" selection-end-column="106" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="416">
|
||||||
|
<caret line="73" column="12" selection-start-line="73" selection-start-column="12" selection-end-line="73" selection-end-column="12" />
|
||||||
|
</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="-492">
|
||||||
|
<caret line="881" column="26" selection-start-line="881" selection-start-column="22" selection-end-line="881" selection-end-column="26" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#17#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</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="395">
|
||||||
|
<caret line="61" column="51" selection-start-line="61" selection-start-column="21" selection-end-line="61" selection-end-column="51" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="147">
|
||||||
|
<caret line="327" column="89" selection-start-line="327" selection-start-column="89" selection-end-line="327" selection-end-column="89" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#32#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="557">
|
<state relative-caret-position="360">
|
||||||
<caret line="39" column="8" lean-forward="true" selection-start-line="39" selection-start-column="8" selection-end-line="39" selection-end-column="8" />
|
<caret line="24" column="42" selection-start-line="24" selection-start-column="42" selection-end-line="24" selection-end-column="42" />
|
||||||
|
</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="60">
|
||||||
|
<caret line="4" column="32" selection-start-line="4" selection-start-column="6" selection-end-line="4" selection-end-column="32" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#10#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.pem">
|
||||||
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/client1-crt.crt">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="72">
|
||||||
|
<caret line="11" column="57" lean-forward="true" selection-start-line="11" selection-start-column="57" selection-end-line="11" selection-end-column="57" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="256">
|
||||||
|
<caret line="43" column="9" selection-start-line="43" selection-start-column="9" selection-end-line="43" selection-end-column="9" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="253">
|
||||||
|
<caret line="88" column="12" selection-start-line="88" selection-start-column="12" selection-end-line="88" selection-end-column="12" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#22#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
|
@ -20,13 +20,16 @@
|
||||||
- Added `startSafeBrowsing`, `setSafeBrowsingWhitelist` and `getSafeBrowsingPrivacyPolicyUrl` methods (available only for Android)
|
- Added `startSafeBrowsing`, `setSafeBrowsingWhitelist` and `getSafeBrowsingPrivacyPolicyUrl` methods (available only for Android)
|
||||||
- Added `onSafeBrowsingHit` event (available only for Android)
|
- Added `onSafeBrowsingHit` event (available only for Android)
|
||||||
- Added `onJsAlert`, `onJsConfirm` and `onJsPrompt` events to manage javascript popup dialogs
|
- Added `onJsAlert`, `onJsConfirm` and `onJsPrompt` events to manage javascript popup dialogs
|
||||||
- Fixed `InputConnection` error on Android
|
- Added `onReceivedHttpAuthRequest` event
|
||||||
|
- Added `clearCache()` method
|
||||||
|
- Added `HttpAuthCredentialDatabase` class
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
- Deleted `WebResourceRequest` class
|
- Deleted `WebResourceRequest` class
|
||||||
- Updated `WebResourceResponse` class
|
- Updated `WebResourceResponse` class
|
||||||
- Updated `ConsoleMessageLevel` class
|
- Updated `ConsoleMessageLevel` class
|
||||||
- Updated `onLoadResource` event
|
- Updated `onLoadResource` event
|
||||||
|
- Updated `CookieManager` class
|
||||||
- WebView options are now available with the new corresponding classes: `InAppWebViewOptions`, `AndroidInAppWebViewOptions`, `iOSInAppWebViewOptions`, `InAppBrowserOptions`, `AndroidInAppBrowserOptions`, `iOSInAppBrowserOptions`, `AndroidChromeCustomTabsOptions` and `iOSChromeCustomTabsOptions`
|
- WebView options are now available with the new corresponding classes: `InAppWebViewOptions`, `AndroidInAppWebViewOptions`, `iOSInAppWebViewOptions`, `InAppBrowserOptions`, `AndroidInAppBrowserOptions`, `iOSInAppBrowserOptions`, `AndroidChromeCustomTabsOptions` and `iOSChromeCustomTabsOptions`
|
||||||
|
|
||||||
## 1.2.1
|
## 1.2.1
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Credential {
|
||||||
|
public Long id;
|
||||||
|
public String username;
|
||||||
|
public String password;
|
||||||
|
public Long protectionSpaceId;
|
||||||
|
|
||||||
|
public Credential (Long id, String username, String password, Long protectionSpaceId) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.protectionSpaceId = protectionSpaceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> credentialMap = new HashMap<>();
|
||||||
|
credentialMap.put("username", username);
|
||||||
|
credentialMap.put("password", password);
|
||||||
|
return credentialMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.provider.BaseColumns;
|
||||||
|
|
||||||
|
public class CredentialContract {
|
||||||
|
private CredentialContract() {}
|
||||||
|
|
||||||
|
/* Inner class that defines the table contents */
|
||||||
|
public static class FeedEntry implements BaseColumns {
|
||||||
|
public static final String TABLE_NAME = "credential";
|
||||||
|
public static final String COLUMN_NAME_USERNAME = "username";
|
||||||
|
public static final String COLUMN_NAME_PASSWORD = "password";
|
||||||
|
public static final String COLUMN_NAME_PROTECTION_SPACE_ID = "protection_space_id";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CredentialDao {
|
||||||
|
|
||||||
|
CredentialDatabaseHelper credentialDatabaseHelper;
|
||||||
|
String[] projection = {
|
||||||
|
CredentialContract.FeedEntry._ID,
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_USERNAME,
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD,
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
public CredentialDao(CredentialDatabaseHelper credentialDatabaseHelper) {
|
||||||
|
this.credentialDatabaseHelper = credentialDatabaseHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Credential> getAllByProtectionSpaceId(Long protectionSpaceId) {
|
||||||
|
String selection = CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
|
||||||
|
String[] selectionArgs = {protectionSpaceId.toString()};
|
||||||
|
|
||||||
|
Cursor cursor = credentialDatabaseHelper.getReadableDatabase().query(
|
||||||
|
CredentialContract.FeedEntry.TABLE_NAME,
|
||||||
|
projection,
|
||||||
|
selection,
|
||||||
|
selectionArgs,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Credential> credentials = new ArrayList<>();
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
Long id = cursor.getLong(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry._ID));
|
||||||
|
String username = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME));
|
||||||
|
String password = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD));
|
||||||
|
credentials.add(new Credential(id, username, password, protectionSpaceId));
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Credential find(String username, String password, Long protectionSpaceId) {
|
||||||
|
String selection = CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + " = ? AND " +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + " = ? AND " +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
|
||||||
|
String[] selectionArgs = {username, password, protectionSpaceId.toString()};
|
||||||
|
|
||||||
|
Cursor cursor = credentialDatabaseHelper.getReadableDatabase().query(
|
||||||
|
CredentialContract.FeedEntry.TABLE_NAME,
|
||||||
|
projection,
|
||||||
|
selection,
|
||||||
|
selectionArgs,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
Credential credential = null;
|
||||||
|
if (cursor.moveToNext()) {
|
||||||
|
Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry._ID));
|
||||||
|
String rowUsername = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME));
|
||||||
|
String rowPassword = cursor.getString(cursor.getColumnIndexOrThrow(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD));
|
||||||
|
credential = new Credential(rowId, rowUsername, rowPassword, protectionSpaceId);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
return credential;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long insert(Credential credential) {
|
||||||
|
ContentValues credentialValues = new ContentValues();
|
||||||
|
credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME, credential.username);
|
||||||
|
credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD, credential.password);
|
||||||
|
credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID, credential.protectionSpaceId);
|
||||||
|
|
||||||
|
return credentialDatabaseHelper.getWritableDatabase().insert(CredentialContract.FeedEntry.TABLE_NAME, null, credentialValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long update(Credential credential) {
|
||||||
|
ContentValues credentialValues = new ContentValues();
|
||||||
|
credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_USERNAME, credential.username);
|
||||||
|
credentialValues.put(CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD, credential.password);
|
||||||
|
|
||||||
|
String whereClause = CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " = ?";
|
||||||
|
String[] whereArgs = {credential.protectionSpaceId.toString()};
|
||||||
|
|
||||||
|
return credentialDatabaseHelper.getWritableDatabase().update(CredentialContract.FeedEntry.TABLE_NAME, credentialValues, whereClause, whereArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long delete(Credential credential) {
|
||||||
|
String whereClause = CredentialContract.FeedEntry._ID + " = ?";
|
||||||
|
String[] whereArgs = {credential.id.toString()};
|
||||||
|
|
||||||
|
return credentialDatabaseHelper.getWritableDatabase().delete(CredentialContract.FeedEntry.TABLE_NAME, whereClause, whereArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CredentialDatabase {
|
||||||
|
|
||||||
|
private static CredentialDatabase instance;
|
||||||
|
static final String LOG_TAG = "CredentialDatabase";
|
||||||
|
|
||||||
|
// If you change the database schema, you must increment the database version.
|
||||||
|
public static final int DATABASE_VERSION = 2;
|
||||||
|
public static final String DATABASE_NAME = "CredentialDatabase.db";
|
||||||
|
|
||||||
|
public ProtectionSpaceDao protectionSpaceDao;
|
||||||
|
public CredentialDao credentialDao;
|
||||||
|
public CredentialDatabaseHelper db;
|
||||||
|
|
||||||
|
private CredentialDatabase() {}
|
||||||
|
|
||||||
|
private CredentialDatabase(CredentialDatabaseHelper db, ProtectionSpaceDao protectionSpaceDao, CredentialDao credentialDao) {
|
||||||
|
this.db = db;
|
||||||
|
this.protectionSpaceDao = protectionSpaceDao;
|
||||||
|
this.credentialDao = credentialDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CredentialDatabase getInstance(Context context) {
|
||||||
|
if (instance != null)
|
||||||
|
return instance;
|
||||||
|
CredentialDatabaseHelper db = new CredentialDatabaseHelper(context);
|
||||||
|
instance = new CredentialDatabase(db, new ProtectionSpaceDao(db), new CredentialDao(db));
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Credential> getHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
|
||||||
|
List<Credential> credentialList = new ArrayList<>();
|
||||||
|
ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
|
||||||
|
if (protectionSpace != null) {
|
||||||
|
credentialList = credentialDao.getAllByProtectionSpaceId(protectionSpace.id);
|
||||||
|
}
|
||||||
|
return credentialList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllAuthCredentials() {
|
||||||
|
db.clearAllTables(db.getWritableDatabase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeHttpAuthCredentials(String host, String protocol, String realm, Integer port) {
|
||||||
|
ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
|
||||||
|
if (protectionSpace != null) {
|
||||||
|
protectionSpaceDao.delete(protectionSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
|
||||||
|
ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
|
||||||
|
if (protectionSpace != null) {
|
||||||
|
credentialDao.find(username, password, protectionSpace.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpAuthCredential(String host, String protocol, String realm, Integer port, String username, String password) {
|
||||||
|
ProtectionSpace protectionSpace = protectionSpaceDao.find(host, protocol, realm, port);
|
||||||
|
Long protectionSpaceId;
|
||||||
|
if (protectionSpace == null) {
|
||||||
|
protectionSpaceId = protectionSpaceDao.insert(new ProtectionSpace(null, host, protocol, realm, port));
|
||||||
|
} else {
|
||||||
|
protectionSpaceId = protectionSpace.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Credential credential = credentialDao.find(username, password, protectionSpaceId);
|
||||||
|
if (credential != null) {
|
||||||
|
boolean needUpdate = false;
|
||||||
|
if (!credential.username.equals(username)) {
|
||||||
|
credential.username = username;
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
if (!credential.password.equals(password)) {
|
||||||
|
credential.password = password;
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
if (needUpdate)
|
||||||
|
credentialDao.update(credential);
|
||||||
|
} else {
|
||||||
|
credential = new Credential(null, username, password, protectionSpaceId);
|
||||||
|
credential.id = credentialDao.insert(credential);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
|
||||||
|
public class CredentialDatabaseHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
private static final String SQL_CREATE_PROTECTION_SPACE_TABLE =
|
||||||
|
"CREATE TABLE " + ProtectionSpaceContract.FeedEntry.TABLE_NAME + " (" +
|
||||||
|
ProtectionSpaceContract.FeedEntry._ID + " INTEGER PRIMARY KEY," +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + " TEXT NOT NULL," +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + " TEXT," +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + " TEXT," +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT + " INTEGER," +
|
||||||
|
"UNIQUE(" + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + ", " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + ", " +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + ", " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT +
|
||||||
|
")" +
|
||||||
|
");";
|
||||||
|
|
||||||
|
private static final String SQL_CREATE_CREDENTIAL_TABLE =
|
||||||
|
"CREATE TABLE " + CredentialContract.FeedEntry.TABLE_NAME + " (" +
|
||||||
|
CredentialContract.FeedEntry._ID + " INTEGER PRIMARY KEY," +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + " TEXT NOT NULL," +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + " TEXT NOT NULL," +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + " INTEGER NOT NULL," +
|
||||||
|
"UNIQUE(" + CredentialContract.FeedEntry.COLUMN_NAME_USERNAME + ", " + CredentialContract.FeedEntry.COLUMN_NAME_PASSWORD + ", " +
|
||||||
|
CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID +
|
||||||
|
")," +
|
||||||
|
"FOREIGN KEY (" + CredentialContract.FeedEntry.COLUMN_NAME_PROTECTION_SPACE_ID + ") REFERENCES " +
|
||||||
|
ProtectionSpaceContract.FeedEntry.TABLE_NAME + " (" + ProtectionSpaceContract.FeedEntry._ID + ") ON DELETE CASCADE" +
|
||||||
|
");";
|
||||||
|
|
||||||
|
private static final String SQL_DELETE_PROTECTION_SPACE_TABLE =
|
||||||
|
"DROP TABLE IF EXISTS " + ProtectionSpaceContract.FeedEntry.TABLE_NAME;
|
||||||
|
|
||||||
|
private static final String SQL_DELETE_CREDENTIAL_TABLE =
|
||||||
|
"DROP TABLE IF EXISTS " + CredentialContract.FeedEntry.TABLE_NAME;
|
||||||
|
|
||||||
|
public CredentialDatabaseHelper(Context context) {
|
||||||
|
super(context, CredentialDatabase.DATABASE_NAME, null, CredentialDatabase.DATABASE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
db.execSQL(SQL_CREATE_PROTECTION_SPACE_TABLE);
|
||||||
|
db.execSQL(SQL_CREATE_CREDENTIAL_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
// This database is only a cache for online data, so its upgrade policy is
|
||||||
|
// to simply to discard the data and start over
|
||||||
|
db.execSQL(SQL_DELETE_PROTECTION_SPACE_TABLE);
|
||||||
|
db.execSQL(SQL_DELETE_CREDENTIAL_TABLE);
|
||||||
|
onCreate(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
onUpgrade(db, oldVersion, newVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllTables(SQLiteDatabase db) {
|
||||||
|
db.execSQL(SQL_DELETE_PROTECTION_SPACE_TABLE);
|
||||||
|
db.execSQL(SQL_DELETE_CREDENTIAL_TABLE);
|
||||||
|
onCreate(db);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ProtectionSpace {
|
||||||
|
public Long id;
|
||||||
|
public String host;
|
||||||
|
public String procotol;
|
||||||
|
public String realm;
|
||||||
|
public Integer port;
|
||||||
|
|
||||||
|
public ProtectionSpace (Long id, String host, String protocol, String realm, Integer port) {
|
||||||
|
this.id = id;
|
||||||
|
this.host = host;
|
||||||
|
this.procotol = protocol;
|
||||||
|
this.realm = realm;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> protectionSpaceMap = new HashMap<>();
|
||||||
|
protectionSpaceMap.put("host", host);
|
||||||
|
protectionSpaceMap.put("protocol", procotol);
|
||||||
|
protectionSpaceMap.put("realm", realm);
|
||||||
|
protectionSpaceMap.put("port", port);
|
||||||
|
return protectionSpaceMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.provider.BaseColumns;
|
||||||
|
|
||||||
|
public class ProtectionSpaceContract {
|
||||||
|
private ProtectionSpaceContract() {}
|
||||||
|
|
||||||
|
/* Inner class that defines the table contents */
|
||||||
|
public static class FeedEntry implements BaseColumns {
|
||||||
|
public static final String TABLE_NAME = "protection_space";
|
||||||
|
public static final String COLUMN_NAME_HOST = "host";
|
||||||
|
public static final String COLUMN_NAME_PROTOCOL = "protocol";
|
||||||
|
public static final String COLUMN_NAME_REALM = "realm";
|
||||||
|
public static final String COLUMN_NAME_PORT = "port";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase;
|
||||||
|
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProtectionSpaceDao {
|
||||||
|
CredentialDatabaseHelper credentialDatabaseHelper;
|
||||||
|
String[] projection = {
|
||||||
|
ProtectionSpaceContract.FeedEntry._ID,
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST,
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL,
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM,
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT
|
||||||
|
};
|
||||||
|
|
||||||
|
public ProtectionSpaceDao(CredentialDatabaseHelper credentialDatabaseHelper) {
|
||||||
|
this.credentialDatabaseHelper = credentialDatabaseHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProtectionSpace> getAll() {
|
||||||
|
SQLiteDatabase readableDatabase = credentialDatabaseHelper.getReadableDatabase();
|
||||||
|
|
||||||
|
Cursor cursor = readableDatabase.query(
|
||||||
|
ProtectionSpaceContract.FeedEntry.TABLE_NAME,
|
||||||
|
projection,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
List<ProtectionSpace> protectionSpaces = new ArrayList<>();
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry._ID));
|
||||||
|
String rowHost = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST));
|
||||||
|
String rowProtocol = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL));
|
||||||
|
String rowRealm = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM));
|
||||||
|
Integer rowPort = cursor.getInt(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT));
|
||||||
|
protectionSpaces.add(new ProtectionSpace(rowId, rowHost, rowProtocol, rowRealm, rowPort));
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
return protectionSpaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtectionSpace find(String host, String protocol, String realm, Integer port) {
|
||||||
|
SQLiteDatabase readableDatabase = credentialDatabaseHelper.getReadableDatabase();
|
||||||
|
|
||||||
|
String selection = ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST + " = ? AND " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL + " = ? AND " +
|
||||||
|
ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM + " = ? AND " + ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT + " = ?";
|
||||||
|
String[] selectionArgs = {host, protocol, realm, port.toString()};
|
||||||
|
|
||||||
|
Cursor cursor = readableDatabase.query(
|
||||||
|
ProtectionSpaceContract.FeedEntry.TABLE_NAME,
|
||||||
|
projection,
|
||||||
|
selection,
|
||||||
|
selectionArgs,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
ProtectionSpace protectionSpace = null;
|
||||||
|
if (cursor.moveToNext()) {
|
||||||
|
Long rowId = cursor.getLong(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry._ID));
|
||||||
|
String rowHost = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST));
|
||||||
|
String rowProtocol = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL));
|
||||||
|
String rowRealm = cursor.getString(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM));
|
||||||
|
Integer rowPort = cursor.getInt(cursor.getColumnIndexOrThrow(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT));
|
||||||
|
protectionSpace = new ProtectionSpace(rowId, rowHost, rowProtocol, rowRealm, rowPort);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
return protectionSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long insert(ProtectionSpace protectionSpace) {
|
||||||
|
ContentValues protectionSpaceValues = new ContentValues();
|
||||||
|
protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_HOST, protectionSpace.host);
|
||||||
|
protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PROTOCOL, protectionSpace.procotol);
|
||||||
|
protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_REALM, protectionSpace.realm);
|
||||||
|
protectionSpaceValues.put(ProtectionSpaceContract.FeedEntry.COLUMN_NAME_PORT, protectionSpace.port);
|
||||||
|
|
||||||
|
return credentialDatabaseHelper.getWritableDatabase().insert(ProtectionSpaceContract.FeedEntry.TABLE_NAME, null, protectionSpaceValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
public long delete(ProtectionSpace protectionSpace) {
|
||||||
|
String whereClause = ProtectionSpaceContract.FeedEntry._ID + " = ?";
|
||||||
|
String[] whereArgs = {protectionSpace.id.toString()};
|
||||||
|
|
||||||
|
return credentialDatabaseHelper.getWritableDatabase().delete(ProtectionSpaceContract.FeedEntry.TABLE_NAME, whereClause, whereArgs);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappbrowser;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase.Credential;
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase.CredentialDatabase;
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase.ProtectionSpace;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.flutter.plugin.common.MethodCall;
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
import io.flutter.plugin.common.PluginRegistry;
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
|
static final String LOG_TAG = "CredentialDatabaseHandler";
|
||||||
|
|
||||||
|
public static PluginRegistry.Registrar registrar;
|
||||||
|
public static MethodChannel channel;
|
||||||
|
public static CredentialDatabase credentialDatabase;
|
||||||
|
|
||||||
|
public CredentialDatabaseHandler(PluginRegistry.Registrar r) {
|
||||||
|
registrar = r;
|
||||||
|
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser_credential_database");
|
||||||
|
channel.setMethodCallHandler(this);
|
||||||
|
credentialDatabase = CredentialDatabase.getInstance(registrar.context());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
|
||||||
|
switch (call.method) {
|
||||||
|
case "getAllAuthCredentials":
|
||||||
|
{
|
||||||
|
List<Map<String, Object>> allCredentials = new ArrayList<>();
|
||||||
|
List<ProtectionSpace> protectionSpaces = credentialDatabase.protectionSpaceDao.getAll();
|
||||||
|
for (ProtectionSpace protectionSpace : protectionSpaces) {
|
||||||
|
List<Map<String, Object>> credentials = new ArrayList<>();
|
||||||
|
for (Credential credential : credentialDatabase.credentialDao.getAllByProtectionSpaceId(protectionSpace.id)) {
|
||||||
|
credentials.add(credential.toMap());
|
||||||
|
}
|
||||||
|
Map<String, Object> obj = new HashMap<>();
|
||||||
|
obj.put("protectionSpace", protectionSpace.toMap());
|
||||||
|
obj.put("credentials", credentials);
|
||||||
|
allCredentials.add(obj);
|
||||||
|
}
|
||||||
|
result.success(allCredentials);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "getHttpAuthCredentials":
|
||||||
|
{
|
||||||
|
String host = (String) call.argument("host");
|
||||||
|
String protocol = (String) call.argument("protocol");
|
||||||
|
String realm = (String) call.argument("realm");
|
||||||
|
Integer port = (Integer) call.argument("port");
|
||||||
|
|
||||||
|
List<Map<String, Object>> credentials = new ArrayList<>();
|
||||||
|
for (Credential credential : credentialDatabase.getHttpAuthCredentials(host, protocol, realm, port)) {
|
||||||
|
credentials.add(credential.toMap());
|
||||||
|
}
|
||||||
|
result.success(credentials);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "setHttpAuthCredential":
|
||||||
|
{
|
||||||
|
String host = (String) call.argument("host");
|
||||||
|
String protocol = (String) call.argument("protocol");
|
||||||
|
String realm = (String) call.argument("realm");
|
||||||
|
Integer port = (Integer) call.argument("port");
|
||||||
|
String username = (String) call.argument("username");
|
||||||
|
String password = (String) call.argument("password");
|
||||||
|
|
||||||
|
credentialDatabase.setHttpAuthCredential(host, protocol, realm, port, username, password);
|
||||||
|
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "removeHttpAuthCredential":
|
||||||
|
{
|
||||||
|
String host = (String) call.argument("host");
|
||||||
|
String protocol = (String) call.argument("protocol");
|
||||||
|
String realm = (String) call.argument("realm");
|
||||||
|
Integer port = (Integer) call.argument("port");
|
||||||
|
String username = (String) call.argument("username");
|
||||||
|
String password = (String) call.argument("password");
|
||||||
|
|
||||||
|
credentialDatabase.removeHttpAuthCredential(host, protocol, realm, port, username, password);
|
||||||
|
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "removeHttpAuthCredentials":
|
||||||
|
{
|
||||||
|
String host = (String) call.argument("host");
|
||||||
|
String protocol = (String) call.argument("protocol");
|
||||||
|
String realm = (String) call.argument("realm");
|
||||||
|
Integer port = (Integer) call.argument("port");
|
||||||
|
|
||||||
|
credentialDatabase.removeHttpAuthCredentials(host, protocol, realm, port);
|
||||||
|
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "clearAllAuthCredentials":
|
||||||
|
credentialDatabase.clearAllAuthCredentials();
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.notImplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -245,6 +245,11 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
||||||
} else
|
} else
|
||||||
result.success(null);
|
result.success(null);
|
||||||
break;
|
break;
|
||||||
|
case "clearCache":
|
||||||
|
if (webView != null)
|
||||||
|
webView.clearAllCache();
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
case "dispose":
|
case "dispose":
|
||||||
dispose();
|
dispose();
|
||||||
result.success(true);
|
result.success(true);
|
||||||
|
|
|
@ -474,4 +474,9 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
||||||
else
|
else
|
||||||
result.success(false);
|
result.success(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearCache() {
|
||||||
|
if (webView != null)
|
||||||
|
webView.clearAllCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
package com.pichillilorenzo.flutter_inappbrowser;
|
package com.pichillilorenzo.flutter_inappbrowser;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.Browser;
|
import android.provider.Browser;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -45,7 +45,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.app.FlutterApplication;
|
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||||
|
@ -82,6 +81,9 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
||||||
instance = new InAppBrowserFlutterPlugin(registrar);
|
instance = new InAppBrowserFlutterPlugin(registrar);
|
||||||
|
|
||||||
new MyCookieManager(registrar);
|
new MyCookieManager(registrar);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
new CredentialDatabaseHandler(registrar);
|
||||||
|
}
|
||||||
|
|
||||||
registrar
|
registrar
|
||||||
.platformViewRegistry()
|
.platformViewRegistry()
|
||||||
|
@ -305,6 +307,10 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
||||||
case "setSafeBrowsingWhitelist":
|
case "setSafeBrowsingWhitelist":
|
||||||
setSafeBrowsingWhitelist(uuid, (List<String>) call.argument("hosts"), result);
|
setSafeBrowsingWhitelist(uuid, (List<String>) call.argument("hosts"), result);
|
||||||
break;
|
break;
|
||||||
|
case "clearCache":
|
||||||
|
clearCache(uuid);
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
}
|
}
|
||||||
|
@ -687,4 +693,10 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
||||||
inAppBrowserActivity.setSafeBrowsingWhitelist(hosts, result);
|
inAppBrowserActivity.setSafeBrowsingWhitelist(hosts, result);
|
||||||
result.success(false);
|
result.success(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearCache(String uuid) {
|
||||||
|
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||||
|
if (inAppBrowserActivity != null)
|
||||||
|
inAppBrowserActivity.clearCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
@ -9,9 +7,6 @@ import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.ConsoleMessage;
|
import android.webkit.ConsoleMessage;
|
||||||
|
@ -31,8 +26,6 @@ import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.R;
|
import com.pichillilorenzo.flutter_inappbrowser.R;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.RequestPermissionHandler;
|
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.Util;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.http.SslError;
|
import android.net.http.SslError;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.webkit.ClientCertRequest;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.CookieSyncManager;
|
import android.webkit.CookieSyncManager;
|
||||||
import android.webkit.HttpAuthHandler;
|
import android.webkit.HttpAuthHandler;
|
||||||
|
@ -17,29 +19,48 @@ import android.webkit.WebResourceRequest;
|
||||||
import android.webkit.WebResourceResponse;
|
import android.webkit.WebResourceResponse;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import android.webkit.WebViewDatabase;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase.Credential;
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.CredentialDatabase.CredentialDatabase;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
|
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.JavaScriptBridgeInterface;
|
import com.pichillilorenzo.flutter_inappbrowser.JavaScriptBridgeInterface;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.Util;
|
import com.pichillilorenzo.flutter_inappbrowser.Util;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
public class InAppWebViewClient extends WebViewClient {
|
public class InAppWebViewClient extends WebViewClient {
|
||||||
|
|
||||||
|
private X509Certificate[] mCertificates;
|
||||||
|
private PrivateKey mPrivateKey;
|
||||||
|
|
||||||
|
|
||||||
protected static final String LOG_TAG = "IABWebViewClient";
|
protected static final String LOG_TAG = "IABWebViewClient";
|
||||||
private FlutterWebView flutterWebView;
|
private FlutterWebView flutterWebView;
|
||||||
private InAppBrowserActivity inAppBrowserActivity;
|
private InAppBrowserActivity inAppBrowserActivity;
|
||||||
Map<Integer, String> statusCodeMapping = new HashMap<Integer, String>();
|
Map<Integer, String> statusCodeMapping = new HashMap<Integer, String>();
|
||||||
long startPageTime = 0;
|
long startPageTime = 0;
|
||||||
|
private static int previousAuthRequestFailureCount = 0;
|
||||||
|
private static List<Credential> credentialsProposed = null;
|
||||||
|
|
||||||
public InAppWebViewClient(Object obj) {
|
public InAppWebViewClient(Object obj) {
|
||||||
super();
|
super();
|
||||||
|
@ -50,7 +71,7 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
prepareStatusCodeMapping();
|
prepareStatusCodeMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareStatusCodeMapping () {
|
private void prepareStatusCodeMapping() {
|
||||||
statusCodeMapping.put(100, "Continue");
|
statusCodeMapping.put(100, "Continue");
|
||||||
statusCodeMapping.put(101, "Switching Protocols");
|
statusCodeMapping.put(101, "Switching Protocols");
|
||||||
statusCodeMapping.put(200, "OK");
|
statusCodeMapping.put(200, "OK");
|
||||||
|
@ -167,7 +188,6 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.shouldOverrideUrlLoading(webView, url);
|
return super.shouldOverrideUrlLoading(webView, url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,6 +228,8 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
super.onPageFinished(view, url);
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
webView.isLoading = false;
|
webView.isLoading = false;
|
||||||
|
previousAuthRequestFailureCount = 0;
|
||||||
|
credentialsProposed = null;
|
||||||
|
|
||||||
// CB-10395 InAppBrowserFlutterPlugin's WebView not storing cookies reliable to local device storage
|
// CB-10395 InAppBrowserFlutterPlugin's WebView not storing cookies reliable to local device storage
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
@ -229,11 +251,10 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
view.loadUrl("javascript:" + InAppWebView.consoleLogJS);
|
||||||
view.loadUrl("javascript:"+InAppWebView.consoleLogJS);
|
view.loadUrl("javascript:" + JavaScriptBridgeInterface.flutterInAppBroserJSClass);
|
||||||
view.loadUrl("javascript:"+JavaScriptBridgeInterface.flutterInAppBroserJSClass);
|
view.loadUrl("javascript:" + InAppWebView.platformReadyJS);
|
||||||
view.loadUrl("javascript:"+InAppWebView.platformReadyJS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
|
@ -247,6 +268,8 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
super.onReceivedError(view, errorCode, description, failingUrl);
|
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||||
|
|
||||||
((inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView).isLoading = false;
|
((inAppBrowserActivity != null) ? inAppBrowserActivity.webView : flutterWebView.webView).isLoading = false;
|
||||||
|
previousAuthRequestFailureCount = 0;
|
||||||
|
credentialsProposed = null;
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
if (inAppBrowserActivity != null)
|
if (inAppBrowserActivity != null)
|
||||||
|
@ -258,7 +281,8 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||||
super.onReceivedSslError(view, handler, error);
|
previousAuthRequestFailureCount = 0;
|
||||||
|
credentialsProposed = null;
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
if (inAppBrowserActivity != null)
|
if (inAppBrowserActivity != null)
|
||||||
|
@ -291,6 +315,7 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
getChannel().invokeMethod("onLoadError", obj);
|
getChannel().invokeMethod("onLoadError", obj);
|
||||||
|
|
||||||
handler.cancel();
|
handler.cancel();
|
||||||
|
//handler.proceed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -298,11 +323,34 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceivedHttpAuthRequest(final WebView view, final HttpAuthHandler handler, final String host, final String realm) {
|
public void onReceivedHttpAuthRequest(final WebView view, final HttpAuthHandler handler, final String host, final String realm) {
|
||||||
|
|
||||||
|
URL url;
|
||||||
|
try {
|
||||||
|
url = new URL(view.getUrl());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(LOG_TAG, e.getMessage());
|
||||||
|
|
||||||
|
credentialsProposed = null;
|
||||||
|
previousAuthRequestFailureCount = 0;
|
||||||
|
|
||||||
|
handler.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String protocol = url.getProtocol();
|
||||||
|
final int port = url.getPort();
|
||||||
|
|
||||||
|
previousAuthRequestFailureCount++;
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
if (inAppBrowserActivity != null)
|
if (inAppBrowserActivity != null)
|
||||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||||
obj.put("host", host);
|
obj.put("host", host);
|
||||||
|
obj.put("protocol", protocol);
|
||||||
obj.put("realm", realm);
|
obj.put("realm", realm);
|
||||||
|
obj.put("port", port);
|
||||||
|
obj.put("previousFailureCount", previousAuthRequestFailureCount);
|
||||||
|
|
||||||
getChannel().invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() {
|
getChannel().invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -310,12 +358,11 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
Map<String, Object> responseMap = (Map<String, Object>) response;
|
Map<String, Object> responseMap = (Map<String, Object>) response;
|
||||||
Integer action = (Integer) responseMap.get("action");
|
Integer action = (Integer) responseMap.get("action");
|
||||||
|
|
||||||
Log.d(LOG_TAG, "\n\naction: " + action);
|
|
||||||
|
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 0:
|
case 0:
|
||||||
|
credentialsProposed = null;
|
||||||
|
previousAuthRequestFailureCount = 0;
|
||||||
handler.cancel();
|
handler.cancel();
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -323,12 +370,20 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
String password = (String) responseMap.get("password");
|
String password = (String) responseMap.get("password");
|
||||||
Boolean permanentPersistence = (Boolean) responseMap.get("permanentPersistence");
|
Boolean permanentPersistence = (Boolean) responseMap.get("permanentPersistence");
|
||||||
if (permanentPersistence != null && permanentPersistence && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (permanentPersistence != null && permanentPersistence && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
WebViewDatabase.getInstance(view.getContext()).setHttpAuthUsernamePassword(host, realm, username, password);
|
CredentialDatabase.getInstance(view.getContext()).setHttpAuthCredential(host, protocol, realm, port, username, password);
|
||||||
}
|
}
|
||||||
handler.proceed(username, password);
|
handler.proceed(username, password);
|
||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
handler.useHttpAuthUsernamePassword();
|
if (credentialsProposed == null)
|
||||||
|
credentialsProposed = CredentialDatabase.getInstance(view.getContext()).getHttpAuthCredentials(host, protocol, realm, port);
|
||||||
|
if (credentialsProposed.size() > 0) {
|
||||||
|
Credential credential = credentialsProposed.remove(0);
|
||||||
|
handler.proceed(credential.username, credential.password);
|
||||||
|
} else {
|
||||||
|
handler.cancel();
|
||||||
|
}
|
||||||
|
//handler.useHttpAuthUsernamePassword();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,6 +404,50 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private void loadCertificateAndPrivateKey(InAppWebView webView) {
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// String key1 = webView.registrar.lookupKeyForAsset("assets/certificate.pfx");
|
||||||
|
// AssetManager mg = webView.registrar.activeContext().getResources().getAssets();
|
||||||
|
// InputStream certificateFileStream = mg.open(key1);//getClass().getResourceAsStream();
|
||||||
|
//
|
||||||
|
// KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||||
|
// String password = "";
|
||||||
|
// keyStore.load(certificateFileStream, password != null ? password.toCharArray() : null);
|
||||||
|
//
|
||||||
|
// Enumeration<String> aliases = keyStore.aliases();
|
||||||
|
// String alias = aliases.nextElement();
|
||||||
|
//
|
||||||
|
// Key key = keyStore.getKey(alias, password.toCharArray());
|
||||||
|
// if (key instanceof PrivateKey) {
|
||||||
|
// mPrivateKey = (PrivateKey)key;
|
||||||
|
// Certificate cert = keyStore.getCertificate(alias);
|
||||||
|
// mCertificates = new X509Certificate[1];
|
||||||
|
// mCertificates[0] = (X509Certificate)cert;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// certificateFileStream.close();
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// Log.e(LOG_TAG, e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
// @Override
|
||||||
|
// public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
|
||||||
|
// Log.d(LOG_TAG, request.getHost());
|
||||||
|
// Log.d(LOG_TAG, request.getKeyTypes().toString());
|
||||||
|
// Log.d(LOG_TAG, request.getPort() + "");
|
||||||
|
// Log.d(LOG_TAG, request.getPrincipals().toString());
|
||||||
|
//
|
||||||
|
// if (mCertificates == null || mPrivateKey == null) {
|
||||||
|
// loadCertificateAndPrivateKey((InAppWebView) view);
|
||||||
|
// }
|
||||||
|
// request.proceed(mPrivateKey, mCertificates);
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScaleChanged(WebView view, float oldScale, float newScale) {
|
public void onScaleChanged(WebView view, float oldScale, float newScale) {
|
||||||
final InAppWebView webView = (InAppWebView) view;
|
final InAppWebView webView = (InAppWebView) view;
|
||||||
|
@ -449,11 +548,13 @@ public class InAppWebViewClient extends WebViewClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
WebResourceResponse response = null;
|
WebResourceResponse response = null;
|
||||||
try {
|
if (webView.contentBlockerHandler.getRuleList().size() > 0) {
|
||||||
response = webView.contentBlockerHandler.checkUrl(webView, url);
|
try {
|
||||||
} catch (Exception e) {
|
response = webView.contentBlockerHandler.checkUrl(webView, url);
|
||||||
e.printStackTrace();
|
} catch (Exception e) {
|
||||||
Log.e(LOG_TAG, e.getMessage());
|
e.printStackTrace();
|
||||||
|
Log.e(LOG_TAG, e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ public class Util {
|
||||||
static final String LOG_TAG = "Util";
|
static final String LOG_TAG = "Util";
|
||||||
public static final String ANDROID_ASSET_URL = "file:///android_asset/";
|
public static final String ANDROID_ASSET_URL = "file:///android_asset/";
|
||||||
|
|
||||||
|
private Util() {}
|
||||||
|
|
||||||
public static String getUrlAsset(PluginRegistry.Registrar registrar, String assetFilePath) throws IOException {
|
public static String getUrlAsset(PluginRegistry.Registrar registrar, String assetFilePath) throws IOException {
|
||||||
String key = registrar.lookupKeyForAsset(assetFilePath);
|
String key = registrar.lookupKeyForAsset(assetFilePath);
|
||||||
AssetManager mg = registrar.activeContext().getResources().getAssets();
|
AssetManager mg = registrar.activeContext().getResources().getAssets();
|
||||||
|
|
|
@ -40,7 +40,7 @@ class _ChromeSafariExampleScreenState extends State<ChromeSafariExampleScreen> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await widget.browser.open("https://flutter.dev/", options: [
|
await widget.browser.open("https://flutter.dev/", options: [
|
||||||
AndroidChromeCustomTabsOptions(addShareButton: false),
|
AndroidChromeCustomTabsOptions(addShareButton: false),
|
||||||
iOSChromeCustomTabsOptions(barCollapsingEnabled: true)
|
iOSSafariOptions(barCollapsingEnabled: true)
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
child: Text("Open Chrome Safari Browser")),
|
child: Text("Open Chrome Safari Browser")),
|
||||||
|
|
|
@ -46,6 +46,24 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// HttpAuthCredentialDatabase.instance().clearAllAuthCredentials();
|
||||||
|
//
|
||||||
|
// HttpAuthCredentialDatabase.instance().getHttpAuthCredentials(ProtectionSpace(host: "192.168.1.20", protocol: "http", realm: "Node", port: 8081)).then((credentials) {
|
||||||
|
// for (var credential in credentials )
|
||||||
|
// print("\n\nCREDENTIAL: ${credential.username} ${credential.password}\n\n");
|
||||||
|
// });
|
||||||
|
// HttpAuthCredentialDatabase.instance().getAllAuthCredentials().then((result) {
|
||||||
|
// for (var r in result) {
|
||||||
|
// ProtectionSpace protectionSpace = r["protectionSpace"];
|
||||||
|
// print("\n\nProtectionSpace: ${protectionSpace.protocol} ${protectionSpace.host}:");
|
||||||
|
// List<HttpAuthCredential> credentials = r["credentials"];
|
||||||
|
// for (var credential in credentials)
|
||||||
|
// print("\tCREDENTIAL: ${credential.username} ${credential.password}");
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// HttpAuthCredentialDatabase.instance().setHttpAuthCredential(ProtectionSpace(host: "192.168.1.20", protocol: "http", realm: "Node", port: 8081), HttpAuthCredential(username: "user 1", password: "password 1"));
|
||||||
|
// HttpAuthCredentialDatabase.instance().setHttpAuthCredential(ProtectionSpace(host: "192.168.1.20", protocol: "http", realm: "Node", port: 8081), HttpAuthCredential(username: "user 2", password: "password 2"));
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
|
@ -66,11 +84,13 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
//initialUrl: "https://www.youtube.com/embed/M7lc1UVf-VE?playsinline=1",
|
//initialUrl: "https://www.youtube.com/embed/M7lc1UVf-VE?playsinline=1",
|
||||||
//initialUrl: "https://flutter.dev/",
|
//initialUrl: "https://flutter.dev/",
|
||||||
//initialUrl: "chrome://safe-browsing/match?type=malware",
|
//initialUrl: "chrome://safe-browsing/match?type=malware",
|
||||||
|
//initialUrl: "http://192.168.1.20:8081/",
|
||||||
|
//initialUrl: "https://192.168.1.20:4433/authenticate",
|
||||||
initialFile: "assets/index.html",
|
initialFile: "assets/index.html",
|
||||||
initialHeaders: {},
|
initialHeaders: {},
|
||||||
initialOptions: [
|
initialOptions: [
|
||||||
InAppWebViewOptions(
|
InAppWebViewOptions(
|
||||||
clearCache: true,
|
//clearCache: true,
|
||||||
useShouldOverrideUrlLoading: true,
|
useShouldOverrideUrlLoading: true,
|
||||||
useOnTargetBlank: true,
|
useOnTargetBlank: true,
|
||||||
//useOnLoadResource: true,
|
//useOnLoadResource: true,
|
||||||
|
@ -152,12 +172,12 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
""");
|
""");
|
||||||
},
|
},
|
||||||
onDownloadStart: (InAppWebViewController controller, String url) async {
|
onDownloadStart: (InAppWebViewController controller, String url) async {
|
||||||
/*final taskId = await FlutterDownloader.enqueue(
|
// final taskId = await FlutterDownloader.enqueue(
|
||||||
url: url,
|
// url: url,
|
||||||
savedDir: await _findLocalPath(),
|
// savedDir: await _findLocalPath(),
|
||||||
showNotification: true, // show download progress in status bar (for Android)
|
// showNotification: true, // show download progress in status bar (for Android)
|
||||||
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
|
// openFileFromNotification: true, // click on notification to open downloaded file (for Android)
|
||||||
);*/
|
// );
|
||||||
},
|
},
|
||||||
onLoadResourceCustomScheme: (InAppWebViewController controller, String scheme, String url) async {
|
onLoadResourceCustomScheme: (InAppWebViewController controller, String scheme, String url) async {
|
||||||
if (scheme == "my-special-custom-scheme") {
|
if (scheme == "my-special-custom-scheme") {
|
||||||
|
@ -220,6 +240,12 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
||||||
SafeBrowsingResponseAction action = SafeBrowsingResponseAction.BACK_TO_SAFETY;
|
SafeBrowsingResponseAction action = SafeBrowsingResponseAction.BACK_TO_SAFETY;
|
||||||
return new SafeBrowsingResponse(report: true, action: action);
|
return new SafeBrowsingResponse(report: true, action: action);
|
||||||
},
|
},
|
||||||
|
onReceivedHttpAuthRequest: (InAppWebViewController controller, HttpAuthChallenge challenge) async {
|
||||||
|
print("HTTP AUTH REQUEST: " + challenge.protectionSpace.host + ", realm: " + challenge.protectionSpace.realm +
|
||||||
|
", previous failure count: " + challenge.previousFailureCount.toString());
|
||||||
|
|
||||||
|
return new HttpAuthResponse(username: "USERNAME", password: "PASSWORD", action: HttpAuthResponseAction.USE_SAVED_HTTP_AUTH_CREDENTIALS, permanentPersistence: true);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
//
|
||||||
|
// CredentialDatabase.swift
|
||||||
|
// flutter_inappbrowser
|
||||||
|
//
|
||||||
|
// Created by Lorenzo Pichilli on 29/10/2019.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
|
static var registrar: FlutterPluginRegistrar?
|
||||||
|
static var channel: FlutterMethodChannel?
|
||||||
|
static var credentialStore: URLCredentialStorage?
|
||||||
|
|
||||||
|
static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
init(registrar: FlutterPluginRegistrar) {
|
||||||
|
super.init()
|
||||||
|
CredentialDatabase.registrar = registrar
|
||||||
|
CredentialDatabase.credentialStore = URLCredentialStorage.shared
|
||||||
|
|
||||||
|
CredentialDatabase.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser_credential_database", binaryMessenger: registrar.messenger())
|
||||||
|
registrar.addMethodCallDelegate(self, channel: CredentialDatabase.channel!)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
|
let arguments = call.arguments as? NSDictionary
|
||||||
|
switch call.method {
|
||||||
|
case "getAllAuthCredentials":
|
||||||
|
var allCredentials: [[String: Any?]] = []
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
let protectionSpaceDict = [
|
||||||
|
"host": protectionSpace.host,
|
||||||
|
"protocol": protectionSpace.protocol,
|
||||||
|
"realm": protectionSpace.realm,
|
||||||
|
"port": protectionSpace.port
|
||||||
|
] as [String : Any?]
|
||||||
|
|
||||||
|
var crendentials: [[String: String?]] = []
|
||||||
|
for c in credentials {
|
||||||
|
let credential: [String: String?] = [
|
||||||
|
"username": c.value.user,
|
||||||
|
"password": c.value.password,
|
||||||
|
]
|
||||||
|
crendentials.append(credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
let dict = [
|
||||||
|
"protectionSpace": protectionSpaceDict,
|
||||||
|
"credentials": crendentials
|
||||||
|
] as [String : Any]
|
||||||
|
allCredentials.append(dict)
|
||||||
|
}
|
||||||
|
result(allCredentials)
|
||||||
|
break
|
||||||
|
case "getHttpAuthCredentials":
|
||||||
|
let host = arguments!["host"] as! String
|
||||||
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
var realm = arguments!["realm"] as? String;
|
||||||
|
if let r = realm, r.isEmpty {
|
||||||
|
realm = nil
|
||||||
|
}
|
||||||
|
var crendentials: [[String: String?]] = []
|
||||||
|
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
|
for c in credentials {
|
||||||
|
let credential: [String: String?] = [
|
||||||
|
"username": c.value.user,
|
||||||
|
"password": c.value.password,
|
||||||
|
]
|
||||||
|
crendentials.append(credential)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result(crendentials)
|
||||||
|
break
|
||||||
|
case "setHttpAuthCredential":
|
||||||
|
let host = arguments!["host"] as! String
|
||||||
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
var realm = arguments!["realm"] as? String;
|
||||||
|
if let r = realm, r.isEmpty {
|
||||||
|
realm = nil
|
||||||
|
}
|
||||||
|
let username = arguments!["username"] as! String
|
||||||
|
let password = arguments!["password"] as! String
|
||||||
|
let credential = URLCredential(user: username, password: password, persistence: .permanent)
|
||||||
|
CredentialDatabase.credentialStore!.set(credential, for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol, realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
|
case "removeHttpAuthCredential":
|
||||||
|
let host = arguments!["host"] as! String
|
||||||
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
var realm = arguments!["realm"] as? String;
|
||||||
|
if let r = realm, r.isEmpty {
|
||||||
|
realm = nil
|
||||||
|
}
|
||||||
|
let username = arguments!["username"] as! String
|
||||||
|
let password = arguments!["password"] as! String
|
||||||
|
|
||||||
|
var credential: URLCredential? = nil;
|
||||||
|
var protectionSpaceCredential: URLProtectionSpace? = nil
|
||||||
|
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
|
for c in credentials {
|
||||||
|
if c.value.user == username, c.value.password == password {
|
||||||
|
credential = c.value
|
||||||
|
protectionSpaceCredential = protectionSpace
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if credential != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let c = credential, let protectionSpace = protectionSpaceCredential {
|
||||||
|
CredentialDatabase.credentialStore!.remove(c, for: protectionSpace)
|
||||||
|
}
|
||||||
|
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
|
case "removeHttpAuthCredentials":
|
||||||
|
let host = arguments!["host"] as! String
|
||||||
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
var realm = arguments!["realm"] as? String;
|
||||||
|
if let r = realm, r.isEmpty {
|
||||||
|
realm = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var credentialsToRemove: [URLCredential] = [];
|
||||||
|
var protectionSpaceCredential: URLProtectionSpace? = nil
|
||||||
|
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
|
protectionSpaceCredential = protectionSpace
|
||||||
|
for c in credentials {
|
||||||
|
credentialsToRemove.append(c.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let protectionSpace = protectionSpaceCredential {
|
||||||
|
for credential in credentialsToRemove {
|
||||||
|
CredentialDatabase.credentialStore!.remove(credential, for: protectionSpace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
|
case "clearAllAuthCredentials":
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
for credential in credentials {
|
||||||
|
CredentialDatabase.credentialStore!.remove(credential.value, for: protectionSpace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
result(FlutterMethodNotImplemented)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -259,6 +259,12 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||||
case "getCopyBackForwardList":
|
case "getCopyBackForwardList":
|
||||||
result((webView != nil) ? webView!.getCopyBackForwardList() : nil)
|
result((webView != nil) ? webView!.getCopyBackForwardList() : nil)
|
||||||
break
|
break
|
||||||
|
case "clearCache":
|
||||||
|
if webView != nil {
|
||||||
|
webView!.clearCache()
|
||||||
|
}
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
case "dispose":
|
case "dispose":
|
||||||
dispose()
|
dispose()
|
||||||
result(true)
|
result(true)
|
||||||
|
|
|
@ -90,6 +90,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
var currentURL: URL?
|
var currentURL: URL?
|
||||||
var WKNavigationMap: [String: [String: Any]] = [:]
|
var WKNavigationMap: [String: [String: Any]] = [:]
|
||||||
var startPageTime: Int64 = 0
|
var startPageTime: Int64 = 0
|
||||||
|
static var credentialsProposed: [URLCredential] = []
|
||||||
|
|
||||||
init(frame: CGRect, configuration: WKWebViewConfiguration, IABController: InAppBrowserWebViewController?, IAWController: FlutterWebViewController?) {
|
init(frame: CGRect, configuration: WKWebViewConfiguration, IABController: InAppBrowserWebViewController?, IAWController: FlutterWebViewController?) {
|
||||||
super.init(frame: frame, configuration: configuration)
|
super.init(frame: frame, configuration: configuration)
|
||||||
|
@ -203,7 +204,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)!
|
scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)!
|
||||||
scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)!
|
scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)!
|
||||||
|
|
||||||
|
|
||||||
// options.debuggingEnabled is always enabled for iOS.
|
// options.debuggingEnabled is always enabled for iOS.
|
||||||
|
|
||||||
if (options?.clearCache)! {
|
if (options?.clearCache)! {
|
||||||
|
@ -721,6 +721,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
self.WKNavigationMap = [:]
|
self.WKNavigationMap = [:]
|
||||||
currentURL = url
|
currentURL = url
|
||||||
|
InAppWebView.credentialsProposed = []
|
||||||
onLoadStop(url: (currentURL?.absoluteString)!)
|
onLoadStop(url: (currentURL?.absoluteString)!)
|
||||||
evaluateJavaScript(platformReadyJS, completionHandler: nil)
|
evaluateJavaScript(platformReadyJS, completionHandler: nil)
|
||||||
|
|
||||||
|
@ -739,6 +740,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
||||||
|
InAppWebView.credentialsProposed = []
|
||||||
|
|
||||||
onLoadError(url: (currentURL?.absoluteString)!, error: error)
|
onLoadError(url: (currentURL?.absoluteString)!, error: error)
|
||||||
|
|
||||||
if IABController != nil {
|
if IABController != nil {
|
||||||
|
@ -749,51 +752,100 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
||||||
let host = challenge.protectionSpace.host
|
|
||||||
let realm = challenge.protectionSpace.realm
|
print (challenge.protectionSpace.authenticationMethod)
|
||||||
onReceivedHttpAuthRequest(host: host, realm: realm, result: {(result) -> Void in
|
|
||||||
if result is FlutterError {
|
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic ||
|
||||||
print((result as! FlutterError).message)
|
challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodDefault ||
|
||||||
}
|
challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPDigest {
|
||||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
let host = challenge.protectionSpace.host
|
||||||
completionHandler(.performDefaultHandling, nil)
|
let prot = challenge.protectionSpace.protocol
|
||||||
}
|
let realm = challenge.protectionSpace.realm
|
||||||
else {
|
let port = challenge.protectionSpace.port
|
||||||
//WKWebsiteDataStore.default()
|
onReceivedHttpAuthRequest(challenge: challenge, result: {(result) -> Void in
|
||||||
//URLCredentialStorage()
|
if result is FlutterError {
|
||||||
var response: [String: Any]
|
print((result as! FlutterError).message)
|
||||||
if let r = result {
|
|
||||||
response = r as! [String: Any]
|
|
||||||
var action = response["action"] as? Int
|
|
||||||
action = action != nil ? action : 0;
|
|
||||||
switch action {
|
|
||||||
case 0:
|
|
||||||
completionHandler(.cancelAuthenticationChallenge, nil)
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
let username = response["username"] as! String
|
|
||||||
let password = response["password"] as! String
|
|
||||||
let permanentPersistence = response["permanentPersistence"] as? Bool ?? false
|
|
||||||
let persistence = (permanentPersistence) ? URLCredential.Persistence.permanent : URLCredential.Persistence.forSession
|
|
||||||
let credential = URLCredential(user: username, password: password, persistence: persistence)
|
|
||||||
completionHandler(.useCredential, credential)
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
if let credential = challenge.proposedCredential {
|
|
||||||
completionHandler(.useCredential, credential)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
completionHandler(.performDefaultHandling, nil)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
completionHandler(.performDefaultHandling, nil)
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
completionHandler(.performDefaultHandling, nil)
|
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||||
}
|
completionHandler(.performDefaultHandling, nil)
|
||||||
})
|
}
|
||||||
|
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 0:
|
||||||
|
InAppWebView.credentialsProposed = []
|
||||||
|
completionHandler(.cancelAuthenticationChallenge, nil)
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
let username = response["username"] as! String
|
||||||
|
let password = response["password"] as! String
|
||||||
|
let permanentPersistence = response["permanentPersistence"] as? Bool ?? false
|
||||||
|
let persistence = (permanentPersistence) ? URLCredential.Persistence.permanent : URLCredential.Persistence.forSession
|
||||||
|
let credential = URLCredential(user: username, password: password, persistence: persistence)
|
||||||
|
completionHandler(.useCredential, credential)
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
if InAppWebView.credentialsProposed.count == 0 {
|
||||||
|
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||||
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
|
protectionSpace.protocol == prot && protectionSpace.port == port {
|
||||||
|
for credential in credentials {
|
||||||
|
InAppWebView.credentialsProposed.append(credential.value)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if InAppWebView.credentialsProposed.count == 0, let credential = challenge.proposedCredential {
|
||||||
|
InAppWebView.credentialsProposed.append(credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let credential = InAppWebView.credentialsProposed.popLast() {
|
||||||
|
completionHandler(.useCredential, credential)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
|
||||||
|
/// TODO: correspond to onSslError event of Android
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
// guard let serverTrust = challenge.protectionSpace.serverTrust else {
|
||||||
|
// completionHandler(.performDefaultHandling, nil)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// //if checkValidity(of: serverTrust) {
|
||||||
|
// if true {
|
||||||
|
// let exceptions = SecTrustCopyExceptions(serverTrust)
|
||||||
|
// SecTrustSetExceptions(serverTrust, exceptions)
|
||||||
|
// let credential = URLCredential(trust: serverTrust)
|
||||||
|
// completionHandler(.useCredential, credential)
|
||||||
|
// } else {
|
||||||
|
// // Show a UI here warning the user the server credentials are
|
||||||
|
// // invalid, and cancel the load.
|
||||||
|
// completionHandler(.cancelAuthenticationChallenge, nil)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate {
|
||||||
|
/// TODO: load certificates
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completionHandler(.performDefaultHandling, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func createAlertDialog(message: String?, responseMessage: String?, confirmButtonTitle: String?, completionHandler: @escaping () -> Void) {
|
fileprivate func createAlertDialog(message: String?, responseMessage: String?, confirmButtonTitle: String?, completionHandler: @escaping () -> Void) {
|
||||||
|
@ -1101,8 +1153,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onReceivedHttpAuthRequest(host: String, realm: String?, result: FlutterResult?) {
|
public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
|
||||||
var arguments: [String: Any] = ["host": host, "realm": realm as Any]
|
var arguments: [String: Any?] = [
|
||||||
|
"host": challenge.protectionSpace.host,
|
||||||
|
"protocol": challenge.protectionSpace.protocol,
|
||||||
|
"realm": challenge.protectionSpace.realm,
|
||||||
|
"port": challenge.protectionSpace.port,
|
||||||
|
"previousFailureCount": challenge.previousFailureCount
|
||||||
|
]
|
||||||
if IABController != nil {
|
if IABController != nil {
|
||||||
arguments["uuid"] = IABController!.uuid
|
arguments["uuid"] = IABController!.uuid
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,17 +52,17 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
let name = arguments!["name"] as! String
|
let name = arguments!["name"] as! String
|
||||||
let domain = arguments!["domain"] as! String
|
let domain = arguments!["domain"] as! String
|
||||||
let path = arguments!["path"] as! String
|
let path = arguments!["path"] as! String
|
||||||
MyCookieManager.deleteCookie(url: url, name: name, domain: domain, path: path, result: result);
|
MyCookieManager.deleteCookie(url: url, name: name, domain: domain, path: path, result: result)
|
||||||
break;
|
break;
|
||||||
case "deleteCookies":
|
case "deleteCookies":
|
||||||
let url = arguments!["url"] as! String
|
let url = arguments!["url"] as! String
|
||||||
let domain = arguments!["domain"] as! String
|
let domain = arguments!["domain"] as! String
|
||||||
let path = arguments!["path"] as! String
|
let path = arguments!["path"] as! String
|
||||||
MyCookieManager.deleteCookies(url: url, domain: domain, path: path, result: result);
|
MyCookieManager.deleteCookies(url: url, domain: domain, path: path, result: result)
|
||||||
break;
|
break;
|
||||||
case "deleteAllCookies":
|
case "deleteAllCookies":
|
||||||
MyCookieManager.deleteAllCookies(result: result);
|
MyCookieManager.deleteAllCookies(result: result)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
result(FlutterMethodNotImplemented)
|
result(FlutterMethodNotImplemented)
|
||||||
break
|
break
|
||||||
|
|
|
@ -61,6 +61,8 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
} else {
|
} else {
|
||||||
// Fallback on earlier versions
|
// Fallback on earlier versions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CredentialDatabase(registrar: registrar)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
|
@ -237,6 +239,10 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
case "getCopyBackForwardList":
|
case "getCopyBackForwardList":
|
||||||
result(self.getCopyBackForwardList(uuid: uuid))
|
result(self.getCopyBackForwardList(uuid: uuid))
|
||||||
break
|
break
|
||||||
|
case "clearCache":
|
||||||
|
self.clearCache(uuid: uuid)
|
||||||
|
result(true)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
result(FlutterMethodNotImplemented)
|
result(FlutterMethodNotImplemented)
|
||||||
break
|
break
|
||||||
|
@ -746,6 +752,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearCache(uuid: String) {
|
||||||
|
if let webViewController = self.webViewControllers[uuid] {
|
||||||
|
webViewController!.webView.clearCache()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function inserted by Swift 4.2 migrator.
|
// Helper function inserted by Swift 4.2 migrator.
|
||||||
|
|
|
@ -30,3 +30,4 @@ export 'src/chrome_safari_browser.dart';
|
||||||
export 'src/in_app_localhost_server.dart';
|
export 'src/in_app_localhost_server.dart';
|
||||||
export 'src/webview_options.dart';
|
export 'src/webview_options.dart';
|
||||||
export 'src/content_blocker.dart';
|
export 'src/content_blocker.dart';
|
||||||
|
export 'src/http_auth_credentials_database.dart';
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ChromeSafariBrowser {
|
||||||
///- __preferredControlTintColor__: Set the custom color of the control buttons on the navigation bar and the toolbar.
|
///- __preferredControlTintColor__: Set the custom color of the control buttons on the navigation bar and the toolbar.
|
||||||
///- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles.
|
///- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles.
|
||||||
///- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.
|
///- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.
|
||||||
Future<void> open(String url, {List<ChromeCustomTabsOptions> options = const [], Map<String, String> headersFallback = const {}, List<BrowserOptions> optionsFallback = const []}) async {
|
Future<void> open(String url, {List<ChromeSafariBrowserOptions> options = const [], Map<String, String> headersFallback = const {}, List<BrowserOptions> optionsFallback = const []}) async {
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
this.throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
|
|
||||||
|
|
|
@ -4,32 +4,34 @@ import 'package:flutter/services.dart';
|
||||||
///
|
///
|
||||||
///**NOTE for iOS**: available from iOS 11.0+.
|
///**NOTE for iOS**: available from iOS 11.0+.
|
||||||
class CookieManager {
|
class CookieManager {
|
||||||
static bool _initialized = false;
|
static CookieManager _instance;
|
||||||
static const MethodChannel _channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser_cookiemanager');
|
static const MethodChannel _channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser_cookiemanager');
|
||||||
|
|
||||||
static void _init () {
|
static CookieManager instance() {
|
||||||
_channel.setMethodCallHandler(handleMethod);
|
return (_instance != null) ? _instance : _init();
|
||||||
_initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<dynamic> handleMethod(MethodCall call) async {
|
static CookieManager _init() {
|
||||||
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
|
_instance = new CookieManager();
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Sets a cookie for the given [url]. Any existing cookie with the same [host], [path] and [name] will be replaced with the new cookie. The cookie being set will be ignored if it is expired.
|
///Sets a cookie for the given [url]. Any existing cookie with the same [host], [path] and [name] will be replaced with the new cookie. The cookie being set will be ignored if it is expired.
|
||||||
///
|
///
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null`, its default value will be the domain name of [url].
|
///If [domain] is `null`, its default value will be the domain name of [url].
|
||||||
static Future<void> setCookie(String url, String name, String value,
|
Future<void> setCookie(String url, String name, String value,
|
||||||
{ String domain,
|
{ String domain,
|
||||||
String path = "/",
|
String path = "/",
|
||||||
int expiresDate,
|
int expiresDate,
|
||||||
int maxAge,
|
int maxAge,
|
||||||
bool isSecure }) async {
|
bool isSecure }) async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
if (domain == null)
|
if (domain == null)
|
||||||
domain = getDomainName(url);
|
domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name != null && name.isNotEmpty);
|
||||||
|
@ -51,10 +53,7 @@ class CookieManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets all the cookies for the given [url].
|
///Gets all the cookies for the given [url].
|
||||||
static Future<List<Map<String, dynamic>>> getCookies(String url) async {
|
Future<List<Map<String, dynamic>>> getCookies(String url) async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -69,10 +68,7 @@ class CookieManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Gets a cookie by its [name] for the given [url].
|
///Gets a cookie by its [name] for the given [url].
|
||||||
static Future<Map<String, dynamic>> getCookie(String url, String name) async {
|
Future<Map<String, dynamic>> getCookie(String url, String name) async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name != null && name.isNotEmpty);
|
||||||
|
|
||||||
|
@ -92,12 +88,9 @@ class CookieManager {
|
||||||
///
|
///
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
||||||
static Future<void> deleteCookie(String url, String name, {String domain = "", String path = "/"}) async {
|
Future<void> deleteCookie(String url, String name, {String domain = "", String path = "/"}) async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
if (domain == null || domain.isEmpty)
|
if (domain == null || domain.isEmpty)
|
||||||
domain = getDomainName(url);
|
domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
assert(name != null && name.isNotEmpty);
|
assert(name != null && name.isNotEmpty);
|
||||||
|
@ -116,12 +109,9 @@ class CookieManager {
|
||||||
///
|
///
|
||||||
///The default value of [path] is `"/"`.
|
///The default value of [path] is `"/"`.
|
||||||
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
///If [domain] is `null` or empty, its default value will be the domain name of [url].
|
||||||
static Future<void> deleteCookies(String url, {String domain = "", String path = "/"}) async {
|
Future<void> deleteCookies(String url, {String domain = "", String path = "/"}) async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
if (domain == null || domain.isEmpty)
|
if (domain == null || domain.isEmpty)
|
||||||
domain = getDomainName(url);
|
domain = _getDomainName(url);
|
||||||
|
|
||||||
assert(url != null && url.isNotEmpty);
|
assert(url != null && url.isNotEmpty);
|
||||||
assert(domain != null && url.isNotEmpty);
|
assert(domain != null && url.isNotEmpty);
|
||||||
|
@ -135,15 +125,12 @@ class CookieManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Removes all cookies.
|
///Removes all cookies.
|
||||||
static Future<void> deleteAllCookies() async {
|
Future<void> deleteAllCookies() async {
|
||||||
if (!_initialized)
|
|
||||||
_init();
|
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
await _channel.invokeMethod('deleteAllCookies', args);
|
await _channel.invokeMethod('deleteAllCookies', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getDomainName(String url) {
|
String _getDomainName(String url) {
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(url);
|
||||||
String domain = uri.host;
|
String domain = uri.host;
|
||||||
if (domain == null)
|
if (domain == null)
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
import 'types.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
class HttpAuthCredentialDatabase {
|
||||||
|
static HttpAuthCredentialDatabase _instance;
|
||||||
|
static const MethodChannel _channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser_credential_database');
|
||||||
|
|
||||||
|
///
|
||||||
|
static HttpAuthCredentialDatabase instance() {
|
||||||
|
return (_instance != null) ? _instance : _init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static HttpAuthCredentialDatabase _init() {
|
||||||
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
|
_instance = new HttpAuthCredentialDatabase();
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<List<Map<String, dynamic>>> getAllAuthCredentials() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
List<dynamic> allCredentials = await _channel.invokeMethod('getAllAuthCredentials', args);
|
||||||
|
List<Map<String, dynamic>> result = [];
|
||||||
|
for (Map<dynamic, dynamic> map in allCredentials) {
|
||||||
|
Map<dynamic, dynamic> protectionSpace = map["protectionSpace"];
|
||||||
|
List<dynamic> credentials = map["credentials"];
|
||||||
|
result.add({
|
||||||
|
"protectionSpace": ProtectionSpace(host: protectionSpace["host"], protocol: protectionSpace["protocol"], realm: protectionSpace["realm"], port: protectionSpace["port"]),
|
||||||
|
"credentials": credentials.map((credential) => HttpAuthCredential(username: credential["username"], password: credential["password"])).toList()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<List<HttpAuthCredential>> getHttpAuthCredentials(ProtectionSpace protectionSpace) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
args.putIfAbsent("realm", () => protectionSpace.realm);
|
||||||
|
args.putIfAbsent("port", () => protectionSpace.port);
|
||||||
|
List<dynamic> credentialList = await _channel.invokeMethod('getHttpAuthCredentials', args);
|
||||||
|
List<HttpAuthCredential> credentials = [];
|
||||||
|
for (Map<dynamic, dynamic> credential in credentialList) {
|
||||||
|
credentials.add(HttpAuthCredential(username: credential["username"], password: credential["password"]));
|
||||||
|
}
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<void> setHttpAuthCredential(ProtectionSpace protectionSpace, HttpAuthCredential credential) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
args.putIfAbsent("realm", () => protectionSpace.realm);
|
||||||
|
args.putIfAbsent("port", () => protectionSpace.port);
|
||||||
|
args.putIfAbsent("username", () => credential.username);
|
||||||
|
args.putIfAbsent("password", () => credential.password);
|
||||||
|
await _channel.invokeMethod('setHttpAuthCredential', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<void> removeHttpAuthCredential(ProtectionSpace protectionSpace, HttpAuthCredential credential) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
args.putIfAbsent("realm", () => protectionSpace.realm);
|
||||||
|
args.putIfAbsent("port", () => protectionSpace.port);
|
||||||
|
args.putIfAbsent("username", () => credential.username);
|
||||||
|
args.putIfAbsent("password", () => credential.password);
|
||||||
|
await _channel.invokeMethod('removeHttpAuthCredential', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<void> removeHttpAuthCredentials(ProtectionSpace protectionSpace) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("host", () => protectionSpace.host);
|
||||||
|
args.putIfAbsent("protocol", () => protectionSpace.protocol);
|
||||||
|
args.putIfAbsent("realm", () => protectionSpace.realm);
|
||||||
|
args.putIfAbsent("port", () => protectionSpace.port);
|
||||||
|
await _channel.invokeMethod('removeHttpAuthCredentials', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<void> clearAllAuthCredentials() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
await _channel.invokeMethod('clearAllAuthCredentials', args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import 'dart:collection';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappbrowser/src/webview_options.dart';
|
import 'package:flutter_inappbrowser/src/webview_options.dart';
|
||||||
|
|
||||||
|
import 'http_auth_credentials_database.dart';
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
import 'channel_manager.dart';
|
import 'channel_manager.dart';
|
||||||
import 'in_app_webview.dart' show InAppWebViewController;
|
import 'in_app_webview.dart' show InAppWebViewController;
|
||||||
|
@ -408,10 +409,8 @@ class InAppBrowser {
|
||||||
|
|
||||||
///Event fires when a WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
///Event fires when a WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
||||||
///
|
///
|
||||||
///[host] represents the host requiring authentication.
|
///[challenge] contains data about host, port, protocol, realm, etc. as specified in the auth challenge.
|
||||||
///
|
Future<HttpAuthResponse> onReceivedHttpAuthRequest(String url, HttpAuthChallenge challenge) {
|
||||||
///[realm] represents the realm for which authentication is required
|
|
||||||
Future<HttpAuthResponse> onReceivedHttpAuthRequest(String url, String realm) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
|
|
||||||
|
import 'http_auth_credentials_database.dart';
|
||||||
import 'types.dart';
|
import 'types.dart';
|
||||||
import 'in_app_browser.dart';
|
import 'in_app_browser.dart';
|
||||||
import 'channel_manager.dart';
|
import 'channel_manager.dart';
|
||||||
|
@ -178,9 +179,7 @@ class InAppWebView extends StatefulWidget {
|
||||||
|
|
||||||
///Event fires when a WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
///Event fires when a WebView received an HTTP authentication request. The default behavior is to cancel the request.
|
||||||
///
|
///
|
||||||
///[host] represents the host requiring authentication.
|
///[challenge] contains data about host, port, protocol, realm, etc. as specified in the auth challenge.
|
||||||
///
|
|
||||||
///[realm] represents the realm for which authentication is required
|
|
||||||
final onReceivedHttpAuthRequestCallback onReceivedHttpAuthRequest;
|
final onReceivedHttpAuthRequestCallback onReceivedHttpAuthRequest;
|
||||||
|
|
||||||
///Initial url that will be loaded.
|
///Initial url that will be loaded.
|
||||||
|
@ -251,7 +250,8 @@ class _InAppWebViewState extends State<InAppWebView> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Map<String, dynamic> initialOptions = {};
|
Map<String, dynamic> initialOptions = {};
|
||||||
widget.initialOptions.forEach((webViewOption) {
|
widget.initialOptions.forEach((webViewOption) {
|
||||||
initialOptions.addAll(webViewOption.toMap());
|
if ((Platform.isAndroid && webViewOption is AndroidOptions) || (Platform.isIOS && webViewOption is iOSOptions))
|
||||||
|
initialOptions.addAll(webViewOption.toMap());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
@ -478,11 +478,16 @@ class InAppWebViewController {
|
||||||
break;
|
break;
|
||||||
case "onReceivedHttpAuthRequest":
|
case "onReceivedHttpAuthRequest":
|
||||||
String host = call.arguments["host"];
|
String host = call.arguments["host"];
|
||||||
|
String protocol = call.arguments["protocol"];
|
||||||
String realm = call.arguments["realm"];
|
String realm = call.arguments["realm"];
|
||||||
|
int port = call.arguments["port"];
|
||||||
|
int previousFailureCount = call.arguments["previousFailureCount"];
|
||||||
|
var protectionSpace = ProtectionSpace(host: host, protocol: protocol, realm: realm, port: port);
|
||||||
|
var challenge = HttpAuthChallenge(previousFailureCount: previousFailureCount, protectionSpace: protectionSpace);
|
||||||
if (_widget != null && _widget.onReceivedHttpAuthRequest != null)
|
if (_widget != null && _widget.onReceivedHttpAuthRequest != null)
|
||||||
return (await _widget.onReceivedHttpAuthRequest(this, host, realm))?.toMap();
|
return (await _widget.onReceivedHttpAuthRequest(this, challenge))?.toMap();
|
||||||
else if (_inAppBrowser != null)
|
else if (_inAppBrowser != null)
|
||||||
return (await _inAppBrowser.onReceivedHttpAuthRequest(host, realm))?.toMap();
|
return (await _inAppBrowser.onReceivedHttpAuthRequest(host, challenge))?.toMap();
|
||||||
break;
|
break;
|
||||||
case "onCallJsHandler":
|
case "onCallJsHandler":
|
||||||
String handlerName = call.arguments["handlerName"];
|
String handlerName = call.arguments["handlerName"];
|
||||||
|
@ -960,6 +965,16 @@ class InAppWebViewController {
|
||||||
return await _channel.invokeMethod('getSafeBrowsingPrivacyPolicyUrl', args);
|
return await _channel.invokeMethod('getSafeBrowsingPrivacyPolicyUrl', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Clear all the webview's cache
|
||||||
|
Future<void> clearCache() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
if (_inAppBrowserUuid != null && _inAppBrowser != null) {
|
||||||
|
_inAppBrowser.throwIsNotOpened();
|
||||||
|
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
|
||||||
|
}
|
||||||
|
await _channel.invokeMethod('clearCache', args);
|
||||||
|
}
|
||||||
|
|
||||||
///Dispose/Destroy the WebView.
|
///Dispose/Destroy the WebView.
|
||||||
Future<void> _dispose() async {
|
Future<void> _dispose() async {
|
||||||
await _channel.invokeMethod('dispose');
|
await _channel.invokeMethod('dispose');
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'in_app_webview.dart';
|
import 'in_app_webview.dart';
|
||||||
|
|
||||||
var uuidGenerator = new Uuid();
|
var uuidGenerator = new Uuid();
|
||||||
|
@ -141,7 +142,7 @@ class GeolocationPermissionShowPromptResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsAlertResponseAction {
|
class JsAlertResponseAction {
|
||||||
final int _value;
|
final int _value;
|
||||||
const JsAlertResponseAction._internal(this._value);
|
const JsAlertResponseAction._internal(this._value);
|
||||||
|
@ -150,6 +151,7 @@ class JsAlertResponseAction {
|
||||||
static const CONFIRM = const JsAlertResponseAction._internal(0);
|
static const CONFIRM = const JsAlertResponseAction._internal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsAlertResponse {
|
class JsAlertResponse {
|
||||||
String message;
|
String message;
|
||||||
String confirmButtonTitle;
|
String confirmButtonTitle;
|
||||||
|
@ -168,6 +170,7 @@ class JsAlertResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsConfirmResponseAction {
|
class JsConfirmResponseAction {
|
||||||
final int _value;
|
final int _value;
|
||||||
const JsConfirmResponseAction._internal(this._value);
|
const JsConfirmResponseAction._internal(this._value);
|
||||||
|
@ -177,6 +180,7 @@ class JsConfirmResponseAction {
|
||||||
static const CANCEL = const JsConfirmResponseAction._internal(1);
|
static const CANCEL = const JsConfirmResponseAction._internal(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsConfirmResponse {
|
class JsConfirmResponse {
|
||||||
String message;
|
String message;
|
||||||
String confirmButtonTitle;
|
String confirmButtonTitle;
|
||||||
|
@ -197,6 +201,7 @@ class JsConfirmResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsPromptResponseAction {
|
class JsPromptResponseAction {
|
||||||
final int _value;
|
final int _value;
|
||||||
const JsPromptResponseAction._internal(this._value);
|
const JsPromptResponseAction._internal(this._value);
|
||||||
|
@ -206,6 +211,7 @@ class JsPromptResponseAction {
|
||||||
static const CANCEL = const JsPromptResponseAction._internal(1);
|
static const CANCEL = const JsPromptResponseAction._internal(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class JsPromptResponse {
|
class JsPromptResponse {
|
||||||
String message;
|
String message;
|
||||||
String defaultValue;
|
String defaultValue;
|
||||||
|
@ -230,6 +236,7 @@ class JsPromptResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class SafeBrowsingThreat {
|
class SafeBrowsingThreat {
|
||||||
final int _value;
|
final int _value;
|
||||||
const SafeBrowsingThreat._internal(this._value);
|
const SafeBrowsingThreat._internal(this._value);
|
||||||
|
@ -247,6 +254,7 @@ class SafeBrowsingThreat {
|
||||||
static const SAFE_BROWSING_THREAT_BILLING = const SafeBrowsingThreat._internal(4);
|
static const SAFE_BROWSING_THREAT_BILLING = const SafeBrowsingThreat._internal(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class SafeBrowsingResponseAction {
|
class SafeBrowsingResponseAction {
|
||||||
final int _value;
|
final int _value;
|
||||||
const SafeBrowsingResponseAction._internal(this._value);
|
const SafeBrowsingResponseAction._internal(this._value);
|
||||||
|
@ -256,6 +264,8 @@ class SafeBrowsingResponseAction {
|
||||||
static const PROCEED = const SafeBrowsingResponseAction._internal(1);
|
static const PROCEED = const SafeBrowsingResponseAction._internal(1);
|
||||||
static const SHOW_INTERSTITIAL = const SafeBrowsingResponseAction._internal(2);
|
static const SHOW_INTERSTITIAL = const SafeBrowsingResponseAction._internal(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class SafeBrowsingResponse {
|
class SafeBrowsingResponse {
|
||||||
bool report;
|
bool report;
|
||||||
SafeBrowsingResponseAction action;
|
SafeBrowsingResponseAction action;
|
||||||
|
@ -270,6 +280,7 @@ class SafeBrowsingResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class HttpAuthResponseAction {
|
class HttpAuthResponseAction {
|
||||||
final int _value;
|
final int _value;
|
||||||
const HttpAuthResponseAction._internal(this._value);
|
const HttpAuthResponseAction._internal(this._value);
|
||||||
|
@ -277,9 +288,10 @@ class HttpAuthResponseAction {
|
||||||
|
|
||||||
static const CANCEL = const HttpAuthResponseAction._internal(0);
|
static const CANCEL = const HttpAuthResponseAction._internal(0);
|
||||||
static const PROCEED = const HttpAuthResponseAction._internal(1);
|
static const PROCEED = const HttpAuthResponseAction._internal(1);
|
||||||
static const USE_HTTP_AUTH_USERNAME_PASSWORD = const HttpAuthResponseAction._internal(2);
|
static const USE_SAVED_HTTP_AUTH_CREDENTIALS = const HttpAuthResponseAction._internal(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
class HttpAuthResponse {
|
class HttpAuthResponse {
|
||||||
String username;
|
String username;
|
||||||
String password;
|
String password;
|
||||||
|
@ -298,6 +310,168 @@ class HttpAuthResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class HttpAuthChallenge {
|
||||||
|
int previousFailureCount;
|
||||||
|
ProtectionSpace protectionSpace;
|
||||||
|
|
||||||
|
HttpAuthChallenge({@required this.previousFailureCount, @required this.protectionSpace}): assert(previousFailureCount != null && protectionSpace != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class ProtectionSpace {
|
||||||
|
String host;
|
||||||
|
String protocol;
|
||||||
|
String realm;
|
||||||
|
int port;
|
||||||
|
|
||||||
|
ProtectionSpace({@required this.host, @required this.protocol, this.realm, this.port}): assert(host != null && protocol != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class HttpAuthCredential {
|
||||||
|
String username;
|
||||||
|
String password;
|
||||||
|
|
||||||
|
HttpAuthCredential({@required this.username, @required this.password}): assert(username != null && password != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AndroidInAppWebViewCacheMode {
|
||||||
|
final int _value;
|
||||||
|
const AndroidInAppWebViewCacheMode._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const LOAD_DEFAULT = const AndroidInAppWebViewCacheMode._internal(-1);
|
||||||
|
static const LOAD_CACHE_ELSE_NETWORK = const AndroidInAppWebViewCacheMode._internal(1);
|
||||||
|
static const LOAD_NO_CACHE = const AndroidInAppWebViewCacheMode._internal(2);
|
||||||
|
static const LOAD_CACHE_ONLY = const AndroidInAppWebViewCacheMode._internal(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AndroidInAppWebViewModeMenuItem {
|
||||||
|
final int _value;
|
||||||
|
const AndroidInAppWebViewModeMenuItem._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const MENU_ITEM_NONE = const AndroidInAppWebViewModeMenuItem._internal(0);
|
||||||
|
static const MENU_ITEM_SHARE = const AndroidInAppWebViewModeMenuItem._internal(1);
|
||||||
|
static const MENU_ITEM_WEB_SEARCH = const AndroidInAppWebViewModeMenuItem._internal(2);
|
||||||
|
static const MENU_ITEM_PROCESS_TEXT = const AndroidInAppWebViewModeMenuItem._internal(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AndroidInAppWebViewForceDark {
|
||||||
|
final int _value;
|
||||||
|
const AndroidInAppWebViewForceDark._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const FORCE_DARK_OFF = const AndroidInAppWebViewForceDark._internal(0);
|
||||||
|
static const FORCE_DARK_AUTO = const AndroidInAppWebViewForceDark._internal(1);
|
||||||
|
static const FORCE_DARK_ON = const AndroidInAppWebViewForceDark._internal(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AndroidInAppWebViewLayoutAlgorithm {
|
||||||
|
final String _value;
|
||||||
|
const AndroidInAppWebViewLayoutAlgorithm._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const NORMAL = const AndroidInAppWebViewLayoutAlgorithm._internal("NORMAL");
|
||||||
|
static const TEXT_AUTOSIZING = const AndroidInAppWebViewLayoutAlgorithm._internal("TEXT_AUTOSIZING");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class AndroidInAppWebViewMixedContentMode {
|
||||||
|
final int _value;
|
||||||
|
const AndroidInAppWebViewMixedContentMode._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const MIXED_CONTENT_ALWAYS_ALLOW = const AndroidInAppWebViewMixedContentMode._internal(0);
|
||||||
|
static const MIXED_CONTENT_NEVER_ALLOW = const AndroidInAppWebViewMixedContentMode._internal(1);
|
||||||
|
static const MIXED_CONTENT_COMPATIBILITY_MODE = const AndroidInAppWebViewMixedContentMode._internal(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSInAppWebViewSelectionGranularity {
|
||||||
|
final int _value;
|
||||||
|
const iOSInAppWebViewSelectionGranularity._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const CHARACTER = const iOSInAppWebViewSelectionGranularity._internal(0);
|
||||||
|
static const DYNAMIC = const iOSInAppWebViewSelectionGranularity._internal(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSInAppWebViewDataDetectorTypes {
|
||||||
|
final String _value;
|
||||||
|
const iOSInAppWebViewDataDetectorTypes._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const NONE = const iOSInAppWebViewDataDetectorTypes._internal("NONE");
|
||||||
|
static const PHONE_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("PHONE_NUMBER");
|
||||||
|
static const LINK = const iOSInAppWebViewDataDetectorTypes._internal("LINK");
|
||||||
|
static const ADDRESS = const iOSInAppWebViewDataDetectorTypes._internal("ADDRESS");
|
||||||
|
static const CALENDAR_EVENT = const iOSInAppWebViewDataDetectorTypes._internal("CALENDAR_EVENT");
|
||||||
|
static const TRACKING_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("TRACKING_NUMBER");
|
||||||
|
static const FLIGHT_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("FLIGHT_NUMBER");
|
||||||
|
static const LOOKUP_SUGGESTION = const iOSInAppWebViewDataDetectorTypes._internal("LOOKUP_SUGGESTION");
|
||||||
|
static const SPOTLIGHT_SUGGESTION = const iOSInAppWebViewDataDetectorTypes._internal("SPOTLIGHT_SUGGESTION");
|
||||||
|
static const ALL = const iOSInAppWebViewDataDetectorTypes._internal("ALL");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSInAppWebViewUserPreferredContentMode {
|
||||||
|
final int _value;
|
||||||
|
const iOSInAppWebViewUserPreferredContentMode._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const RECOMMENDED = const iOSInAppWebViewUserPreferredContentMode._internal(0);
|
||||||
|
static const MOBILE = const iOSInAppWebViewUserPreferredContentMode._internal(1);
|
||||||
|
static const DESKTOP = const iOSInAppWebViewUserPreferredContentMode._internal(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSWebViewOptionsPresentationStyle {
|
||||||
|
final int _value;
|
||||||
|
const iOSWebViewOptionsPresentationStyle._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const FULL_SCREEN = const iOSWebViewOptionsPresentationStyle._internal(0);
|
||||||
|
static const PAGE_SHEET = const iOSWebViewOptionsPresentationStyle._internal(1);
|
||||||
|
static const FORM_SHEET = const iOSWebViewOptionsPresentationStyle._internal(2);
|
||||||
|
static const CURRENT_CONTEXT = const iOSWebViewOptionsPresentationStyle._internal(3);
|
||||||
|
static const CUSTOM = const iOSWebViewOptionsPresentationStyle._internal(4);
|
||||||
|
static const OVER_FULL_SCREEN = const iOSWebViewOptionsPresentationStyle._internal(5);
|
||||||
|
static const OVER_CURRENT_CONTEXT = const iOSWebViewOptionsPresentationStyle._internal(6);
|
||||||
|
static const POPOVER = const iOSWebViewOptionsPresentationStyle._internal(7);
|
||||||
|
static const NONE = const iOSWebViewOptionsPresentationStyle._internal(8);
|
||||||
|
static const AUTOMATIC = const iOSWebViewOptionsPresentationStyle._internal(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSWebViewOptionsTransitionStyle {
|
||||||
|
final int _value;
|
||||||
|
const iOSWebViewOptionsTransitionStyle._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const COVER_VERTICAL = const iOSWebViewOptionsTransitionStyle._internal(0);
|
||||||
|
static const FLIP_HORIZONTAL = const iOSWebViewOptionsTransitionStyle._internal(1);
|
||||||
|
static const CROSS_DISSOLVE = const iOSWebViewOptionsTransitionStyle._internal(2);
|
||||||
|
static const PARTIAL_CURL = const iOSWebViewOptionsTransitionStyle._internal(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class iOSSafariOptionsDismissButtonStyle {
|
||||||
|
final int _value;
|
||||||
|
const iOSSafariOptionsDismissButtonStyle._internal(this._value);
|
||||||
|
toValue() => _value;
|
||||||
|
|
||||||
|
static const DONE = const iOSSafariOptionsDismissButtonStyle._internal(0);
|
||||||
|
static const CLOSE = const iOSSafariOptionsDismissButtonStyle._internal(1);
|
||||||
|
static const CANCEL = const iOSSafariOptionsDismissButtonStyle._internal(2);
|
||||||
|
}
|
||||||
|
|
||||||
typedef onWebViewCreatedCallback = void Function(InAppWebViewController controller);
|
typedef onWebViewCreatedCallback = void Function(InAppWebViewController controller);
|
||||||
typedef onWebViewLoadStartCallback = void Function(InAppWebViewController controller, String url);
|
typedef onWebViewLoadStartCallback = void Function(InAppWebViewController controller, String url);
|
||||||
typedef onWebViewLoadStopCallback = void Function(InAppWebViewController controller, String url);
|
typedef onWebViewLoadStopCallback = void Function(InAppWebViewController controller, String url);
|
||||||
|
@ -315,4 +489,4 @@ typedef onJsAlertCallback = Future<JsAlertResponse> Function(InAppWebViewControl
|
||||||
typedef onJsConfirmCallback = Future<JsConfirmResponse> Function(InAppWebViewController controller, String message);
|
typedef onJsConfirmCallback = Future<JsConfirmResponse> Function(InAppWebViewController controller, String message);
|
||||||
typedef onJsPromptCallback = Future<JsPromptResponse> Function(InAppWebViewController controller, String message, String defaultValue);
|
typedef onJsPromptCallback = Future<JsPromptResponse> Function(InAppWebViewController controller, String message, String defaultValue);
|
||||||
typedef onSafeBrowsingHitCallback = Future<SafeBrowsingResponse> Function(InAppWebViewController controller, String url, SafeBrowsingThreat threatType);
|
typedef onSafeBrowsingHitCallback = Future<SafeBrowsingResponse> Function(InAppWebViewController controller, String url, SafeBrowsingThreat threatType);
|
||||||
typedef onReceivedHttpAuthRequestCallback = Future<HttpAuthResponse> Function(InAppWebViewController controller, String url, String realm);
|
typedef onReceivedHttpAuthRequestCallback = Future<HttpAuthResponse> Function(InAppWebViewController controller, HttpAuthChallenge challenge);
|
|
@ -1,7 +1,11 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'types.dart';
|
||||||
import 'package:flutter_inappbrowser/src/content_blocker.dart';
|
import 'package:flutter_inappbrowser/src/content_blocker.dart';
|
||||||
|
|
||||||
|
class AndroidOptions {}
|
||||||
|
class iOSOptions {}
|
||||||
|
|
||||||
class WebViewOptions {
|
class WebViewOptions {
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {};
|
return {};
|
||||||
|
@ -14,7 +18,7 @@ class BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
class InAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOptions, iOSOptions {
|
||||||
bool useShouldOverrideUrlLoading;
|
bool useShouldOverrideUrlLoading;
|
||||||
bool useOnLoadResource;
|
bool useOnLoadResource;
|
||||||
bool useOnDownloadStart;
|
bool useOnDownloadStart;
|
||||||
|
@ -66,58 +70,7 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AndroidInAppWebViewCacheMode {
|
class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions, AndroidOptions {
|
||||||
final int _value;
|
|
||||||
const AndroidInAppWebViewCacheMode._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const LOAD_DEFAULT = const AndroidInAppWebViewCacheMode._internal(-1);
|
|
||||||
static const LOAD_CACHE_ELSE_NETWORK = const AndroidInAppWebViewCacheMode._internal(1);
|
|
||||||
static const LOAD_NO_CACHE = const AndroidInAppWebViewCacheMode._internal(2);
|
|
||||||
static const LOAD_CACHE_ONLY = const AndroidInAppWebViewCacheMode._internal(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidInAppWebViewModeMenuItem {
|
|
||||||
final int _value;
|
|
||||||
const AndroidInAppWebViewModeMenuItem._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const MENU_ITEM_NONE = const AndroidInAppWebViewModeMenuItem._internal(0);
|
|
||||||
static const MENU_ITEM_SHARE = const AndroidInAppWebViewModeMenuItem._internal(1);
|
|
||||||
static const MENU_ITEM_WEB_SEARCH = const AndroidInAppWebViewModeMenuItem._internal(2);
|
|
||||||
static const MENU_ITEM_PROCESS_TEXT = const AndroidInAppWebViewModeMenuItem._internal(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidInAppWebViewForceDark {
|
|
||||||
final int _value;
|
|
||||||
const AndroidInAppWebViewForceDark._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const FORCE_DARK_OFF = const AndroidInAppWebViewForceDark._internal(0);
|
|
||||||
static const FORCE_DARK_AUTO = const AndroidInAppWebViewForceDark._internal(1);
|
|
||||||
static const FORCE_DARK_ON = const AndroidInAppWebViewForceDark._internal(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidInAppWebViewLayoutAlgorithm {
|
|
||||||
final String _value;
|
|
||||||
const AndroidInAppWebViewLayoutAlgorithm._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const NORMAL = const AndroidInAppWebViewLayoutAlgorithm._internal("NORMAL");
|
|
||||||
static const TEXT_AUTOSIZING = const AndroidInAppWebViewLayoutAlgorithm._internal("TEXT_AUTOSIZING");
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidInAppWebViewMixedContentMode {
|
|
||||||
final int _value;
|
|
||||||
const AndroidInAppWebViewMixedContentMode._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const MIXED_CONTENT_ALWAYS_ALLOW = const AndroidInAppWebViewMixedContentMode._internal(0);
|
|
||||||
static const MIXED_CONTENT_NEVER_ALLOW = const AndroidInAppWebViewMixedContentMode._internal(1);
|
|
||||||
static const MIXED_CONTENT_COMPATIBILITY_MODE = const AndroidInAppWebViewMixedContentMode._internal(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|
||||||
bool clearSessionCache;
|
bool clearSessionCache;
|
||||||
bool builtInZoomControls;
|
bool builtInZoomControls;
|
||||||
bool displayZoomControls;
|
bool displayZoomControls;
|
||||||
|
@ -211,43 +164,7 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class iOSInAppWebViewSelectionGranularity {
|
class iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions, iOSOptions {
|
||||||
final int _value;
|
|
||||||
const iOSInAppWebViewSelectionGranularity._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const CHARACTER = const iOSInAppWebViewSelectionGranularity._internal(0);
|
|
||||||
static const DYNAMIC = const iOSInAppWebViewSelectionGranularity._internal(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSInAppWebViewDataDetectorTypes {
|
|
||||||
final String _value;
|
|
||||||
const iOSInAppWebViewDataDetectorTypes._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const NONE = const iOSInAppWebViewDataDetectorTypes._internal("NONE");
|
|
||||||
static const PHONE_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("PHONE_NUMBER");
|
|
||||||
static const LINK = const iOSInAppWebViewDataDetectorTypes._internal("LINK");
|
|
||||||
static const ADDRESS = const iOSInAppWebViewDataDetectorTypes._internal("ADDRESS");
|
|
||||||
static const CALENDAR_EVENT = const iOSInAppWebViewDataDetectorTypes._internal("CALENDAR_EVENT");
|
|
||||||
static const TRACKING_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("TRACKING_NUMBER");
|
|
||||||
static const FLIGHT_NUMBER = const iOSInAppWebViewDataDetectorTypes._internal("FLIGHT_NUMBER");
|
|
||||||
static const LOOKUP_SUGGESTION = const iOSInAppWebViewDataDetectorTypes._internal("LOOKUP_SUGGESTION");
|
|
||||||
static const SPOTLIGHT_SUGGESTION = const iOSInAppWebViewDataDetectorTypes._internal("SPOTLIGHT_SUGGESTION");
|
|
||||||
static const ALL = const iOSInAppWebViewDataDetectorTypes._internal("ALL");
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSInAppWebViewUserPreferredContentMode {
|
|
||||||
final int _value;
|
|
||||||
const iOSInAppWebViewUserPreferredContentMode._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const RECOMMENDED = const iOSInAppWebViewUserPreferredContentMode._internal(0);
|
|
||||||
static const MOBILE = const iOSInAppWebViewUserPreferredContentMode._internal(1);
|
|
||||||
static const DESKTOP = const iOSInAppWebViewUserPreferredContentMode._internal(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|
||||||
bool disallowOverScroll;
|
bool disallowOverScroll;
|
||||||
bool enableViewportScale;
|
bool enableViewportScale;
|
||||||
bool suppressesIncrementalRendering;
|
bool suppressesIncrementalRendering;
|
||||||
|
@ -298,7 +215,7 @@ class iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InAppBrowserOptions implements BrowserOptions {
|
class InAppBrowserOptions implements BrowserOptions, AndroidOptions, iOSOptions {
|
||||||
bool hidden;
|
bool hidden;
|
||||||
bool toolbarTop;
|
bool toolbarTop;
|
||||||
String toolbarTopBackgroundColor;
|
String toolbarTopBackgroundColor;
|
||||||
|
@ -319,7 +236,7 @@ class InAppBrowserOptions implements BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AndroidInAppBrowserOptions implements BrowserOptions {
|
class AndroidInAppBrowserOptions implements BrowserOptions, AndroidOptions {
|
||||||
bool hideTitleBar;
|
bool hideTitleBar;
|
||||||
bool closeOnCannotGoBack;
|
bool closeOnCannotGoBack;
|
||||||
bool progressBar;
|
bool progressBar;
|
||||||
|
@ -336,47 +253,19 @@ class AndroidInAppBrowserOptions implements BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class iOSInAppBrowserOptionsPresentationStyle {
|
class iOSInAppBrowserOptions implements BrowserOptions, iOSOptions {
|
||||||
final int _value;
|
|
||||||
const iOSInAppBrowserOptionsPresentationStyle._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const FULL_SCREEN = const iOSInAppBrowserOptionsPresentationStyle._internal(0);
|
|
||||||
static const PAGE_SHEET = const iOSInAppBrowserOptionsPresentationStyle._internal(1);
|
|
||||||
static const FORM_SHEET = const iOSInAppBrowserOptionsPresentationStyle._internal(2);
|
|
||||||
static const CURRENT_CONTEXT = const iOSInAppBrowserOptionsPresentationStyle._internal(3);
|
|
||||||
static const CUSTOM = const iOSInAppBrowserOptionsPresentationStyle._internal(4);
|
|
||||||
static const OVER_FULL_SCREEN = const iOSInAppBrowserOptionsPresentationStyle._internal(5);
|
|
||||||
static const OVER_CURRENT_CONTEXT = const iOSInAppBrowserOptionsPresentationStyle._internal(6);
|
|
||||||
static const POPOVER = const iOSInAppBrowserOptionsPresentationStyle._internal(7);
|
|
||||||
static const NONE = const iOSInAppBrowserOptionsPresentationStyle._internal(8);
|
|
||||||
static const AUTOMATIC = const iOSInAppBrowserOptionsPresentationStyle._internal(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSInAppBrowserOptionsTransitionStyle {
|
|
||||||
final int _value;
|
|
||||||
const iOSInAppBrowserOptionsTransitionStyle._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const COVER_VERTICAL = const iOSInAppBrowserOptionsTransitionStyle._internal(0);
|
|
||||||
static const FLIP_HORIZONTAL = const iOSInAppBrowserOptionsTransitionStyle._internal(1);
|
|
||||||
static const CROSS_DISSOLVE = const iOSInAppBrowserOptionsTransitionStyle._internal(2);
|
|
||||||
static const PARTIAL_CURL = const iOSInAppBrowserOptionsTransitionStyle._internal(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSInAppBrowserOptions implements BrowserOptions {
|
|
||||||
bool toolbarBottom;
|
bool toolbarBottom;
|
||||||
String toolbarBottomBackgroundColor;
|
String toolbarBottomBackgroundColor;
|
||||||
bool toolbarBottomTranslucent;
|
bool toolbarBottomTranslucent;
|
||||||
String closeButtonCaption;
|
String closeButtonCaption;
|
||||||
String closeButtonColor;
|
String closeButtonColor;
|
||||||
iOSInAppBrowserOptionsPresentationStyle presentationStyle;
|
iOSWebViewOptionsPresentationStyle presentationStyle;
|
||||||
iOSInAppBrowserOptionsTransitionStyle transitionStyle;
|
iOSWebViewOptionsTransitionStyle transitionStyle;
|
||||||
bool spinner;
|
bool spinner;
|
||||||
|
|
||||||
iOSInAppBrowserOptions({this.toolbarBottom = true, this.toolbarBottomBackgroundColor = "", this.toolbarBottomTranslucent = true, this.closeButtonCaption = "",
|
iOSInAppBrowserOptions({this.toolbarBottom = true, this.toolbarBottomBackgroundColor = "", this.toolbarBottomTranslucent = true, this.closeButtonCaption = "",
|
||||||
this.closeButtonColor = "", this.presentationStyle = iOSInAppBrowserOptionsPresentationStyle.FULL_SCREEN,
|
this.closeButtonColor = "", this.presentationStyle = iOSWebViewOptionsPresentationStyle.FULL_SCREEN,
|
||||||
this.transitionStyle = iOSInAppBrowserOptionsTransitionStyle.COVER_VERTICAL, this.spinner = true});
|
this.transitionStyle = iOSWebViewOptionsTransitionStyle.COVER_VERTICAL, this.spinner = true});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
@ -393,13 +282,13 @@ class iOSInAppBrowserOptions implements BrowserOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChromeCustomTabsOptions {
|
class ChromeSafariBrowserOptions {
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AndroidChromeCustomTabsOptions implements ChromeCustomTabsOptions {
|
class AndroidChromeCustomTabsOptions implements ChromeSafariBrowserOptions, AndroidOptions {
|
||||||
bool addShareButton;
|
bool addShareButton;
|
||||||
bool showTitle;
|
bool showTitle;
|
||||||
String toolbarBackgroundColor;
|
String toolbarBackgroundColor;
|
||||||
|
@ -420,28 +309,18 @@ class AndroidChromeCustomTabsOptions implements ChromeCustomTabsOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class iOSChromeCustomTabsOptionsDismissButtonStyle {
|
class iOSSafariOptions implements ChromeSafariBrowserOptions, iOSOptions {
|
||||||
final int _value;
|
|
||||||
const iOSChromeCustomTabsOptionsDismissButtonStyle._internal(this._value);
|
|
||||||
toValue() => _value;
|
|
||||||
|
|
||||||
static const DONE = const iOSChromeCustomTabsOptionsDismissButtonStyle._internal(0);
|
|
||||||
static const CLOSE = const iOSChromeCustomTabsOptionsDismissButtonStyle._internal(1);
|
|
||||||
static const CANCEL = const iOSChromeCustomTabsOptionsDismissButtonStyle._internal(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
class iOSChromeCustomTabsOptions implements ChromeCustomTabsOptions {
|
|
||||||
bool entersReaderIfAvailable;
|
bool entersReaderIfAvailable;
|
||||||
bool barCollapsingEnabled;
|
bool barCollapsingEnabled;
|
||||||
iOSChromeCustomTabsOptionsDismissButtonStyle dismissButtonStyle;
|
iOSSafariOptionsDismissButtonStyle dismissButtonStyle;
|
||||||
String preferredBarTintColor;
|
String preferredBarTintColor;
|
||||||
String preferredControlTintColor;
|
String preferredControlTintColor;
|
||||||
iOSInAppBrowserOptionsPresentationStyle presentationStyle;
|
iOSWebViewOptionsPresentationStyle presentationStyle;
|
||||||
iOSInAppBrowserOptionsTransitionStyle transitionStyle;
|
iOSWebViewOptionsTransitionStyle transitionStyle;
|
||||||
|
|
||||||
iOSChromeCustomTabsOptions({this.entersReaderIfAvailable = false, this.barCollapsingEnabled = false, this.dismissButtonStyle = iOSChromeCustomTabsOptionsDismissButtonStyle.DONE,
|
iOSSafariOptions({this.entersReaderIfAvailable = false, this.barCollapsingEnabled = false, this.dismissButtonStyle = iOSSafariOptionsDismissButtonStyle.DONE,
|
||||||
this.preferredBarTintColor = "", this.preferredControlTintColor = "", this.presentationStyle = iOSInAppBrowserOptionsPresentationStyle.FULL_SCREEN,
|
this.preferredBarTintColor = "", this.preferredControlTintColor = "", this.presentationStyle = iOSWebViewOptionsPresentationStyle.FULL_SCREEN,
|
||||||
this.transitionStyle = iOSInAppBrowserOptionsTransitionStyle.COVER_VERTICAL});
|
this.transitionStyle = iOSWebViewOptionsTransitionStyle.COVER_VERTICAL});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
|
Loading…
Reference in New Issue