Added new WebView option minimumFontSize, Added new Android WebView options, Added new iOS WebView options, Added onGeolocationPermissionsShowPrompt event and GeolocationPermissionShowPromptResponse class (available only for Android), updated Android ContentBlocker, updated Android build.gradle compileSdkVersion 29
This commit is contained in:
parent
372b771211
commit
bc6bed1891
|
@ -15,22 +15,39 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlockerHandler.java" 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$/android/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/android/build.gradle" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlocker.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlocker.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlockerTrigger.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/ContentBlocker/ContentBlockerTrigger.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/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/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/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/RequestPermissionHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/RequestPermissionHandler.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/android/app/src/main/AndroidManifest.xml" beforeDir="false" afterPath="$PROJECT_DIR$/example/android/app/src/main/AndroidManifest.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/assets/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/example/assets/index.html" 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/ios/Runner.xcodeproj/project.pbxproj" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner/AppDelegate.swift" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner/AppDelegate.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner/Info.plist" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner/Info.plist" 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/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/lib/webview_example.screen.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/webview_example.screen.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/pubspec.yaml" 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/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.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$/lib/src/chrome_safari_browser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/chrome_safari_browser.dart" 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$/lib/src/content_blocker.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/content_blocker.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/types.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/types.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/src/webview_options.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/src/webview_options.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
||||
<ignored path="$PROJECT_DIR$/.idea/" />
|
||||
|
@ -50,20 +67,20 @@
|
|||
<component name="ExecutionTargetManager" SELECTED_TARGET="Pixel_3_XL_API_24" />
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<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 relative-caret-position="405">
|
||||
<caret line="27" selection-start-line="27" selection-end-line="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="165">
|
||||
<caret line="11" column="55" selection-start-line="11" selection-start-column="37" selection-end-line="11" selection-end-column="55" />
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -71,17 +88,8 @@
|
|||
<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="84">
|
||||
<caret line="93" column="70" selection-start-line="93" selection-start-column="56" selection-end-line="93" selection-end-column="70" />
|
||||
</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="457">
|
||||
<caret line="139" column="27" selection-start-line="139" selection-start-column="13" selection-end-line="139" selection-end-column="27" />
|
||||
<state relative-caret-position="61">
|
||||
<caret line="239" column="47" lean-forward="true" selection-start-line="239" selection-start-column="47" selection-end-line="239" selection-end-column="47" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -90,22 +98,31 @@
|
|||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="135">
|
||||
<caret line="244" column="66" selection-start-line="244" selection-start-column="66" selection-end-line="244" selection-end-column="66" />
|
||||
<state relative-caret-position="233">
|
||||
<caret line="396" column="56" selection-start-line="396" selection-start-column="56" selection-end-line="396" selection-end-column="56" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/chrome_safari_browser.dart">
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="94">
|
||||
<caret line="76" column="41" lean-forward="true" selection-start-line="76" selection-start-column="41" selection-end-line="76" selection-end-column="41" />
|
||||
<state relative-caret-position="302">
|
||||
<caret line="111" column="45" selection-start-line="111" selection-start-column="6" selection-end-line="111" selection-end-column="45" />
|
||||
</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="5265">
|
||||
<caret line="359" column="84" selection-start-line="359" selection-start-column="50" selection-end-line="359" selection-end-column="84" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -116,8 +133,8 @@
|
|||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/content_blocker.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="462">
|
||||
<caret line="124" column="12" selection-start-line="124" selection-start-column="12" selection-end-line="124" selection-end-column="12" />
|
||||
<state relative-caret-position="90">
|
||||
<caret line="6" column="45" selection-start-line="6" selection-start-column="45" selection-end-line="6" selection-end-column="45" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -125,8 +142,8 @@
|
|||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="360">
|
||||
<caret line="35" column="88" selection-start-line="35" selection-start-column="63" selection-end-line="35" selection-end-column="88" />
|
||||
<state relative-caret-position="460">
|
||||
<caret line="63" column="19" lean-forward="true" selection-start-line="63" selection-start-column="19" selection-end-line="63" selection-end-column="19" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -134,8 +151,8 @@
|
|||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/inline_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="335">
|
||||
<caret line="68" column="19" selection-start-line="68" selection-start-column="19" selection-end-line="68" selection-end-column="19" />
|
||||
<state relative-caret-position="439">
|
||||
<caret line="85" column="38" selection-start-line="85" selection-start-column="38" selection-end-line="85" selection-end-column="38" />
|
||||
<folding>
|
||||
<element signature="e#0#22#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -144,10 +161,10 @@
|
|||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/webview_example.screen.dart">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="99" column="26" selection-start-line="99" selection-start-column="26" selection-end-line="99" selection-end-column="26" />
|
||||
<state relative-caret-position="255">
|
||||
<caret line="17" column="2" selection-start-line="17" selection-start-column="2" selection-end-line="17" selection-end-column="2" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
|
@ -167,36 +184,36 @@
|
|||
</component>
|
||||
<component name="FindInProjectRecents">
|
||||
<findStrings>
|
||||
<find>initialUrl</find>
|
||||
<find>InAppBrowser</find>
|
||||
<find>onCustomScheme</find>
|
||||
<find>print</find>
|
||||
<find>onTargetBlank</find>
|
||||
<find>customSchemes</find>
|
||||
<find>customSchemes__</find>
|
||||
<find>toJson</find>
|
||||
<find>onCustom</find>
|
||||
<find>schemes</find>
|
||||
<find>schemes_</find>
|
||||
<find>onDownload</find>
|
||||
<find>resourceCustomSchemes</find>
|
||||
<find>onLoadResourceCustomScheme</find>
|
||||
<find>and return a [Cu</find>
|
||||
<find>encoded in `base64`</find>
|
||||
<find>_</find>
|
||||
<find>_throwIsNotOpened(</find>
|
||||
<find>_throwIsNotOpened</find>
|
||||
<find>_hand</find>
|
||||
<find>_ChannelManager</find>
|
||||
<find>onDo</find>
|
||||
<find>initialData</find>
|
||||
<find>assert</find>
|
||||
<find>Level</find>
|
||||
<find>options</find>
|
||||
<find>options = const {}</find>
|
||||
<find>List<WebViewOptions> options = const []</find>
|
||||
<find>options)</find>
|
||||
<find>WebViewOptions</find>
|
||||
<find>websiteDataStore</find>
|
||||
<find>CacheMode</find>
|
||||
<find>toStr</find>
|
||||
<find>cacheMode</find>
|
||||
<find>disabledActionModeMenuItems</find>
|
||||
<find>AndroidInAppWebViewModeMenuItem</find>
|
||||
<find>fantasyFontFamily</find>
|
||||
<find>AndroidInAppWebViewLayoutAlgorithm</find>
|
||||
<find>loadWithOverviewMode</find>
|
||||
<find>AndroidInAppWebViewCacheMode</find>
|
||||
<find>mixedContentMode</find>
|
||||
<find>disable</find>
|
||||
<find>appCachePath</find>
|
||||
<find>List<Con</find>
|
||||
<find>appCacheEnabled</find>
|
||||
<find>List<Content</find>
|
||||
<find>NOTE</find>
|
||||
<find>onGeolocationPermissionsShowPrompt</find>
|
||||
<find>"onGeolocationPermissionsShowPrompt"</find>
|
||||
<find>databaseEnabled</find>
|
||||
<find>RequestPermission</find>
|
||||
<find>geolocation</find>
|
||||
<find>userInterfaceDirectionPolicy</find>
|
||||
<find>WKSelectionGranularityDynamic</find>
|
||||
<find>minimumFontSize</find>
|
||||
<find>defaultWebpagePreferences</find>
|
||||
<find>contentBlockers</find>
|
||||
<find>preferredContentMode</find>
|
||||
</findStrings>
|
||||
<replaceStrings>
|
||||
<replace>activity.getPreferences(0)</replace>
|
||||
|
@ -232,7 +249,6 @@
|
|||
<option value="$PROJECT_DIR$/example/html/css/style.css" />
|
||||
<option value="$PROJECT_DIR$/example/html/index.html" />
|
||||
<option value="$PROJECT_DIR$/example/ios/Flutter/Generated.xcconfig" />
|
||||
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
||||
<option value="$PROJECT_DIR$/android/gradle/wrapper/gradle-wrapper.properties" />
|
||||
<option value="$PROJECT_DIR$/example/android/app/build.gradle" />
|
||||
<option value="$PROJECT_DIR$/example/android/gradle.properties" />
|
||||
|
@ -246,27 +262,28 @@
|
|||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/android/src/main/AndroidManifest.xml" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.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/channel_manager.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/cookie_manager.dart" />
|
||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/lib/src/web_history.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/in_app_webview.dart" />
|
||||
<option value="$PROJECT_DIR$/example/lib/test.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/content_blocker.dart" />
|
||||
<option value="$PROJECT_DIR$/example/lib/webview_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/example/lib/chrome_safari_example.screen.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/chrome_safari_browser.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/content_blocker.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$/example/lib/webview_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/src/types.dart" />
|
||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/lib/src/webview_options.dart" />
|
||||
<option value="$PROJECT_DIR$/example/ios/Runner/Info.plist" />
|
||||
<option value="$PROJECT_DIR$/example/lib/inline_example.screen.dart" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
|
@ -281,6 +298,67 @@
|
|||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<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="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
</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>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="ios" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="ios" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Runner" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="AndroidView">
|
||||
<subPane>
|
||||
<expand>
|
||||
|
@ -310,61 +388,7 @@
|
|||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
</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>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="lib" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
<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>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
|
@ -515,11 +539,11 @@
|
|||
</todo-panel>
|
||||
</component>
|
||||
<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" />
|
||||
<layout>
|
||||
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.6088957" visible="true" weight="0.15867944" />
|
||||
<window_info id="Structure" order="1" sideWeight="0.39110428" side_tool="true" visible="true" weight="0.15867944" />
|
||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.6049822" visible="true" weight="0.15867944" />
|
||||
<window_info id="Structure" order="1" sideWeight="0.3950178" side_tool="true" visible="true" weight="0.15867944" />
|
||||
<window_info id="Designer" order="2" />
|
||||
<window_info id="Build Variants" order="3" side_tool="true" />
|
||||
<window_info id="Captures" order="4" side_tool="true" weight="0.32936507" />
|
||||
|
@ -529,15 +553,15 @@
|
|||
<window_info id="Resources Explorer" order="8" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" weight="0.32642487" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49361023" visible="true" weight="0.32435232" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49307775" weight="0.38445595" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.34196892" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" sideWeight="0.49946752" weight="0.3284974" />
|
||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5063898" side_tool="true" weight="0.373057" />
|
||||
<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="Terminal" order="10" sideWeight="0.49533224" weight="0.19792746" />
|
||||
<window_info active="true" anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" visible="true" weight="0.41761658" />
|
||||
<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="Dependency Viewer" order="13" weight="0.32800853" />
|
||||
|
@ -565,22 +589,12 @@
|
|||
</ignored-roots>
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/App.framework/Info.plist">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/ios/Flutter/Flutter.framework/Info.plist">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<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/Info.plist">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="511">
|
||||
<caret line="49" column="4" selection-start-line="49" selection-start-column="4" selection-end-line="49" selection-end-column="4" />
|
||||
</state>
|
||||
</provider>
|
||||
</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">
|
||||
|
@ -588,13 +602,6 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="614">
|
||||
<caret line="66" column="44" selection-start-line="66" selection-start-column="6" selection-end-line="66" selection-end-column="44" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/.packages">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
|
@ -716,23 +723,6 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="465">
|
||||
<caret line="31" column="11" selection-start-line="31" selection-start-column="11" selection-end-line="31" selection-end-column="11" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="299">
|
||||
<caret line="21" column="23" selection-start-line="21" selection-start-column="23" selection-end-line="21" selection-end-column="23" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_localhost_server.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="60">
|
||||
|
@ -787,27 +777,10 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="45">
|
||||
<caret line="51" column="52" selection-start-line="51" selection-start-column="52" selection-end-line="51" selection-end-column="52" />
|
||||
<folding>
|
||||
<element signature="e#0#25#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state>
|
||||
<caret line="14" column="16" selection-start-line="14" selection-start-column="16" selection-end-line="14" selection-end-column="16" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="165">
|
||||
<caret line="11" column="55" selection-start-line="11" selection-start-column="37" selection-end-line="11" selection-end-column="55" />
|
||||
<state relative-caret-position="417">
|
||||
<caret line="41" column="66" selection-start-line="41" selection-start-column="61" selection-end-line="41" selection-end-column="66" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -818,81 +791,136 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/chrome_safari_example.screen.dart">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/chrome_safari_browser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="417">
|
||||
<caret line="41" column="66" selection-start-line="41" selection-start-column="61" selection-end-line="41" selection-end-column="66" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="360">
|
||||
<caret line="35" column="88" selection-start-line="35" selection-start-column="63" selection-end-line="35" selection-end-column="88" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/webview_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="99" column="26" selection-start-line="99" selection-start-column="26" selection-end-line="99" selection-end-column="26" />
|
||||
<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/lib/webview_example.screen.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="184">
|
||||
<caret line="81" column="47" selection-start-line="81" selection-start-column="47" selection-end-line="81" selection-end-column="47" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/flutter/packages/flutter/lib/src/material/dialog.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="189">
|
||||
<caret line="690" column="10" selection-start-line="690" selection-start-column="10" selection-end-line="690" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="345">
|
||||
<caret line="23" column="28" selection-start-line="23" selection-start-column="28" selection-end-line="23" selection-end-column="28" />
|
||||
</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="5265">
|
||||
<caret line="359" column="84" selection-start-line="359" selection-start-column="50" selection-end-line="359" selection-end-column="84" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/ios/Podfile">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="990">
|
||||
<caret line="66" column="3" lean-forward="true" selection-start-line="66" selection-start-column="3" selection-end-line="66" selection-end-column="3" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/ios/Runner/Info.plist">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="60">
|
||||
<caret line="4" column="41" selection-start-line="4" selection-start-column="41" selection-end-line="4" selection-end-column="41" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/content_blocker.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="90">
|
||||
<caret line="6" column="45" selection-start-line="6" selection-start-column="45" selection-end-line="6" selection-end-column="45" />
|
||||
</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="335">
|
||||
<caret line="68" column="19" selection-start-line="68" selection-start-column="19" selection-end-line="68" selection-end-column="19" />
|
||||
<state relative-caret-position="439">
|
||||
<caret line="85" column="38" selection-start-line="85" selection-start-column="38" selection-end-line="85" selection-end-column="38" />
|
||||
<folding>
|
||||
<element signature="e#0#22#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/content_blocker.dart">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="462">
|
||||
<caret line="124" column="12" selection-start-line="124" selection-start-column="12" selection-end-line="124" selection-end-column="12" />
|
||||
<state relative-caret-position="255">
|
||||
<caret line="17" column="2" selection-start-line="17" selection-start-column="2" selection-end-line="17" selection-end-column="2" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="457">
|
||||
<caret line="139" column="27" selection-start-line="139" selection-start-column="13" selection-end-line="139" selection-end-column="27" />
|
||||
<state relative-caret-position="460">
|
||||
<caret line="63" column="19" lean-forward="true" selection-start-line="63" selection-start-column="19" selection-end-line="63" selection-end-column="19" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/types.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="302">
|
||||
<caret line="111" column="45" selection-start-line="111" selection-start-column="6" selection-end-line="111" selection-end-column="45" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="61">
|
||||
<caret line="239" column="47" lean-forward="true" selection-start-line="239" selection-start-column="47" selection-end-line="239" selection-end-column="47" />
|
||||
<folding>
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/webview_options.dart">
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="84">
|
||||
<caret line="93" column="70" selection-start-line="93" selection-start-column="56" selection-end-line="93" selection-end-column="70" />
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_browser.dart">
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/in_app_webview.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="135">
|
||||
<caret line="244" column="66" selection-start-line="244" selection-start-column="66" selection-end-line="244" selection-end-column="66" />
|
||||
<state relative-caret-position="233">
|
||||
<caret line="396" column="56" selection-start-line="396" selection-start-column="56" selection-end-line="396" selection-end-column="56" />
|
||||
<folding>
|
||||
<element signature="e#0#20#0" expanded="true" />
|
||||
<element signature="e#0#17#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/src/chrome_safari_browser.dart">
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="94">
|
||||
<caret line="76" column="41" lean-forward="true" 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 relative-caret-position="405">
|
||||
<caret line="27" selection-start-line="27" selection-end-line="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## 1.3.0
|
||||
## 2.0.0
|
||||
|
||||
- Merge "Avoid null pointer exception after webview is disposed" [#116](https://github.com/pichillilorenzo/flutter_inappbrowser/pull/116) (thanks to [robsonfingo](https://github.com/robsonfingo))
|
||||
- Merge "Remove async call in close" [#119](https://github.com/pichillilorenzo/flutter_inappbrowser/pull/119) (thanks to [benfingo](https://github.com/benfingo))
|
||||
|
@ -13,6 +13,10 @@
|
|||
- Added `onLoadResourceCustomScheme` event and `resourceCustomSchemes` option to set custom schemes that WebView must handle to load resources
|
||||
- Added `onTargetBlank` event and `useOnTargetBlank` option to manage links with `target="_blank"`
|
||||
- Added `ContentBlocker`, `ContentBlockerTrigger` and `ContentBlockerAction` classes and the `contentBlockers` option that allows to define a set of rules to use to block content in the WebView
|
||||
- Added new WebView option `minimumFontSize`
|
||||
- Added new Android WebView options: `allowContentAccess`, `allowFileAccess`, `allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`, `appCacheEnabled`, `appCachePath`, `blockNetworkImage`, `blockNetworkLoads`, `cacheMode`, `cursiveFontFamily`, `defaultFixedFontSize`, `defaultFontSize`, `defaultTextEncodingName`, `disabledActionModeMenuItems`, `fantasyFontFamily`, `fixedFontFamily`, `forceDark`, `geolocationEnabled`, `layoutAlgorithm`, `loadWithOverviewMode`, `loadsImagesAutomatically`, `minimumLogicalFontSize`, `needInitialFocus`, `offscreenPreRaster`, `sansSerifFontFamily`, `serifFontFamily`, `standardFontFamily`
|
||||
- Added new iOS WebView options: `applicationNameForUserAgent`, `isFraudulentWebsiteWarningEnabled`, `selectionGranularity`, `dataDetectorTypes`, `preferredContentMode`
|
||||
- Added `onGeolocationPermissionsShowPrompt` event and `GeolocationPermissionShowPromptResponse` class (available only for Android)
|
||||
|
||||
### BREAKING CHANGES
|
||||
- Deleted `WebResourceRequest` class
|
||||
|
@ -20,7 +24,6 @@
|
|||
- Updated `onLoadResource` event
|
||||
- WebView options are now available with the new corresponding classes: `InAppWebViewOptions`, `AndroidInAppWebViewOptions`, `iOSInAppWebViewOptions`, `InAppBrowserOptions`, `AndroidInAppBrowserOptions`, `iOSInAppBrowserOptions`, `AndroidChromeCustomTabsOptions` and `iOSChromeCustomTabsOptions`
|
||||
|
||||
|
||||
## 1.2.1
|
||||
|
||||
- Merge "Add new option to control the contentMode in Android platform" [#101](https://github.com/pichillilorenzo/flutter_inappbrowser/pull/101) (thanks to [DreamBuddy](https://github.com/DreamBuddy))
|
||||
|
|
|
@ -35,7 +35,7 @@ rootProject.allprojects {
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 29
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 17
|
||||
|
|
|
@ -1,235 +1,11 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser.ContentBlocker;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.webkit.WebResourceResponse;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class ContentBlocker {
|
||||
protected static final String LOG_TAG = "ContentBlocker";
|
||||
public ContentBlockerTrigger trigger;
|
||||
public ContentBlockerAction action;
|
||||
|
||||
public static WebResourceResponse checkUrl(final InAppWebView webView, String url, ContentBlockerTriggerResourceType responseResourceType) throws URISyntaxException, InterruptedException {
|
||||
if (webView.options.contentBlockers == null)
|
||||
return null;
|
||||
|
||||
URI u = new URI(url);
|
||||
String host = u.getHost();
|
||||
int port = u.getPort();
|
||||
String scheme = u.getScheme();
|
||||
|
||||
for (Map<String, Map<String, Object>> contentBlocker : webView.options.contentBlockers) {
|
||||
ContentBlockerTrigger trigger = ContentBlockerTrigger.fromMap(contentBlocker.get("trigger"));
|
||||
List<ContentBlockerTriggerResourceType> resourceTypes = trigger.resourceType;
|
||||
|
||||
ContentBlockerAction action = ContentBlockerAction.fromMap(contentBlocker.get("action"));
|
||||
|
||||
Pattern mPattern = Pattern.compile(trigger.urlFilter);
|
||||
Matcher m = mPattern.matcher(url);
|
||||
|
||||
if (m.matches()) {
|
||||
|
||||
if (!resourceTypes.isEmpty() && !resourceTypes.contains(responseResourceType)) {
|
||||
return null;
|
||||
}
|
||||
if (!trigger.ifDomain.isEmpty()) {
|
||||
boolean matchFound = false;
|
||||
for (String domain : trigger.ifDomain) {
|
||||
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matchFound)
|
||||
return null;
|
||||
}
|
||||
if (!trigger.unlessDomain.isEmpty()) {
|
||||
for (String domain : trigger.unlessDomain)
|
||||
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host))
|
||||
return null;
|
||||
}
|
||||
|
||||
final String[] webViewUrl = new String[1];
|
||||
if (!trigger.loadType.isEmpty() || !trigger.ifTopUrl.isEmpty() || !trigger.unlessTopUrl.isEmpty()) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
webViewUrl[0] = webView.getUrl();
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
latch.await();
|
||||
}
|
||||
|
||||
if (!trigger.loadType.isEmpty()) {
|
||||
URI cUrl = new URI(webViewUrl[0]);
|
||||
String cHost = cUrl.getHost();
|
||||
int cPort = cUrl.getPort();
|
||||
String cScheme = cUrl.getScheme();
|
||||
|
||||
if ( (trigger.loadType.contains("first-party") && cHost != null && !(cScheme.equals(scheme) && cHost.equals(host) && cPort == port)) ||
|
||||
(trigger.loadType.contains("third-party") && cHost != null && cHost.equals(host)) )
|
||||
return null;
|
||||
}
|
||||
if (!trigger.ifTopUrl.isEmpty()) {
|
||||
boolean matchFound = false;
|
||||
for (String topUrl : trigger.ifTopUrl) {
|
||||
if (webViewUrl[0].equals(topUrl)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matchFound)
|
||||
return null;
|
||||
}
|
||||
if (!trigger.unlessTopUrl.isEmpty()) {
|
||||
for (String topUrl : trigger.unlessTopUrl)
|
||||
if (webViewUrl[0].equals(topUrl))
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
case BLOCK:
|
||||
return new WebResourceResponse("", "", null);
|
||||
|
||||
case CSS_DISPLAY_NONE:
|
||||
final String jsScript = "function hide () { document.querySelectorAll('" + action.selector + "').forEach(function (item, index) { item.style.display = \"none\"; }); }; hide(); document.addEventListener(\"DOMContentLoaded\", function(event) { hide(); });";
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
Log.d(LOG_TAG, jsScript);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
webView.evaluateJavascript(jsScript, null);
|
||||
} else {
|
||||
webView.loadUrl("javascript:" + jsScript);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case MAKE_HTTPS:
|
||||
if (url.startsWith("http://")) {
|
||||
String urlHttps = url.replace("http://", "https://");
|
||||
|
||||
Request mRequest = new Request.Builder().url(urlHttps).build();
|
||||
Response response = null;
|
||||
|
||||
try {
|
||||
|
||||
response = webView.httpClient.newCall(mRequest).execute();
|
||||
byte[] dataBytes = response.body().bytes();
|
||||
InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
|
||||
String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.close();
|
||||
|
||||
return new WebResourceResponse(contentType, encoding, dataStream);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static WebResourceResponse checkUrl(final InAppWebView webView, String url) throws URISyntaxException, InterruptedException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(webView, url);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
}
|
||||
|
||||
public static WebResourceResponse checkUrl(final InAppWebView webView, String url, String contentType) throws URISyntaxException, InterruptedException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
}
|
||||
|
||||
|
||||
public static ContentBlockerTriggerResourceType getResourceTypeFromUrl(InAppWebView webView, String url) {
|
||||
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
|
||||
|
||||
// make an HTTP "HEAD" request to the server for that URL. This will not return the full content of the URL.
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
Request mRequest = new Request.Builder().url(url).head().build();
|
||||
Response response = null;
|
||||
try {
|
||||
response = webView.httpClient.newCall(mRequest).execute();
|
||||
|
||||
if (response.header("content-type") != null) {
|
||||
String[] contentTypeSplitted = response.header("content-type").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.close();
|
||||
responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
return responseResourceType;
|
||||
}
|
||||
|
||||
public static ContentBlockerTriggerResourceType getResourceTypeFromContentType(String contentType) {
|
||||
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
|
||||
if (contentType.equals("text/css")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.STYLE_SHEET;
|
||||
} else if (contentType.equals("image/svg+xml")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.SVG_DOCUMENT;
|
||||
} else if (contentType.startsWith("image/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.IMAGE;
|
||||
} else if (contentType.startsWith("font/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.FONT;
|
||||
} else if (contentType.startsWith("audio/") || contentType.startsWith("video/") || contentType.equals("application/ogg")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.MEDIA;
|
||||
} else if (contentType.endsWith("javascript")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.SCRIPT;
|
||||
} else if (contentType.startsWith("text/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.DOCUMENT;
|
||||
}
|
||||
|
||||
return responseResourceType;
|
||||
public ContentBlocker (ContentBlockerTrigger trigger, ContentBlockerAction action) {
|
||||
this.trigger = trigger;
|
||||
this.action = action;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser.ContentBlocker;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.webkit.WebResourceResponse;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class ContentBlockerHandler {
|
||||
protected static final String LOG_TAG = "ContentBlockerHandler";
|
||||
|
||||
protected List<ContentBlocker> ruleList = new ArrayList<>();
|
||||
|
||||
public ContentBlockerHandler() {}
|
||||
|
||||
public ContentBlockerHandler(List<ContentBlocker> ruleList) {
|
||||
this.ruleList = ruleList;
|
||||
}
|
||||
|
||||
public List<ContentBlocker> getRuleList() {
|
||||
return this.ruleList;
|
||||
}
|
||||
|
||||
public void setRuleList(List<ContentBlocker> newRuleList) {
|
||||
this.ruleList = newRuleList;
|
||||
}
|
||||
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url, ContentBlockerTriggerResourceType responseResourceType) throws URISyntaxException, InterruptedException {
|
||||
if (webView.options.contentBlockers == null)
|
||||
return null;
|
||||
|
||||
URI u = new URI(url);
|
||||
String host = u.getHost();
|
||||
int port = u.getPort();
|
||||
String scheme = u.getScheme();
|
||||
// thread safe copy list
|
||||
List<ContentBlocker> ruleListCopy = new CopyOnWriteArrayList<ContentBlocker>(ruleList);
|
||||
|
||||
for (ContentBlocker contentBlocker : ruleListCopy) {
|
||||
ContentBlockerTrigger trigger = contentBlocker.trigger;
|
||||
List<ContentBlockerTriggerResourceType> resourceTypes = trigger.resourceType;
|
||||
|
||||
ContentBlockerAction action = contentBlocker.action;
|
||||
|
||||
Matcher m = trigger.urlFilterPatternCompiled.matcher(url);
|
||||
if (m.matches()) {
|
||||
|
||||
if (!resourceTypes.isEmpty() && !resourceTypes.contains(responseResourceType)) {
|
||||
return null;
|
||||
}
|
||||
if (!trigger.ifDomain.isEmpty()) {
|
||||
boolean matchFound = false;
|
||||
for (String domain : trigger.ifDomain) {
|
||||
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matchFound)
|
||||
return null;
|
||||
}
|
||||
if (!trigger.unlessDomain.isEmpty()) {
|
||||
for (String domain : trigger.unlessDomain)
|
||||
if ((domain.startsWith("*") && host.endsWith(domain.replace("*", ""))) || domain.equals(host))
|
||||
return null;
|
||||
}
|
||||
|
||||
final String[] webViewUrl = new String[1];
|
||||
if (!trigger.loadType.isEmpty() || !trigger.ifTopUrl.isEmpty() || !trigger.unlessTopUrl.isEmpty()) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
webViewUrl[0] = webView.getUrl();
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
latch.await();
|
||||
}
|
||||
|
||||
if (!trigger.loadType.isEmpty()) {
|
||||
URI cUrl = new URI(webViewUrl[0]);
|
||||
String cHost = cUrl.getHost();
|
||||
int cPort = cUrl.getPort();
|
||||
String cScheme = cUrl.getScheme();
|
||||
|
||||
if ( (trigger.loadType.contains("first-party") && cHost != null && !(cScheme.equals(scheme) && cHost.equals(host) && cPort == port)) ||
|
||||
(trigger.loadType.contains("third-party") && cHost != null && cHost.equals(host)) )
|
||||
return null;
|
||||
}
|
||||
if (!trigger.ifTopUrl.isEmpty()) {
|
||||
boolean matchFound = false;
|
||||
for (String topUrl : trigger.ifTopUrl) {
|
||||
if (webViewUrl[0].equals(topUrl)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matchFound)
|
||||
return null;
|
||||
}
|
||||
if (!trigger.unlessTopUrl.isEmpty()) {
|
||||
for (String topUrl : trigger.unlessTopUrl)
|
||||
if (webViewUrl[0].equals(topUrl))
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
case BLOCK:
|
||||
return new WebResourceResponse("", "", null);
|
||||
|
||||
case CSS_DISPLAY_NONE:
|
||||
final String jsScript = "function hide () { document.querySelectorAll('" + action.selector + "').forEach(function (item, index) { item.style.display = \"none\"; }); }; hide(); document.addEventListener(\"DOMContentLoaded\", function(event) { hide(); });";
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
Log.d(LOG_TAG, jsScript);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
webView.evaluateJavascript(jsScript, null);
|
||||
} else {
|
||||
webView.loadUrl("javascript:" + jsScript);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case MAKE_HTTPS:
|
||||
if (url.startsWith("http://")) {
|
||||
String urlHttps = url.replace("http://", "https://");
|
||||
|
||||
Request mRequest = new Request.Builder().url(urlHttps).build();
|
||||
Response response = null;
|
||||
|
||||
try {
|
||||
|
||||
response = webView.httpClient.newCall(mRequest).execute();
|
||||
byte[] dataBytes = response.body().bytes();
|
||||
InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
|
||||
String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.close();
|
||||
|
||||
return new WebResourceResponse(contentType, encoding, dataStream);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url) throws URISyntaxException, InterruptedException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(webView, url);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
}
|
||||
|
||||
public WebResourceResponse checkUrl(final InAppWebView webView, String url, String contentType) throws URISyntaxException, InterruptedException {
|
||||
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
return checkUrl(webView, url, responseResourceType);
|
||||
}
|
||||
|
||||
|
||||
public ContentBlockerTriggerResourceType getResourceTypeFromUrl(InAppWebView webView, String url) {
|
||||
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
|
||||
|
||||
// make an HTTP "HEAD" request to the server for that URL. This will not return the full content of the URL.
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
Request mRequest = new Request.Builder().url(url).head().build();
|
||||
Response response = null;
|
||||
try {
|
||||
response = webView.httpClient.newCall(mRequest).execute();
|
||||
|
||||
if (response.header("content-type") != null) {
|
||||
String[] contentTypeSplitted = response.header("content-type").split(";");
|
||||
|
||||
String contentType = contentTypeSplitted[0].trim();
|
||||
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
|
||||
? contentTypeSplitted[1].replace("charset=", "").trim()
|
||||
: "utf-8";
|
||||
|
||||
response.close();
|
||||
responseResourceType = getResourceTypeFromContentType(contentType);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
return responseResourceType;
|
||||
}
|
||||
|
||||
public ContentBlockerTriggerResourceType getResourceTypeFromContentType(String contentType) {
|
||||
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
|
||||
if (contentType.equals("text/css")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.STYLE_SHEET;
|
||||
} else if (contentType.equals("image/svg+xml")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.SVG_DOCUMENT;
|
||||
} else if (contentType.startsWith("image/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.IMAGE;
|
||||
} else if (contentType.startsWith("font/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.FONT;
|
||||
} else if (contentType.startsWith("audio/") || contentType.startsWith("video/") || contentType.equals("application/ogg")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.MEDIA;
|
||||
} else if (contentType.endsWith("javascript")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.SCRIPT;
|
||||
} else if (contentType.startsWith("text/")) {
|
||||
responseResourceType = ContentBlockerTriggerResourceType.DOCUMENT;
|
||||
}
|
||||
|
||||
return responseResourceType;
|
||||
}
|
||||
}
|
|
@ -3,10 +3,12 @@ package com.pichillilorenzo.flutter_inappbrowser.ContentBlocker;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ContentBlockerTrigger {
|
||||
|
||||
public String urlFilter;
|
||||
public Pattern urlFilterPatternCompiled;
|
||||
public Boolean urlFilterIsCaseSensitive;
|
||||
public List<ContentBlockerTriggerResourceType> resourceType = new ArrayList<>();
|
||||
public List<String> ifDomain = new ArrayList<>();
|
||||
|
@ -18,6 +20,8 @@ public class ContentBlockerTrigger {
|
|||
public ContentBlockerTrigger(String urlFilter, Boolean urlFilterIsCaseSensitive, List<ContentBlockerTriggerResourceType> resourceType, List<String> ifDomain,
|
||||
List<String> unlessDomain, List<String> loadType, List<String> ifTopUrl, List<String> unlessTopUrl) {
|
||||
this.urlFilter = urlFilter;
|
||||
this.urlFilterPatternCompiled = Pattern.compile(this.urlFilter);
|
||||
|
||||
this.resourceType = resourceType != null ? resourceType : this.resourceType;
|
||||
this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive != null ? urlFilterIsCaseSensitive : false;
|
||||
this.ifDomain = ifDomain != null ? ifDomain : this.ifDomain;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
@ -191,7 +192,10 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
|||
result.success((webView != null) && webView.isLoading());
|
||||
break;
|
||||
case "takeScreenshot":
|
||||
result.success((webView != null) ? webView.takeScreenshot() : null);
|
||||
if (webView != null)
|
||||
webView.takeScreenshot(result);
|
||||
else
|
||||
result.error(LOG_TAG, "webView is null", null);
|
||||
break;
|
||||
case "setOptions":
|
||||
if (webView != null) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
@ -9,6 +11,7 @@ import android.os.Build;
|
|||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.webkit.ConsoleMessage;
|
||||
import android.webkit.GeolocationPermissions;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebView;
|
||||
|
@ -17,6 +20,7 @@ import android.widget.FrameLayout;
|
|||
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.RequestPermissionHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -98,6 +102,34 @@ public class InAppWebChromeClient extends WebChromeClient {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGeolocationPermissionsShowPrompt (final String origin, final GeolocationPermissions.Callback callback) {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("origin", origin);
|
||||
getChannel().invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object o) {
|
||||
Map<String, Object> response = (Map<String, Object>) o;
|
||||
if (response != null)
|
||||
callback.invoke((String) response.get("origin"),(Boolean) response.get("allow"),(Boolean) response.get("retain"));
|
||||
else
|
||||
callback.invoke(origin,false,false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String s, String s1, Object o) {
|
||||
callback.invoke(origin,false,false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notImplemented() {
|
||||
callback.invoke(origin,false,false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
|
|
|
@ -18,6 +18,10 @@ import android.webkit.WebHistoryItem;
|
|||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappbrowser.ContentBlocker.ContentBlocker;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.ContentBlocker.ContentBlockerAction;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.ContentBlocker.ContentBlockerHandler;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.ContentBlocker.ContentBlockerTrigger;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
|
||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
||||
|
@ -34,7 +38,6 @@ import java.util.Map;
|
|||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class InAppWebView extends WebView {
|
||||
|
@ -51,6 +54,7 @@ public class InAppWebView extends WebView {
|
|||
public boolean isLoading = false;
|
||||
public OkHttpClient httpClient;
|
||||
int okHttpClientCacheSize = 10 * 1024 * 1024; // 10MB
|
||||
public ContentBlockerHandler contentBlockerHandler = new ContentBlockerHandler();
|
||||
|
||||
static final String consoleLogJS = "(function() {" +
|
||||
" var oldLogs = {" +
|
||||
|
@ -115,12 +119,11 @@ public class InAppWebView extends WebView {
|
|||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
Log.d(LOG_TAG, "RELOAD");
|
||||
}
|
||||
|
||||
public void prepare() {
|
||||
|
||||
final Activity activity = (inAppBrowserActivity != null) ? inAppBrowserActivity : registrar.activity();
|
||||
final Activity activity = (inAppBrowserActivity != null) ? inAppBrowserActivity : registrar.activity().getParent();
|
||||
|
||||
boolean isFromInAppBrowserActivity = inAppBrowserActivity != null;
|
||||
|
||||
|
@ -173,24 +176,53 @@ public class InAppWebView extends WebView {
|
|||
setVerticalScrollBarEnabled(options.verticalScrollBarEnabled);
|
||||
setHorizontalScrollBarEnabled(options.horizontalScrollBarEnabled);
|
||||
|
||||
if (options.transparentBackground) {
|
||||
if (options.transparentBackground)
|
||||
setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
if (!options.mixedContentMode.isEmpty()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
switch (options.mixedContentMode) {
|
||||
case "MIXED_CONTENT_COMPATIBILITY_MODE":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
break;
|
||||
case "MIXED_CONTENT_ALWAYS_ALLOW":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
||||
break;
|
||||
case "MIXED_CONTENT_NEVER_ALLOW":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && options.mixedContentMode != null)
|
||||
settings.setMixedContentMode(options.mixedContentMode);
|
||||
|
||||
settings.setAllowContentAccess(options.allowContentAccess);
|
||||
settings.setAllowFileAccess(options.allowFileAccess);
|
||||
settings.setAllowFileAccessFromFileURLs(options.allowFileAccessFromFileURLs);
|
||||
settings.setAllowUniversalAccessFromFileURLs(options.allowUniversalAccessFromFileURLs);
|
||||
settings.setAppCacheEnabled(options.appCacheEnabled);
|
||||
if (options.appCachePath != null && !options.appCachePath.isEmpty() && options.appCacheEnabled)
|
||||
settings.setAppCachePath(options.appCachePath);
|
||||
settings.setBlockNetworkImage(options.blockNetworkImage);
|
||||
settings.setBlockNetworkLoads(options.blockNetworkLoads);
|
||||
if (options.cacheMode != null)
|
||||
settings.setCacheMode(options.cacheMode);
|
||||
settings.setCursiveFontFamily(options.cursiveFontFamily);
|
||||
settings.setDefaultFixedFontSize(options.defaultFixedFontSize);
|
||||
settings.setDefaultFontSize(options.defaultFontSize);
|
||||
settings.setDefaultTextEncodingName(options.defaultTextEncodingName);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && options.disabledActionModeMenuItems != null)
|
||||
settings.setDisabledActionModeMenuItems(options.disabledActionModeMenuItems);
|
||||
settings.setFantasyFontFamily(options.fantasyFontFamily);
|
||||
settings.setFixedFontFamily(options.fixedFontFamily);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && options.forceDark != null)
|
||||
settings.setForceDark(options.forceDark);
|
||||
settings.setGeolocationEnabled(options.geolocationEnabled);
|
||||
if (options.layoutAlgorithm != null)
|
||||
settings.setLayoutAlgorithm(options.layoutAlgorithm);
|
||||
settings.setLoadWithOverviewMode(options.loadWithOverviewMode);
|
||||
settings.setLoadsImagesAutomatically(options.loadsImagesAutomatically);
|
||||
settings.setMinimumFontSize(options.minimumFontSize);
|
||||
settings.setMinimumLogicalFontSize(options.minimumLogicalFontSize);
|
||||
settings.setNeedInitialFocus(options.needInitialFocus);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
settings.setOffscreenPreRaster(options.offscreenPreRaster);
|
||||
settings.setSansSerifFontFamily(options.sansSerifFontFamily);
|
||||
settings.setSerifFontFamily(options.serifFontFamily);
|
||||
settings.setStandardFontFamily(options.standardFontFamily);
|
||||
|
||||
contentBlockerHandler.getRuleList().clear();
|
||||
for (Map<String, Map<String, Object>> contentBlocker : options.contentBlockers) {
|
||||
// compile ContentBlockerTrigger urlFilter
|
||||
ContentBlockerTrigger trigger = ContentBlockerTrigger.fromMap(contentBlocker.get("trigger"));
|
||||
ContentBlockerAction action = ContentBlockerAction.fromMap(contentBlocker.get("action"));
|
||||
contentBlockerHandler.getRuleList().add(new ContentBlocker(trigger, action));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,29 +318,36 @@ public class InAppWebView extends WebView {
|
|||
clearFormData();
|
||||
}
|
||||
|
||||
public byte[] takeScreenshot() {
|
||||
float scale = getResources().getDisplayMetrics().density; // getScale();
|
||||
int height = (int) (getContentHeight() * scale + 0.5);
|
||||
public void takeScreenshot(final MethodChannel.Result result) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
float scale = getResources().getDisplayMetrics().density; // getScale();
|
||||
int height = (int) (getContentHeight() * scale + 0.5);
|
||||
|
||||
Bitmap b = Bitmap.createBitmap( getWidth(),
|
||||
height, Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(b);
|
||||
Bitmap b = Bitmap.createBitmap( getWidth(),
|
||||
height, Bitmap.Config.ARGB_8888);
|
||||
Canvas c = new Canvas(b);
|
||||
|
||||
draw(c);
|
||||
int scrollOffset = (getScrollY() + getMeasuredHeight() > b.getHeight())
|
||||
? b.getHeight() : getScrollY();
|
||||
Bitmap resized = Bitmap.createBitmap(
|
||||
b, 0, scrollOffset, b.getWidth(), getMeasuredHeight());
|
||||
draw(c);
|
||||
int scrollOffset = (getScrollY() + getMeasuredHeight() > b.getHeight())
|
||||
? b.getHeight() : getScrollY();
|
||||
Bitmap resized = Bitmap.createBitmap(
|
||||
b, 0, scrollOffset, b.getWidth(), getMeasuredHeight());
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
resized.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
resized.recycle();
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
resized.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
}
|
||||
resized.recycle();
|
||||
result.success(byteArrayOutputStream.toByteArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOptions(InAppWebViewOptions newOptions, HashMap<String, Object> newOptionsMap) {
|
||||
|
@ -353,7 +392,7 @@ public class InAppWebView extends WebView {
|
|||
if (newOptionsMap.get("supportZoom") != null && options.supportZoom != newOptions.supportZoom)
|
||||
settings.setSupportZoom(newOptions.supportZoom);
|
||||
|
||||
if (newOptionsMap.get("textZoom") != null && options.textZoom != newOptions.textZoom)
|
||||
if (newOptionsMap.get("textZoom") != null && !options.textZoom.equals(newOptions.textZoom))
|
||||
settings.setTextZoom(newOptions.textZoom);
|
||||
|
||||
if (newOptionsMap.get("verticalScrollBarEnabled") != null && options.verticalScrollBarEnabled != newOptions.verticalScrollBarEnabled)
|
||||
|
@ -370,21 +409,9 @@ public class InAppWebView extends WebView {
|
|||
}
|
||||
}
|
||||
|
||||
if (newOptionsMap.get("mixedContentMode") != null && !options.mixedContentMode.equals(newOptions.mixedContentMode)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
switch (newOptions.mixedContentMode) {
|
||||
case "MIXED_CONTENT_COMPATIBILITY_MODE":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
break;
|
||||
case "MIXED_CONTENT_ALWAYS_ALLOW":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
||||
break;
|
||||
case "MIXED_CONTENT_NEVER_ALLOW":
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
if (newOptionsMap.get("mixedContentMode") != null && !options.mixedContentMode.equals(newOptions.mixedContentMode))
|
||||
settings.setMixedContentMode(newOptions.mixedContentMode);
|
||||
|
||||
if (newOptionsMap.get("useOnTargetBlank") != null && options.useOnTargetBlank != newOptions.useOnTargetBlank)
|
||||
settings.setSupportMultipleWindows(newOptions.useOnTargetBlank);
|
||||
|
@ -397,6 +424,104 @@ public class InAppWebView extends WebView {
|
|||
}
|
||||
}
|
||||
|
||||
if (newOptionsMap.get("allowContentAccess") != null && options.allowContentAccess != newOptions.allowContentAccess)
|
||||
settings.setAllowContentAccess(newOptions.allowContentAccess);
|
||||
|
||||
if (newOptionsMap.get("allowFileAccess") != null && options.allowFileAccess != newOptions.allowFileAccess)
|
||||
settings.setAllowFileAccess(newOptions.allowFileAccess);
|
||||
|
||||
if (newOptionsMap.get("allowFileAccessFromFileURLs") != null && options.allowFileAccessFromFileURLs != newOptions.allowFileAccessFromFileURLs)
|
||||
settings.setAllowFileAccessFromFileURLs(newOptions.allowFileAccessFromFileURLs);
|
||||
|
||||
if (newOptionsMap.get("allowUniversalAccessFromFileURLs") != null && options.allowUniversalAccessFromFileURLs != newOptions.allowUniversalAccessFromFileURLs)
|
||||
settings.setAllowUniversalAccessFromFileURLs(newOptions.allowUniversalAccessFromFileURLs);
|
||||
|
||||
if (newOptionsMap.get("appCacheEnabled") != null && options.appCacheEnabled != newOptions.appCacheEnabled)
|
||||
settings.setAppCacheEnabled(newOptions.appCacheEnabled);
|
||||
|
||||
if (newOptionsMap.get("appCachePath") != null && !options.appCachePath.equals(newOptions.appCachePath))
|
||||
if (newOptions.appCacheEnabled)
|
||||
settings.setAppCachePath(newOptions.appCachePath);
|
||||
|
||||
if (newOptionsMap.get("blockNetworkImage") != null && options.blockNetworkImage != newOptions.blockNetworkImage)
|
||||
settings.setBlockNetworkImage(newOptions.blockNetworkImage);
|
||||
|
||||
if (newOptionsMap.get("blockNetworkLoads") != null && options.blockNetworkLoads != newOptions.blockNetworkLoads)
|
||||
settings.setBlockNetworkLoads(newOptions.blockNetworkLoads);
|
||||
|
||||
if (newOptionsMap.get("cacheMode") != null && !options.cacheMode.equals(newOptions.cacheMode))
|
||||
settings.setCacheMode(newOptions.cacheMode);
|
||||
|
||||
if (newOptionsMap.get("cursiveFontFamily") != null && !options.cursiveFontFamily.equals(newOptions.cursiveFontFamily))
|
||||
settings.setCursiveFontFamily(newOptions.cursiveFontFamily);
|
||||
|
||||
if (newOptionsMap.get("defaultFixedFontSize") != null && !options.defaultFixedFontSize.equals(newOptions.defaultFixedFontSize))
|
||||
settings.setDefaultFixedFontSize(newOptions.defaultFixedFontSize);
|
||||
|
||||
if (newOptionsMap.get("defaultFontSize") != null && !options.defaultFontSize.equals(newOptions.defaultFontSize))
|
||||
settings.setDefaultFontSize(newOptions.defaultFontSize);
|
||||
|
||||
if (newOptionsMap.get("defaultTextEncodingName") != null && !options.defaultTextEncodingName.equals(newOptions.defaultTextEncodingName))
|
||||
settings.setDefaultTextEncodingName(newOptions.defaultTextEncodingName);
|
||||
|
||||
if (newOptionsMap.get("disabledActionModeMenuItems") != null && !options.disabledActionModeMenuItems.equals(newOptions.disabledActionModeMenuItems))
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
settings.setDisabledActionModeMenuItems(newOptions.disabledActionModeMenuItems);
|
||||
|
||||
if (newOptionsMap.get("fantasyFontFamily") != null && !options.fantasyFontFamily.equals(newOptions.fantasyFontFamily))
|
||||
settings.setFantasyFontFamily(newOptions.fantasyFontFamily);
|
||||
|
||||
if (newOptionsMap.get("fixedFontFamily") != null && !options.fixedFontFamily.equals(newOptions.fixedFontFamily))
|
||||
settings.setFixedFontFamily(newOptions.fixedFontFamily);
|
||||
|
||||
if (newOptionsMap.get("forceDark") != null && !options.forceDark.equals(newOptions.forceDark))
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
settings.setForceDark(newOptions.forceDark);
|
||||
|
||||
if (newOptionsMap.get("geolocationEnabled") != null && options.geolocationEnabled != newOptions.geolocationEnabled)
|
||||
settings.setGeolocationEnabled(newOptions.geolocationEnabled);
|
||||
|
||||
if (newOptionsMap.get("layoutAlgorithm") != null && options.layoutAlgorithm != newOptions.layoutAlgorithm)
|
||||
settings.setLayoutAlgorithm(newOptions.layoutAlgorithm);
|
||||
|
||||
if (newOptionsMap.get("loadWithOverviewMode") != null && options.loadWithOverviewMode != newOptions.loadWithOverviewMode)
|
||||
settings.setLoadWithOverviewMode(newOptions.loadWithOverviewMode);
|
||||
|
||||
if (newOptionsMap.get("loadsImagesAutomatically") != null && options.loadsImagesAutomatically != newOptions.loadsImagesAutomatically)
|
||||
settings.setLoadsImagesAutomatically(newOptions.loadsImagesAutomatically);
|
||||
|
||||
if (newOptionsMap.get("minimumFontSize") != null && !options.minimumFontSize.equals(newOptions.minimumFontSize))
|
||||
settings.setMinimumFontSize(newOptions.minimumFontSize);
|
||||
|
||||
if (newOptionsMap.get("minimumLogicalFontSize") != null && !options.minimumLogicalFontSize.equals(newOptions.minimumLogicalFontSize))
|
||||
settings.setMinimumLogicalFontSize(newOptions.minimumLogicalFontSize);
|
||||
|
||||
if (newOptionsMap.get("needInitialFocus") != null && options.needInitialFocus != newOptions.needInitialFocus)
|
||||
settings.setNeedInitialFocus(newOptions.needInitialFocus);
|
||||
|
||||
if (newOptionsMap.get("offscreenPreRaster") != null && options.offscreenPreRaster != newOptions.offscreenPreRaster)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
settings.setOffscreenPreRaster(newOptions.offscreenPreRaster);
|
||||
|
||||
if (newOptionsMap.get("sansSerifFontFamily") != null && !options.sansSerifFontFamily.equals(newOptions.sansSerifFontFamily))
|
||||
settings.setSansSerifFontFamily(newOptions.sansSerifFontFamily);
|
||||
|
||||
if (newOptionsMap.get("serifFontFamily") != null && !options.serifFontFamily.equals(newOptions.serifFontFamily))
|
||||
settings.setSerifFontFamily(newOptions.serifFontFamily);
|
||||
|
||||
if (newOptionsMap.get("standardFontFamily") != null && !options.standardFontFamily.equals(newOptions.standardFontFamily))
|
||||
settings.setStandardFontFamily(newOptions.standardFontFamily);
|
||||
|
||||
if (newOptions.contentBlockers != null) {
|
||||
contentBlockerHandler.getRuleList().clear();
|
||||
for (Map<String, Map<String, Object>> contentBlocker : newOptions.contentBlockers) {
|
||||
// compile ContentBlockerTrigger urlFilter
|
||||
ContentBlockerTrigger trigger = ContentBlockerTrigger.fromMap(contentBlocker.get("trigger"));
|
||||
ContentBlockerAction action = ContentBlockerAction.fromMap(contentBlocker.get("action"));
|
||||
contentBlockerHandler.getRuleList().add(new ContentBlocker(trigger, action));
|
||||
}
|
||||
}
|
||||
|
||||
options = newOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
Map<String, String> res = (Map<String, String>) flutterResult.result;
|
||||
WebResourceResponse response = null;
|
||||
try {
|
||||
response = ContentBlocker.checkUrl(webView, url, res.get("content-type"));
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, url, res.get("content-type"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
|
@ -349,7 +349,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
|
||||
WebResourceResponse response = null;
|
||||
try {
|
||||
response = ContentBlocker.checkUrl(webView, url);
|
||||
response = webView.contentBlockerHandler.checkUrl(webView, url);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
|
||||
|
||||
import android.webkit.WebSettings;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappbrowser.Options;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -19,11 +21,12 @@ public class InAppWebViewOptions extends Options {
|
|||
public boolean javaScriptEnabled = true;
|
||||
public boolean javaScriptCanOpenWindowsAutomatically = false;
|
||||
public boolean mediaPlaybackRequiresUserGesture = true;
|
||||
public int textZoom = 100;
|
||||
public Integer textZoom = 100;
|
||||
public boolean verticalScrollBarEnabled = true;
|
||||
public boolean horizontalScrollBarEnabled = true;
|
||||
public List<String> resourceCustomSchemes = new ArrayList<>();
|
||||
public List<Map<String, Map<String, Object>>> contentBlockers = new ArrayList<>();
|
||||
public Integer minimumFontSize = 8;
|
||||
|
||||
public boolean clearSessionCache = false;
|
||||
public boolean builtInZoomControls = false;
|
||||
|
@ -34,5 +37,32 @@ public class InAppWebViewOptions extends Options {
|
|||
public boolean useWideViewPort = true;
|
||||
public boolean safeBrowsingEnabled = true;
|
||||
public boolean transparentBackground = false;
|
||||
public String mixedContentMode = "";
|
||||
public Integer mixedContentMode;
|
||||
public boolean allowContentAccess = true;
|
||||
public boolean allowFileAccess = true;
|
||||
public boolean allowFileAccessFromFileURLs = true;
|
||||
public boolean allowUniversalAccessFromFileURLs = true;
|
||||
public boolean appCacheEnabled = true;
|
||||
public String appCachePath;
|
||||
public boolean blockNetworkImage = false;
|
||||
public boolean blockNetworkLoads = false;
|
||||
public Integer cacheMode = WebSettings.LOAD_DEFAULT;
|
||||
public String cursiveFontFamily = "cursive";
|
||||
public Integer defaultFixedFontSize = 16;
|
||||
public Integer defaultFontSize = 16;
|
||||
public String defaultTextEncodingName = "UTF-8";
|
||||
public Integer disabledActionModeMenuItems;
|
||||
public String fantasyFontFamily = "fantasy";
|
||||
public String fixedFontFamily = "monospace";
|
||||
public Integer forceDark = 0; // WebSettings.FORCE_DARK_OFF
|
||||
public boolean geolocationEnabled = true;
|
||||
public WebSettings.LayoutAlgorithm layoutAlgorithm;
|
||||
public boolean loadWithOverviewMode = true;
|
||||
public boolean loadsImagesAutomatically = true;
|
||||
public Integer minimumLogicalFontSize = 8;
|
||||
public boolean needInitialFocus = true;
|
||||
public boolean offscreenPreRaster = false;
|
||||
public String sansSerifFontFamily = "sans-serif";
|
||||
public String serifFontFamily = "sans-serif";
|
||||
public String standardFontFamily = "sans-serif";
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.pichillilorenzo.flutter_inappbrowser;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
@ -15,8 +17,6 @@ public abstract class RequestPermissionHandler implements ActivityCompat.OnReque
|
|||
|
||||
private static Map<Integer, List<Runnable>> actionDictionary = new HashMap<>();
|
||||
|
||||
public static int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 1;
|
||||
|
||||
public static void checkAndRun(Activity activity, String permission, int requestCode, Runnable runnable) {
|
||||
|
||||
int permissionCheck = ContextCompat.checkSelfPermission(activity.getApplicationContext(), permission);
|
||||
|
@ -34,6 +34,7 @@ public abstract class RequestPermissionHandler implements ActivityCompat.OnReque
|
|||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
Log.d("asdasd", "\n\na asd asd \n\n");
|
||||
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
||||
List<Runnable> callbacks = actionDictionary.get(requestCode);
|
||||
for (Runnable runnable : callbacks) {
|
||||
|
|
|
@ -91,6 +91,5 @@ public class Util {
|
|||
result = r;
|
||||
error = e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_GPS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
|
|
|
@ -56,6 +56,15 @@
|
|||
});
|
||||
$(document).ready(function() {
|
||||
console.log("jQuery ready");
|
||||
|
||||
if ("geolocation" in navigator) {
|
||||
console.log("Geolocation API enabled");
|
||||
navigator.geolocation.getCurrentPosition(function(position) {
|
||||
console.log(position.coords.latitude, position.coords.longitude);
|
||||
});
|
||||
} else {
|
||||
console.log("No geolocation API");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1000;
|
||||
LastUpgradeCheck = 1110;
|
||||
ORGANIZATIONNAME = "The Chromium Authors";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
|
@ -337,6 +337,7 @@
|
|||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
@ -384,6 +385,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -393,6 +395,7 @@
|
|||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
@ -434,6 +437,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1000"
|
||||
LastUpgradeVersion = "1110"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -27,8 +27,6 @@
|
|||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
|
@ -38,8 +36,8 @@
|
|||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
|
@ -61,8 +59,6 @@
|
|||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import UIKit
|
||||
import Flutter
|
||||
import flutter_downloader
|
||||
//import flutter_downloader
|
||||
|
||||
@UIApplicationMain
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
|
@ -10,9 +10,9 @@ import flutter_downloader
|
|||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
FlutterDownloaderPlugin.setPluginRegistrantCallback({(registry: FlutterPluginRegistry) in
|
||||
/*FlutterDownloaderPlugin.setPluginRegistrantCallback({(registry: FlutterPluginRegistry) in
|
||||
|
||||
})
|
||||
})*/
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,58 +2,62 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key></key>
|
||||
<string></string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>Need location</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>Need location</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>Need location</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>flutter_inappbrowser_example</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -80,6 +80,16 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
|||
ContentBlockerAction(ContentBlockerActionType.BLOCK)
|
||||
)
|
||||
]
|
||||
),
|
||||
AndroidInAppWebViewOptions(
|
||||
databaseEnabled: true,
|
||||
appCacheEnabled: true,
|
||||
domStorageEnabled: true,
|
||||
geolocationEnabled: true,
|
||||
//blockNetworkImage: true,
|
||||
),
|
||||
iOSInAppWebViewOptions(
|
||||
preferredContentMode: iOSInAppWebViewUserPreferredContentMode.DESKTOP
|
||||
)
|
||||
],
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
|
@ -103,6 +113,9 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
|||
onLoadStop: (InAppWebViewController controller, String url) async {
|
||||
print("stopped $url");
|
||||
},
|
||||
onLoadError: (InAppWebViewController controller, String url, int code, String message) async {
|
||||
print("error $url: $code, $message");
|
||||
},
|
||||
onProgressChanged:
|
||||
(InAppWebViewController controller, int progress) {
|
||||
setState(() {
|
||||
|
@ -131,12 +144,12 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
|||
""");
|
||||
},
|
||||
onDownloadStart: (InAppWebViewController controller, String url) async {
|
||||
final taskId = await FlutterDownloader.enqueue(
|
||||
/*final taskId = await FlutterDownloader.enqueue(
|
||||
url: url,
|
||||
savedDir: await _findLocalPath(),
|
||||
showNotification: true, // show download progress in status bar (for Android)
|
||||
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
|
||||
);
|
||||
);*/
|
||||
},
|
||||
onLoadResourceCustomScheme: (InAppWebViewController controller, String scheme, String url) async {
|
||||
if (scheme == "my-special-custom-scheme") {
|
||||
|
@ -151,6 +164,37 @@ class _InlineExampleScreenState extends State<InlineExampleScreen> {
|
|||
print("target _blank: " + url);
|
||||
controller.loadUrl(url);
|
||||
},
|
||||
onGeolocationPermissionsShowPrompt: (InAppWebViewController controller, String origin) async {
|
||||
GeolocationPermissionShowPromptResponse response;
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: new Text("Permission Geolocation API"),
|
||||
content: new Text("Can we use Geolocation API?"),
|
||||
actions: <Widget>[
|
||||
new FlatButton(
|
||||
child: new Text("Close"),
|
||||
onPressed: () {
|
||||
response = new GeolocationPermissionShowPromptResponse(origin, false, false);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
new FlatButton(
|
||||
child: new Text("Accept"),
|
||||
onPressed: () {
|
||||
response = new GeolocationPermissionShowPromptResponse(origin, true, true);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
return response;
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
|
||||
import 'package:flutter_inappbrowser_example/chrome_safari_example.screen.dart';
|
||||
import 'package:flutter_inappbrowser_example/inline_example.screen.dart';
|
||||
import 'package:flutter_inappbrowser_example/webview_example.screen.dart';
|
||||
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
// InAppLocalhostServer localhostServer = new InAppLocalhostServer();
|
||||
|
||||
Future main() async {
|
||||
// await localhostServer.start();
|
||||
await FlutterDownloader.initialize();
|
||||
// await FlutterDownloader.initialize();
|
||||
await PermissionHandler().requestPermissions([PermissionGroup.locationAlways]);
|
||||
runApp(new MyApp());
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,11 @@ class MyInappBrowser extends InAppBrowser {
|
|||
Future<CustomSchemeResponse> onLoadResourceCustomScheme(String scheme, String url) async {
|
||||
print("custom scheme: " + scheme);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GeolocationPermissionShowPromptResponse> onGeolocationPermissionsShowPrompt(String origin) async {
|
||||
print("request Geolocation permission API");
|
||||
}
|
||||
}
|
||||
|
||||
class WebviewExampleScreen extends StatefulWidget {
|
||||
|
|
|
@ -21,6 +21,7 @@ dependencies:
|
|||
cupertino_icons: ^0.1.2
|
||||
flutter_downloader: ^1.3.2
|
||||
path_provider: ^1.4.0
|
||||
permission_handler: ^3.3.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -39,7 +39,8 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||
webView!.prepare()
|
||||
|
||||
if #available(iOS 11.0, *) {
|
||||
if let contentBlockers = webView!.options?.contentBlockers {
|
||||
self.webView!.configuration.userContentController.removeAllContentRuleLists()
|
||||
if let contentBlockers = webView!.options?.contentBlockers, contentBlockers.count > 0 {
|
||||
do {
|
||||
let jsonData = try JSONSerialization.data(withJSONObject: contentBlockers, options: [])
|
||||
let blockRules = String(data: jsonData, encoding: String.Encoding.utf8)
|
||||
|
|
|
@ -166,34 +166,76 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
allowsBackForwardNavigationGestures = (options?.allowsBackForwardNavigationGestures)!
|
||||
if #available(iOS 9.0, *) {
|
||||
allowsLinkPreview = (options?.allowsLinkPreview)!
|
||||
}
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
configuration.ignoresViewportScaleLimits = (options?.ignoresViewportScaleLimits)!
|
||||
}
|
||||
|
||||
if #available(iOS 9.0, *) {
|
||||
configuration.allowsPictureInPictureMediaPlayback = (options?.allowsPictureInPictureMediaPlayback)!
|
||||
}
|
||||
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = (options?.javaScriptCanOpenWindowsAutomatically)!
|
||||
|
||||
configuration.preferences.javaScriptEnabled = (options?.javaScriptEnabled)!
|
||||
|
||||
scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)!
|
||||
scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)!
|
||||
|
||||
if ((options?.userAgent)! != "") {
|
||||
if #available(iOS 9.0, *) {
|
||||
if ((options?.applicationNameForUserAgent)! != "") {
|
||||
configuration.applicationNameForUserAgent = (options?.applicationNameForUserAgent)!
|
||||
}
|
||||
if ((options?.userAgent)! != "") {
|
||||
customUserAgent = (options?.userAgent)!
|
||||
}
|
||||
}
|
||||
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = (options?.javaScriptCanOpenWindowsAutomatically)!
|
||||
configuration.preferences.javaScriptEnabled = (options?.javaScriptEnabled)!
|
||||
configuration.preferences.minimumFontSize = CGFloat((options?.minimumFontSize)!)
|
||||
configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: (options?.selectionGranularity)!)!
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
configuration.ignoresViewportScaleLimits = (options?.ignoresViewportScaleLimits)!
|
||||
|
||||
var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0)
|
||||
for type in options?.dataDetectorTypes ?? [] {
|
||||
let dataDetectorType = getDataDetectorType(type: type)
|
||||
dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue)
|
||||
}
|
||||
configuration.dataDetectorTypes = dataDetectorTypes
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
if #available(iOS 13.0, *) {
|
||||
configuration.preferences.isFraudulentWebsiteWarningEnabled = (options?.isFraudulentWebsiteWarningEnabled)!
|
||||
configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: (options?.preferredContentMode)!)!
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
scrollView.showsVerticalScrollIndicator = (options?.verticalScrollBarEnabled)!
|
||||
scrollView.showsHorizontalScrollIndicator = (options?.horizontalScrollBarEnabled)!
|
||||
|
||||
if (options?.clearCache)! {
|
||||
clearCache()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 10.0, *)
|
||||
public func getDataDetectorType(type: String) -> WKDataDetectorTypes {
|
||||
switch type {
|
||||
case "NONE":
|
||||
return WKDataDetectorTypes.init(rawValue: 0)
|
||||
case "PHONE_NUMBER":
|
||||
return .phoneNumber
|
||||
case "LINK":
|
||||
return .link
|
||||
case "ADDRESS":
|
||||
return .address
|
||||
case "CALENDAR_EVENT":
|
||||
return .calendarEvent
|
||||
case "TRACKING_NUMBER":
|
||||
return .trackingNumber
|
||||
case "FLIGHT_NUMBER":
|
||||
return .flightNumber
|
||||
case "LOOKUP_SUGGESTION":
|
||||
return .lookupSuggestion
|
||||
case "SPOTLIGHT_SUGGESTION":
|
||||
return .spotlightSuggestion
|
||||
case "ALL":
|
||||
return .all
|
||||
default:
|
||||
return WKDataDetectorTypes.init(rawValue: 0)
|
||||
}
|
||||
}
|
||||
|
||||
public static func preWKWebViewConfiguration(options: InAppWebViewOptions?) -> WKWebViewConfiguration {
|
||||
let configuration = WKWebViewConfiguration()
|
||||
|
||||
|
@ -371,28 +413,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
allowsBackForwardNavigationGestures = newOptions.allowsBackForwardNavigationGestures
|
||||
}
|
||||
|
||||
if newOptionsMap["allowsLinkPreview"] != nil && options?.allowsLinkPreview != newOptions.allowsLinkPreview {
|
||||
if #available(iOS 9.0, *) {
|
||||
allowsLinkPreview = newOptions.allowsLinkPreview
|
||||
}
|
||||
}
|
||||
|
||||
if newOptionsMap["ignoresViewportScaleLimits"] != nil && options?.ignoresViewportScaleLimits != newOptions.ignoresViewportScaleLimits {
|
||||
if #available(iOS 10.0, *) {
|
||||
configuration.ignoresViewportScaleLimits = newOptions.ignoresViewportScaleLimits
|
||||
}
|
||||
}
|
||||
|
||||
if newOptionsMap["allowsInlineMediaPlayback"] != nil && options?.allowsInlineMediaPlayback != newOptions.allowsInlineMediaPlayback {
|
||||
configuration.allowsInlineMediaPlayback = newOptions.allowsInlineMediaPlayback
|
||||
}
|
||||
|
||||
if newOptionsMap["allowsPictureInPictureMediaPlayback"] != nil && options?.allowsPictureInPictureMediaPlayback != newOptions.allowsPictureInPictureMediaPlayback {
|
||||
if #available(iOS 9.0, *) {
|
||||
configuration.allowsPictureInPictureMediaPlayback = newOptions.allowsPictureInPictureMediaPlayback
|
||||
}
|
||||
}
|
||||
|
||||
if newOptionsMap["javaScriptCanOpenWindowsAutomatically"] != nil && options?.javaScriptCanOpenWindowsAutomatically != newOptions.javaScriptCanOpenWindowsAutomatically {
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = newOptions.javaScriptCanOpenWindowsAutomatically
|
||||
}
|
||||
|
@ -401,6 +425,38 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
configuration.preferences.javaScriptEnabled = newOptions.javaScriptEnabled
|
||||
}
|
||||
|
||||
if newOptionsMap["minimumFontSize"] != nil && options?.minimumFontSize != newOptions.minimumFontSize {
|
||||
configuration.preferences.minimumFontSize = CGFloat(newOptions.minimumFontSize)
|
||||
}
|
||||
|
||||
if newOptionsMap["selectionGranularity"] != nil && options?.selectionGranularity != newOptions.selectionGranularity {
|
||||
configuration.selectionGranularity = WKSelectionGranularity.init(rawValue: newOptions.selectionGranularity)!
|
||||
}
|
||||
|
||||
if #available(iOS 10.0, *) {
|
||||
if newOptionsMap["ignoresViewportScaleLimits"] != nil && options?.ignoresViewportScaleLimits != newOptions.ignoresViewportScaleLimits {
|
||||
configuration.ignoresViewportScaleLimits = newOptions.ignoresViewportScaleLimits
|
||||
}
|
||||
|
||||
if newOptionsMap["dataDetectorTypes"] != nil && options?.dataDetectorTypes != newOptions.dataDetectorTypes {
|
||||
var dataDetectorTypes = WKDataDetectorTypes.init(rawValue: 0)
|
||||
for type in newOptions.dataDetectorTypes {
|
||||
let dataDetectorType = getDataDetectorType(type: type)
|
||||
dataDetectorTypes = WKDataDetectorTypes(rawValue: dataDetectorTypes.rawValue | dataDetectorType.rawValue)
|
||||
}
|
||||
configuration.dataDetectorTypes = dataDetectorTypes
|
||||
}
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
if #available(iOS 13.0, *) {
|
||||
configuration.preferences.isFraudulentWebsiteWarningEnabled = (options?.isFraudulentWebsiteWarningEnabled)!
|
||||
configuration.defaultWebpagePreferences.preferredContentMode = WKWebpagePreferences.ContentMode(rawValue: (options?.preferredContentMode)!)!
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
if newOptionsMap["verticalScrollBarEnabled"] != nil && options?.verticalScrollBarEnabled != newOptions.verticalScrollBarEnabled {
|
||||
scrollView.showsVerticalScrollIndicator = newOptions.verticalScrollBarEnabled
|
||||
}
|
||||
|
@ -408,19 +464,30 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
scrollView.showsHorizontalScrollIndicator = newOptions.horizontalScrollBarEnabled
|
||||
}
|
||||
|
||||
if newOptionsMap["userAgent"] != nil && options?.userAgent != newOptions.userAgent && (newOptions.userAgent != "") {
|
||||
if #available(iOS 9.0, *) {
|
||||
if #available(iOS 9.0, *) {
|
||||
if newOptionsMap["allowsLinkPreview"] != nil && options?.allowsLinkPreview != newOptions.allowsLinkPreview {
|
||||
allowsLinkPreview = newOptions.allowsLinkPreview
|
||||
}
|
||||
if newOptionsMap["allowsPictureInPictureMediaPlayback"] != nil && options?.allowsPictureInPictureMediaPlayback != newOptions.allowsPictureInPictureMediaPlayback {
|
||||
configuration.allowsPictureInPictureMediaPlayback = newOptions.allowsPictureInPictureMediaPlayback
|
||||
}
|
||||
if newOptionsMap["applicationNameForUserAgent"] != nil && options?.applicationNameForUserAgent != newOptions.applicationNameForUserAgent && newOptions.applicationNameForUserAgent != "" {
|
||||
configuration.applicationNameForUserAgent = newOptions.applicationNameForUserAgent
|
||||
}
|
||||
if newOptionsMap["userAgent"] != nil && options?.userAgent != newOptions.userAgent && newOptions.userAgent != "" {
|
||||
customUserAgent = newOptions.userAgent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if newOptionsMap["clearCache"] != nil && newOptions.clearCache {
|
||||
clearCache()
|
||||
}
|
||||
|
||||
if #available(iOS 11.0, *), newOptionsMap["contentBlockers"] != nil {
|
||||
let contentBlockers = newOptions.contentBlockers
|
||||
configuration.userContentController.removeAllContentRuleLists()
|
||||
let contentBlockers = newOptions.contentBlockers
|
||||
if contentBlockers.count > 0 {
|
||||
do {
|
||||
let jsonData = try JSONSerialization.data(withJSONObject: contentBlockers, options: [])
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebKit
|
||||
|
||||
@objcMembers
|
||||
public class InAppWebViewOptions: Options {
|
||||
|
@ -23,6 +24,7 @@ public class InAppWebViewOptions: Options {
|
|||
var horizontalScrollBarEnabled = true
|
||||
var resourceCustomSchemes: [String] = []
|
||||
var contentBlockers: [[String: [String : Any]]] = []
|
||||
var minimumFontSize = 0;
|
||||
|
||||
var disallowOverScroll = false
|
||||
var enableViewportScale = false
|
||||
|
@ -35,6 +37,11 @@ public class InAppWebViewOptions: Options {
|
|||
var allowsInlineMediaPlayback = false
|
||||
var allowsPictureInPictureMediaPlayback = true
|
||||
var transparentBackground = false
|
||||
var applicationNameForUserAgent = "";
|
||||
var isFraudulentWebsiteWarningEnabled = true;
|
||||
var selectionGranularity = 0;
|
||||
var dataDetectorTypes: [String] = ["NONE"]; // WKDataDetectorTypeNone
|
||||
var preferredContentMode = 0;
|
||||
|
||||
override init(){
|
||||
super.init()
|
||||
|
|
|
@ -15,7 +15,7 @@ class ContentBlocker {
|
|||
class ContentBlockerTriggerResourceType {
|
||||
final String _value;
|
||||
const ContentBlockerTriggerResourceType._internal(this._value);
|
||||
toString() => _value;
|
||||
toValue() => _value;
|
||||
|
||||
static const DOCUMENT = const ContentBlockerTriggerResourceType._internal('document');
|
||||
static const IMAGE = const ContentBlockerTriggerResourceType._internal('image');
|
||||
|
@ -30,7 +30,7 @@ class ContentBlockerTriggerResourceType {
|
|||
class ContentBlockerTriggerLoadType {
|
||||
final String _value;
|
||||
const ContentBlockerTriggerLoadType._internal(this._value);
|
||||
toString() => _value;
|
||||
toValue() => _value;
|
||||
|
||||
static const FIRST_PARTY = const ContentBlockerTriggerLoadType._internal('first-party');
|
||||
static const THIRD_PARTY = const ContentBlockerTriggerLoadType._internal('third-party');
|
||||
|
@ -65,11 +65,11 @@ class ContentBlockerTrigger {
|
|||
Map<String, dynamic> toMap() {
|
||||
List<String> resourceTypeStringList = [];
|
||||
resourceType.forEach((type) {
|
||||
resourceTypeStringList.add(type.toString());
|
||||
resourceTypeStringList.add(type.toValue());
|
||||
});
|
||||
List<String> loadTypeStringList = [];
|
||||
loadType.forEach((type) {
|
||||
loadTypeStringList.add(type.toString());
|
||||
loadTypeStringList.add(type.toValue());
|
||||
});
|
||||
|
||||
Map<String, dynamic> map = {
|
||||
|
@ -95,7 +95,7 @@ class ContentBlockerTrigger {
|
|||
class ContentBlockerActionType {
|
||||
final String _value;
|
||||
const ContentBlockerActionType._internal(this._value);
|
||||
toString() => _value;
|
||||
toValue() => _value;
|
||||
|
||||
static const BLOCK = const ContentBlockerActionType._internal('block');
|
||||
static const CSS_DISPLAY_NONE = const ContentBlockerActionType._internal('css-display-none');
|
||||
|
@ -116,7 +116,7 @@ class ContentBlockerAction {
|
|||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> map = {
|
||||
"type": type.toString(),
|
||||
"type": type.toValue(),
|
||||
"selector": selector
|
||||
};
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@ class InAppBrowser {
|
|||
///Event fires when the [InAppBrowser] webview finds the `custom-scheme` while loading a resource. Here you can handle the url request and return a [CustomSchemeResponse] to load a specific resource encoded to `base64`.
|
||||
///[scheme] represents the scheme of the url.
|
||||
///[url] represents the url of the request.
|
||||
Future<CustomSchemeResponse> onLoadResourceCustomScheme(String scheme, String url) async {
|
||||
Future<CustomSchemeResponse> onLoadResourceCustomScheme(String scheme, String url) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -352,6 +352,15 @@ class InAppBrowser {
|
|||
|
||||
}
|
||||
|
||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
||||
///On non-secure origins geolocation requests are automatically denied.
|
||||
///[origin] represents the origin of the web content attempting to use the Geolocation API.
|
||||
///**NOTE**: available only for Android.
|
||||
Future<GeolocationPermissionShowPromptResponse> onGeolocationPermissionsShowPrompt (String origin) {
|
||||
|
||||
}
|
||||
|
||||
void throwIsAlreadyOpened({String message = ''}) {
|
||||
if (this.isOpened()) {
|
||||
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
|
||||
|
|
|
@ -128,6 +128,13 @@ class InAppWebView extends StatefulWidget {
|
|||
///[url] represents the url of the link.
|
||||
final onTargetBlankCallback onTargetBlank;
|
||||
|
||||
///Event that notifies the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin.
|
||||
///Note that for applications targeting Android N and later SDKs (API level > `Build.VERSION_CODES.M`) this method is only called for requests originating from secure origins such as https.
|
||||
///On non-secure origins geolocation requests are automatically denied.
|
||||
///[origin] represents the origin of the web content attempting to use the Geolocation API.
|
||||
///**NOTE**: available only for Android.
|
||||
final onGeolocationPermissionsShowPromptCallback onGeolocationPermissionsShowPrompt;
|
||||
|
||||
///Initial url that will be loaded.
|
||||
final String initialUrl;
|
||||
///Initial asset file that will be loaded. See [InAppWebView.loadFile()] for explanation.
|
||||
|
@ -166,6 +173,7 @@ class InAppWebView extends StatefulWidget {
|
|||
this.onDownloadStart,
|
||||
this.onLoadResourceCustomScheme,
|
||||
this.onTargetBlank,
|
||||
this.onGeolocationPermissionsShowPrompt,
|
||||
this.gestureRecognizers,
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -384,6 +392,13 @@ class InAppWebViewController {
|
|||
else if (_inAppBrowser != null)
|
||||
_inAppBrowser.onTargetBlank(url);
|
||||
break;
|
||||
case "onGeolocationPermissionsShowPrompt":
|
||||
String origin = call.arguments["origin"];
|
||||
if (_widget != null && _widget.onGeolocationPermissionsShowPrompt != null)
|
||||
return (await _widget.onGeolocationPermissionsShowPrompt(this, origin)).toMap();
|
||||
else if (_inAppBrowser != null)
|
||||
return (await _inAppBrowser.onGeolocationPermissionsShowPrompt(origin)).toMap();
|
||||
break;
|
||||
case "onCallJsHandler":
|
||||
String handlerName = call.arguments["handlerName"];
|
||||
// decode args to json
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'in_app_webview.dart' show InAppWebViewController;
|
||||
|
@ -108,6 +106,28 @@ class WebHistoryItem {
|
|||
WebHistoryItem(this.originalUrl, this.title, this.url, this.index, this.offset);
|
||||
}
|
||||
|
||||
///GeolocationPermissionPromptResponse class.
|
||||
///
|
||||
///Class used by the host application to set the Geolocation permission state for an origin during the [onGeolocationPermissionsShowPrompt] event.
|
||||
class GeolocationPermissionShowPromptResponse {
|
||||
///The origin for which permissions are set.
|
||||
String origin;
|
||||
///Whether or not the origin should be allowed to use the Geolocation API.
|
||||
bool allow;
|
||||
///Whether the permission should be retained beyond the lifetime of a page currently being displayed by a WebView
|
||||
bool retain;
|
||||
|
||||
GeolocationPermissionShowPromptResponse(this.origin, this.allow, this.retain);
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"origin": origin,
|
||||
"allow": allow,
|
||||
"retain": retain
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
typedef onWebViewCreatedCallback = void Function(InAppWebViewController controller);
|
||||
typedef onWebViewLoadStartCallback = void Function(InAppWebViewController controller, String url);
|
||||
typedef onWebViewLoadStopCallback = void Function(InAppWebViewController controller, String url);
|
||||
|
@ -119,4 +139,5 @@ typedef onWebViewLoadResourceCallback = void Function(InAppWebViewController con
|
|||
typedef onWebViewScrollChangedCallback = void Function(InAppWebViewController controller, int x, int y);
|
||||
typedef onDownloadStartCallback = void Function(InAppWebViewController controller, String url);
|
||||
typedef onLoadResourceCustomSchemeCallback = Future<CustomSchemeResponse> Function(InAppWebViewController controller, String scheme, String url);
|
||||
typedef onTargetBlankCallback = void Function(InAppWebViewController controller, String url);
|
||||
typedef onTargetBlankCallback = void Function(InAppWebViewController controller, String url);
|
||||
typedef onGeolocationPermissionsShowPromptCallback = Future<GeolocationPermissionShowPromptResponse> Function(InAppWebViewController controller, String origin);
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_inappbrowser/src/content_blocker.dart';
|
||||
|
||||
class WebViewOptions {
|
||||
|
@ -23,6 +25,7 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
bool javaScriptCanOpenWindowsAutomatically;
|
||||
bool mediaPlaybackRequiresUserGesture;
|
||||
int textZoom;
|
||||
int minimumFontSize;
|
||||
bool verticalScrollBarEnabled;
|
||||
bool horizontalScrollBarEnabled;
|
||||
List<String> resourceCustomSchemes;
|
||||
|
@ -30,8 +33,11 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
|
||||
InAppWebViewOptions({this.useShouldOverrideUrlLoading = false, this.useOnLoadResource = false, this.useOnDownloadStart = false, this.useOnTargetBlank = false,
|
||||
this.clearCache = false, this.userAgent = "", this.javaScriptEnabled = true, this.javaScriptCanOpenWindowsAutomatically = false,
|
||||
this.mediaPlaybackRequiresUserGesture = true, this.textZoom = 100, this.verticalScrollBarEnabled = true, this.horizontalScrollBarEnabled = true, this.resourceCustomSchemes = const [],
|
||||
this.contentBlockers = const []});
|
||||
this.mediaPlaybackRequiresUserGesture = true, this.textZoom = 100, this.minimumFontSize, this.verticalScrollBarEnabled = true, this.horizontalScrollBarEnabled = true,
|
||||
this.resourceCustomSchemes = const [], this.contentBlockers = const []}) {
|
||||
if (this.minimumFontSize == null)
|
||||
this.minimumFontSize = Platform.isAndroid ? 8 : 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
|
@ -59,6 +65,57 @@ class InAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
}
|
||||
}
|
||||
|
||||
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 AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
||||
bool clearSessionCache;
|
||||
bool builtInZoomControls;
|
||||
|
@ -69,10 +126,46 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
bool useWideViewPort;
|
||||
bool safeBrowsingEnabled;
|
||||
bool transparentBackground;
|
||||
String mixedContentMode;
|
||||
AndroidInAppWebViewMixedContentMode mixedContentMode;
|
||||
|
||||
bool allowContentAccess;
|
||||
bool allowFileAccess;
|
||||
bool allowFileAccessFromFileURLs;
|
||||
bool allowUniversalAccessFromFileURLs;
|
||||
bool appCacheEnabled;
|
||||
String appCachePath;
|
||||
bool blockNetworkImage;
|
||||
bool blockNetworkLoads;
|
||||
AndroidInAppWebViewCacheMode cacheMode;
|
||||
String cursiveFontFamily;
|
||||
int defaultFixedFontSize;
|
||||
int defaultFontSize;
|
||||
String defaultTextEncodingName;
|
||||
AndroidInAppWebViewModeMenuItem disabledActionModeMenuItems;
|
||||
String fantasyFontFamily;
|
||||
String fixedFontFamily;
|
||||
AndroidInAppWebViewForceDark forceDark;
|
||||
bool geolocationEnabled;
|
||||
AndroidInAppWebViewLayoutAlgorithm layoutAlgorithm;
|
||||
bool loadWithOverviewMode;
|
||||
bool loadsImagesAutomatically;
|
||||
int minimumLogicalFontSize;
|
||||
bool needInitialFocus;
|
||||
bool offscreenPreRaster;
|
||||
String sansSerifFontFamily;
|
||||
String serifFontFamily;
|
||||
String standardFontFamily;
|
||||
|
||||
AndroidInAppWebViewOptions({this.clearSessionCache = false, this.builtInZoomControls = false, this.displayZoomControls = false, this.supportZoom = true, this.databaseEnabled = false,
|
||||
this.domStorageEnabled = false, this.useWideViewPort = true, this.safeBrowsingEnabled = true, this.transparentBackground = false, this.mixedContentMode = ""});
|
||||
this.domStorageEnabled = false, this.useWideViewPort = true, this.safeBrowsingEnabled = true, this.transparentBackground = false, this.mixedContentMode,
|
||||
this.allowContentAccess = true, this.allowFileAccess = true, this.allowFileAccessFromFileURLs = true, this.allowUniversalAccessFromFileURLs = true,
|
||||
this.appCacheEnabled = true, this.appCachePath, this.blockNetworkImage = false, this.blockNetworkLoads = false, this.cacheMode = AndroidInAppWebViewCacheMode.LOAD_DEFAULT,
|
||||
this.cursiveFontFamily = "cursive", this.defaultFixedFontSize = 16, this.defaultFontSize = 16, this.defaultTextEncodingName = "UTF-8",
|
||||
this.disabledActionModeMenuItems, this.fantasyFontFamily = "fantasy", this.fixedFontFamily = "monospace", this.forceDark = AndroidInAppWebViewForceDark.FORCE_DARK_OFF,
|
||||
this.geolocationEnabled = true, this.layoutAlgorithm, this.loadWithOverviewMode = true, this.loadsImagesAutomatically = true,
|
||||
this.minimumLogicalFontSize = 8, this.needInitialFocus = true, this.offscreenPreRaster = false, this.sansSerifFontFamily = "sans-serif", this.serifFontFamily = "sans-serif",
|
||||
this.standardFontFamily = "sans-serif"
|
||||
});
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
|
@ -86,11 +179,74 @@ class AndroidInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
"useWideViewPort": useWideViewPort,
|
||||
"safeBrowsingEnabled": safeBrowsingEnabled,
|
||||
"transparentBackground": transparentBackground,
|
||||
"mixedContentMode": mixedContentMode,
|
||||
"mixedContentMode": mixedContentMode?.toValue(),
|
||||
"allowContentAccess": allowContentAccess,
|
||||
"allowFileAccess": allowFileAccess,
|
||||
"allowFileAccessFromFileURLs": allowFileAccessFromFileURLs,
|
||||
"allowUniversalAccessFromFileURLs": allowUniversalAccessFromFileURLs,
|
||||
"appCacheEnabled": appCacheEnabled,
|
||||
"appCachePath": appCachePath,
|
||||
"blockNetworkImage": blockNetworkImage,
|
||||
"blockNetworkLoads": blockNetworkLoads,
|
||||
"cacheMode": cacheMode?.toValue(),
|
||||
"cursiveFontFamily": cursiveFontFamily,
|
||||
"defaultFixedFontSize": defaultFixedFontSize,
|
||||
"defaultFontSize": defaultFontSize,
|
||||
"defaultTextEncodingName": defaultTextEncodingName,
|
||||
"disabledActionModeMenuItems": disabledActionModeMenuItems?.toValue(),
|
||||
"fantasyFontFamily": fantasyFontFamily,
|
||||
"fixedFontFamily": fixedFontFamily,
|
||||
"forceDark": forceDark?.toValue(),
|
||||
"geolocationEnabled": geolocationEnabled,
|
||||
"layoutAlgorithm": layoutAlgorithm?.toValue(),
|
||||
"loadWithOverviewMode": loadWithOverviewMode,
|
||||
"loadsImagesAutomatically": loadsImagesAutomatically,
|
||||
"minimumLogicalFontSize": minimumLogicalFontSize,
|
||||
"needInitialFocus": needInitialFocus,
|
||||
"offscreenPreRaster": offscreenPreRaster,
|
||||
"sansSerifFontFamily": sansSerifFontFamily,
|
||||
"serifFontFamily": serifFontFamily,
|
||||
"standardFontFamily": standardFontFamily
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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 iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
||||
bool disallowOverScroll;
|
||||
bool enableViewportScale;
|
||||
|
@ -103,12 +259,26 @@ class iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
bool allowsPictureInPictureMediaPlayback;
|
||||
bool transparentBackground;
|
||||
|
||||
String applicationNameForUserAgent;
|
||||
bool isFraudulentWebsiteWarningEnabled;
|
||||
iOSInAppWebViewSelectionGranularity selectionGranularity;
|
||||
List<iOSInAppWebViewDataDetectorTypes> dataDetectorTypes;
|
||||
iOSInAppWebViewUserPreferredContentMode preferredContentMode;
|
||||
|
||||
iOSInAppWebViewOptions({this.disallowOverScroll = false, this.enableViewportScale = false, this.suppressesIncrementalRendering = false, this.allowsAirPlayForMediaPlayback = true,
|
||||
this.allowsBackForwardNavigationGestures = true, this.allowsLinkPreview = true, this.ignoresViewportScaleLimits = false, this.allowsInlineMediaPlayback = false,
|
||||
this.allowsPictureInPictureMediaPlayback = true, this.transparentBackground = false});
|
||||
this.allowsPictureInPictureMediaPlayback = true, this.transparentBackground = false, this.applicationNameForUserAgent = "", this.isFraudulentWebsiteWarningEnabled = true,
|
||||
this.selectionGranularity = iOSInAppWebViewSelectionGranularity.DYNAMIC, this.dataDetectorTypes = const [iOSInAppWebViewDataDetectorTypes.NONE],
|
||||
this.preferredContentMode = iOSInAppWebViewUserPreferredContentMode.RECOMMENDED
|
||||
});
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toMap() {
|
||||
List<String> dataDetectorTypesList = [];
|
||||
dataDetectorTypes.forEach((dataDetectorType) {
|
||||
dataDetectorTypesList.add(dataDetectorType.toValue());
|
||||
});
|
||||
|
||||
return {
|
||||
"disallowOverScroll": disallowOverScroll,
|
||||
"enableViewportScale": enableViewportScale,
|
||||
|
@ -120,6 +290,11 @@ class iOSInAppWebViewOptions implements WebViewOptions, BrowserOptions {
|
|||
"allowsInlineMediaPlayback": allowsInlineMediaPlayback,
|
||||
"allowsPictureInPictureMediaPlayback": allowsPictureInPictureMediaPlayback,
|
||||
"transparentBackground": transparentBackground,
|
||||
"applicationNameForUserAgent": applicationNameForUserAgent,
|
||||
"isFraudulentWebsiteWarningEnabled": isFraudulentWebsiteWarningEnabled,
|
||||
"selectionGranularity": selectionGranularity.toValue(),
|
||||
"dataDetectorTypes": dataDetectorTypesList,
|
||||
"preferredContentMode": preferredContentMode.toValue(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_inappbrowser
|
||||
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window.
|
||||
version: 1.3.0
|
||||
version: 2.0.0
|
||||
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
||||
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
||||
|
||||
|
|
Loading…
Reference in New Issue