v0.4.0
This commit is contained in:
parent
c7356f33c8
commit
860a42e2ba
.idea
CHANGELOG.mdREADME.mdandroid/src/main/java/com/pichillilorenzo/flutter_inappbrowser
InAppBrowserFlutterPlugin.javaInAppBrowserOptions.javaInAppBrowserWebChromeClient.javaInAppBrowserWebViewClient.javaJavaScriptBridgeInterface.javaOptions.javaWebViewActivity.java
chrome_custom_tabs
example
flutter_inappbrowser.imlios/Classes
InAppBrowserOptions.swiftInAppBrowserWebViewController.swiftOptions.swiftSafariViewController.swiftSwiftFlutterPlugin.swift
lib
pubspec.yaml
281
.idea/workspace.xml
generated
281
.idea/workspace.xml
generated
@ -15,13 +15,30 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/example/assets/css/style.css" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/example/assets/images/dart.svg" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/example/assets/index.html" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" 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$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebChromeClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebChromeClient.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/JavaScriptBridgeInterface.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/JavaScriptBridgeInterface.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/Options.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/Options.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsActivity.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabActivityHelper.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabActivityHelper.java" 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/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/example/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/example/pubspec.yaml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/flutter_inappbrowser.iml" beforeDir="false" afterPath="$PROJECT_DIR$/flutter_inappbrowser.iml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.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/Options.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/Options.swift" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/SafariViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SafariViewController.swift" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/ios/Storyboards/en.lproj/WebView.storyboard" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" beforeDir="false" afterPath="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
@ -43,20 +60,25 @@
|
|||||||
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
|
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="5791">
|
<state relative-caret-position="128">
|
||||||
<caret line="429" column="3" selection-start-line="429" selection-start-column="3" selection-end-line="429" selection-end-column="3" />
|
<caret line="82" column="21" selection-start-line="82" selection-start-column="6" selection-end-line="82" selection-end-column="21" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#814#834#0" expanded="true" />
|
<element signature="e#814#831#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
<file leaf-file-name="pubspec.yaml" pinned="false" current-in-tab="false">
|
<file leaf-file-name="README.md" pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||||
<state relative-caret-position="30">
|
<state split_layout="SPLIT">
|
||||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
<first_editor relative-caret-position="4980">
|
||||||
|
<caret line="332" column="20" lean-forward="true" selection-start-line="332" selection-start-column="20" selection-end-line="332" selection-end-column="41" />
|
||||||
|
</first_editor>
|
||||||
|
<second_editor>
|
||||||
|
<markdownNavigatorState />
|
||||||
|
</second_editor>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
@ -65,8 +87,8 @@
|
|||||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||||
<state split_layout="SPLIT">
|
<state split_layout="SPLIT">
|
||||||
<first_editor relative-caret-position="30">
|
<first_editor relative-caret-position="135">
|
||||||
<caret line="2" column="39" selection-start-line="2" selection-start-column="39" selection-end-line="2" selection-end-column="39" />
|
<caret line="9" lean-forward="true" selection-start-line="9" selection-end-line="9" />
|
||||||
</first_editor>
|
</first_editor>
|
||||||
<second_editor>
|
<second_editor>
|
||||||
<markdownNavigatorState />
|
<markdownNavigatorState />
|
||||||
@ -75,6 +97,18 @@
|
|||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</file>
|
</file>
|
||||||
|
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="165">
|
||||||
|
<caret line="165" column="42" selection-start-line="165" selection-start-column="42" selection-end-line="165" selection-end-column="42" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
</leaf>
|
</leaf>
|
||||||
</component>
|
</component>
|
||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
@ -86,11 +120,6 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="FindInProjectRecents">
|
<component name="FindInProjectRecents">
|
||||||
<findStrings>
|
<findStrings>
|
||||||
<find>loadUrl</find>
|
|
||||||
<find>showWebPage</find>
|
|
||||||
<find>InAppBrowserClient</find>
|
|
||||||
<find>LOG.</find>
|
|
||||||
<find>preferences</find>
|
|
||||||
<find>getPre</find>
|
<find>getPre</find>
|
||||||
<find>client</find>
|
<find>client</find>
|
||||||
<find>webView</find>
|
<find>webView</find>
|
||||||
@ -116,6 +145,11 @@
|
|||||||
<find>presentationStyle</find>
|
<find>presentationStyle</find>
|
||||||
<find>###</find>
|
<find>###</find>
|
||||||
<find>inAppBrowserFallback</find>
|
<find>inAppBrowserFallback</find>
|
||||||
|
<find>target</find>
|
||||||
|
<find>.assets</find>
|
||||||
|
<find>_blank</find>
|
||||||
|
<find>.html</find>
|
||||||
|
<find>close(</find>
|
||||||
</findStrings>
|
</findStrings>
|
||||||
<replaceStrings>
|
<replaceStrings>
|
||||||
<replace>activity.getPreferences(0)</replace>
|
<replace>activity.getPreferences(0)</replace>
|
||||||
@ -142,7 +176,6 @@
|
|||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserClient.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserClient.java" />
|
||||||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserDialog.java" />
|
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/InAppBrowserDialog.java" />
|
||||||
<option value="$PROJECT_DIR$/android/settings.gradle" />
|
<option value="$PROJECT_DIR$/android/settings.gradle" />
|
||||||
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
|
||||||
<option value="$PROJECT_DIR$/ios/Classes/InAppBrowser.m" />
|
<option value="$PROJECT_DIR$/ios/Classes/InAppBrowser.m" />
|
||||||
<option value="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" />
|
<option value="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" />
|
||||||
<option value="$PROJECT_DIR$/LICENSE" />
|
<option value="$PROJECT_DIR$/LICENSE" />
|
||||||
@ -152,17 +185,23 @@
|
|||||||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||||
<option value="$PROJECT_DIR$/example/ios/Podfile" />
|
<option value="$PROJECT_DIR$/example/ios/Podfile" />
|
||||||
<option value="$PROJECT_DIR$/android/build.gradle" />
|
<option value="$PROJECT_DIR$/android/build.gradle" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
<option value="$PROJECT_DIR$/example/html/css/style.css" />
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
<option value="$PROJECT_DIR$/example/html/index.html" />
|
||||||
<option value="$PROJECT_DIR$/README.md" />
|
|
||||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||||
|
<option value="$PROJECT_DIR$/example/assets/css/style.css" />
|
||||||
|
<option value="$PROJECT_DIR$/example/assets/index.html" />
|
||||||
|
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
|
||||||
|
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
|
<option value="$PROJECT_DIR$/README.md" />
|
||||||
|
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds">
|
<component name="ProjectFrameBounds">
|
||||||
<option name="y" value="23" />
|
<option name="x" value="-1920" />
|
||||||
<option name="width" value="1920" />
|
<option name="y" value="-21" />
|
||||||
|
<option name="width" value="1711" />
|
||||||
<option name="height" value="1057" />
|
<option name="height" value="1057" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
@ -171,6 +210,18 @@
|
|||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
|
<pane id="Scope">
|
||||||
|
<subPane subId="Project Files">
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="Root" type="cbb8eebc:String" user="Root" />
|
||||||
|
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="PackagesPane" />
|
||||||
<pane id="ProjectPane">
|
<pane id="ProjectPane">
|
||||||
<subPane>
|
<subPane>
|
||||||
<expand>
|
<expand>
|
||||||
@ -183,6 +234,23 @@
|
|||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
<item name="android" type="462c0819:PsiDirectoryNode" />
|
<item name="android" type="462c0819:PsiDirectoryNode" />
|
||||||
</path>
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="example" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</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>
|
<path>
|
||||||
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
|
||||||
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
|
||||||
@ -193,19 +261,7 @@
|
|||||||
</subPane>
|
</subPane>
|
||||||
<option name="show-excluded-files" value="false" />
|
<option name="show-excluded-files" value="false" />
|
||||||
</pane>
|
</pane>
|
||||||
<pane id="PackagesPane" />
|
|
||||||
<pane id="AndroidView" />
|
<pane id="AndroidView" />
|
||||||
<pane id="Scope">
|
|
||||||
<subPane subId="Project Files">
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="Root" type="cbb8eebc:String" user="Root" />
|
|
||||||
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</subPane>
|
|
||||||
</pane>
|
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
@ -224,12 +280,13 @@
|
|||||||
<property name="show.migrate.to.gradle.popup" value="false" />
|
<property name="show.migrate.to.gradle.popup" value="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/android/libs" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/android/src/main/java" />
|
<recent name="$PROJECT_DIR$/android/src/main/java" />
|
||||||
</key>
|
</key>
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/example/assets/images" />
|
||||||
|
<recent name="$PROJECT_DIR$/android/libs" />
|
||||||
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunDashboard">
|
<component name="RunDashboard">
|
||||||
<option name="ruleStates">
|
<option name="ruleStates">
|
||||||
@ -361,7 +418,7 @@
|
|||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="0" y="23" width="1920" height="1057" extended-state="0" />
|
<frame x="-1920" y="-21" width="1711" height="1057" extended-state="0" />
|
||||||
<editor active="true" />
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||||
@ -372,22 +429,22 @@
|
|||||||
<window_info anchor="right" id="Capture Analysis" order="3" />
|
<window_info anchor="right" id="Capture Analysis" order="3" />
|
||||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5035553" side_tool="true" weight="0.25689086" />
|
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5035553" side_tool="true" weight="0.25689086" />
|
||||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32855567" />
|
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32855567" />
|
||||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49644473" weight="0.20384204" />
|
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49644473" weight="0.3628602" />
|
||||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49644473" visible="true" weight="0.25506938" />
|
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49644473" visible="true" weight="0.2529349" />
|
||||||
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32922077" />
|
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32922077" />
|
||||||
<window_info anchor="bottom" id="Logcat" order="11" />
|
<window_info anchor="bottom" id="Logcat" order="11" />
|
||||||
<window_info id="Captures" order="2" weight="0.32936507" />
|
<window_info id="Captures" order="2" weight="0.32936507" />
|
||||||
<window_info id="Capture Tool" order="2" />
|
<window_info id="Capture Tool" order="2" />
|
||||||
<window_info id="Designer" order="2" />
|
<window_info id="Designer" order="2" />
|
||||||
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.49855492" visible="true" weight="0.15069222" />
|
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.49724367" visible="true" weight="0.16956261" />
|
||||||
<window_info id="Structure" order="1" sideWeight="0.5014451" side_tool="true" weight="0.18293472" />
|
<window_info id="Structure" order="1" sideWeight="0.50275636" side_tool="true" weight="0.1910871" />
|
||||||
<window_info anchor="right" id="Device File Explorer" order="3" side_tool="true" />
|
<window_info anchor="right" id="Device File Explorer" order="3" side_tool="true" />
|
||||||
<window_info anchor="right" id="Theme Preview" order="3" />
|
<window_info anchor="right" id="Theme Preview" order="3" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
<window_info id="Favorites" order="2" side_tool="true" />
|
<window_info id="Favorites" order="2" side_tool="true" />
|
||||||
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32987013" />
|
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32987013" />
|
||||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.2370452" />
|
<window_info anchor="bottom" id="Messages" order="12" weight="0.23692636" />
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||||
<window_info anchor="right" id="Assistant" order="4" visible="true" weight="0.32987013" />
|
<window_info anchor="right" id="Assistant" order="4" visible="true" weight="0.32987013" />
|
||||||
@ -396,13 +453,12 @@
|
|||||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
||||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
<window_info anchor="bottom" id="Find" order="1" weight="0.328125" />
|
<window_info anchor="bottom" id="Find" order="1" weight="0.3276414" />
|
||||||
</layout>
|
</layout>
|
||||||
<layout-to-restore>
|
<layout-to-restore>
|
||||||
<window_info id="Designer" order="4" />
|
<window_info id="Designer" order="4" />
|
||||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" />
|
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" />
|
||||||
<window_info id="Build Variants" order="2" side_tool="true" />
|
<window_info id="Build Variants" order="2" side_tool="true" />
|
||||||
<window_info id="Image Layers" order="5" />
|
|
||||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.4973545" weight="0.32161874" />
|
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.4973545" weight="0.32161874" />
|
||||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
@ -414,25 +470,29 @@
|
|||||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5026455" side_tool="true" weight="0.31735888" />
|
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5026455" side_tool="true" weight="0.31735888" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
|
|
||||||
<window_info anchor="right" id="Device File Explorer" order="4" side_tool="true" />
|
<window_info anchor="right" id="Device File Explorer" order="4" side_tool="true" />
|
||||||
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32936507" />
|
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32936507" />
|
||||||
<window_info anchor="bottom" id="Logcat" order="11" />
|
<window_info anchor="bottom" id="Logcat" order="11" />
|
||||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
||||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" visible="true" weight="0.27888888" />
|
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" visible="true" weight="0.27888888" />
|
||||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
|
||||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.23777778" />
|
<window_info anchor="bottom" id="Messages" order="12" weight="0.23777778" />
|
||||||
<window_info anchor="bottom" id="Message" order="0" />
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
<window_info anchor="bottom" id="TODO" order="6" />
|
<window_info id="Image Layers" order="5" />
|
||||||
<window_info anchor="right" id="Palette	" order="5" />
|
<window_info anchor="right" id="Palette	" order="5" />
|
||||||
<window_info anchor="right" id="Theme Preview" order="7" />
|
<window_info anchor="right" id="Theme Preview" order="7" />
|
||||||
<window_info id="Structure" order="1" weight="0.24969475" />
|
<window_info id="Structure" order="1" weight="0.24969475" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
<window_info anchor="bottom" id="Find" order="1" weight="0.3290735" />
|
<window_info anchor="bottom" id="Find" order="1" weight="0.3290735" />
|
||||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
</layout-to-restore>
|
</layout-to-restore>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="UnknownFeatures">
|
||||||
|
<option featureType="com.intellij.fileTypeFactory" implementationName="*.css" />
|
||||||
|
</component>
|
||||||
<component name="VcsContentAnnotationSettings">
|
<component name="VcsContentAnnotationSettings">
|
||||||
<option name="myLimit" value="2678400000" />
|
<option name="myLimit" value="2678400000" />
|
||||||
</component>
|
</component>
|
||||||
@ -442,21 +502,6 @@
|
|||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
</component>
|
</component>
|
||||||
<component name="editorHistoryManager">
|
<component name="editorHistoryManager">
|
||||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="270">
|
|
||||||
<caret line="18" column="34" lean-forward="true" selection-start-line="18" selection-start-column="34" selection-end-line="18" selection-end-column="34" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="135">
|
|
||||||
<caret line="9" column="34" lean-forward="true" selection-start-line="9" selection-start-column="34" selection-end-line="9" selection-end-column="34" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutterwebview/WebViewActivity.java" />
|
|
||||||
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/java/com/pichillilorenzo/flutterwebviewexample/MainActivity.java">
|
<entry file="file://$PROJECT_DIR$/example/android/app/src/main/java/com/pichillilorenzo/flutterwebviewexample/MainActivity.java">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="135">
|
<state relative-caret-position="135">
|
||||||
@ -584,13 +629,6 @@
|
|||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state>
|
|
||||||
<caret column="6" selection-start-column="6" selection-end-column="26" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java">
|
<entry file="file://$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="1560">
|
<state relative-caret-position="1560">
|
||||||
@ -647,30 +685,6 @@
|
|||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state>
|
|
||||||
<caret line="1" column="64" selection-start-line="1" selection-start-column="64" selection-end-line="1" selection-end-column="64" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/README.md">
|
|
||||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
|
||||||
<state split_layout="SPLIT">
|
|
||||||
<first_editor relative-caret-position="256">
|
|
||||||
<caret line="52" column="66" selection-start-line="52" selection-start-column="66" selection-end-line="52" selection-end-column="66" />
|
|
||||||
</first_editor>
|
|
||||||
<second_editor>
|
|
||||||
<markdownNavigatorState />
|
|
||||||
</second_editor>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
<provider editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="247">
|
|
||||||
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/flutter_inappbrowser.iml">
|
<entry file="file://$PROJECT_DIR$/flutter_inappbrowser.iml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="330">
|
<state relative-caret-position="330">
|
||||||
@ -692,39 +706,92 @@
|
|||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
<entry file="file://$PROJECT_DIR$/example/assets/images/dart.svg">
|
||||||
|
<provider selected="true" editor-type-id="images">
|
||||||
|
<state />
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/css/style.css">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="5791">
|
<state relative-caret-position="75">
|
||||||
<caret line="429" column="3" selection-start-line="429" selection-start-column="3" selection-end-line="429" selection-end-column="3" />
|
<caret line="5" column="20" selection-start-line="5" selection-start-column="20" selection-end-line="5" selection-end-column="20" />
|
||||||
<folding>
|
</state>
|
||||||
<element signature="e#814#834#0" expanded="true" />
|
</provider>
|
||||||
</folding>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/assets/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="435">
|
||||||
|
<caret line="29" column="29" selection-start-line="29" selection-start-column="29" selection-end-line="29" selection-end-column="29" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="30">
|
<state relative-caret-position="180">
|
||||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
<caret line="12" column="14" selection-start-line="12" selection-start-column="14" selection-end-line="12" selection-end-column="14" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
<entry file="file://$PROJECT_DIR$/example/pubspec.yaml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="405">
|
||||||
|
<caret line="27" column="13" selection-start-line="27" selection-start-column="13" selection-end-line="27" selection-end-column="13" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="165">
|
||||||
|
<caret line="165" column="42" selection-start-line="165" selection-start-column="42" selection-end-line="165" selection-end-column="42" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#20#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="128">
|
||||||
|
<caret line="82" column="21" selection-start-line="82" selection-start-column="6" selection-end-line="82" selection-end-column="21" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#814#831#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="247">
|
||||||
|
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||||
<state split_layout="SPLIT">
|
<state split_layout="SPLIT">
|
||||||
<first_editor relative-caret-position="30">
|
<first_editor relative-caret-position="4980">
|
||||||
<caret line="2" column="39" selection-start-line="2" selection-start-column="39" selection-end-line="2" selection-end-column="39" />
|
<caret line="332" column="20" lean-forward="true" selection-start-line="332" selection-start-column="20" selection-end-line="332" selection-end-column="41" />
|
||||||
</first_editor>
|
</first_editor>
|
||||||
<second_editor>
|
<second_editor>
|
||||||
<markdownNavigatorState />
|
<markdownNavigatorState />
|
||||||
</second_editor>
|
</second_editor>
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||||
<provider editor-type-id="text-editor">
|
<provider editor-type-id="text-editor">
|
||||||
<state relative-caret-position="30">
|
<state relative-caret-position="30">
|
||||||
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
|
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
|
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||||
|
<state split_layout="SPLIT">
|
||||||
|
<first_editor relative-caret-position="135">
|
||||||
|
<caret line="9" lean-forward="true" selection-start-line="9" selection-end-line="9" />
|
||||||
|
</first_editor>
|
||||||
|
<second_editor>
|
||||||
|
<markdownNavigatorState />
|
||||||
|
</second_editor>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
</component>
|
</component>
|
||||||
<component name="masterDetails">
|
<component name="masterDetails">
|
||||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,3 +1,13 @@
|
|||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
- removed `target` parameter to `InAppBrowser.open()` method. To open the url on the system browser, use the `openWithSystemBrowser: true` option
|
||||||
|
- fixes for the `_ChannelManager` private class
|
||||||
|
- fixed `EXC_BAD_INSTRUCTION` onLoadStart in Swift
|
||||||
|
- added `openWithSystemBrowser` and `isLocalFile` options
|
||||||
|
- added `InAppBrowser.openWithSystemBrowser` method
|
||||||
|
- added `InAppBrowser.openOnLocalhost` method
|
||||||
|
- added `InAppBrowser.loadFile` method
|
||||||
|
|
||||||
## 0.3.2
|
## 0.3.2
|
||||||
|
|
||||||
- fixed WebView.storyboard path for iOS
|
- fixed WebView.storyboard path for iOS
|
||||||
|
87
README.md
87
README.md
@ -136,8 +136,8 @@ class _MyAppState extends State<MyApp> {
|
|||||||
title: const Text('Flutter InAppBrowser Plugin example app'),
|
title: const Text('Flutter InAppBrowser Plugin example app'),
|
||||||
),
|
),
|
||||||
body: new Center(
|
body: new Center(
|
||||||
child: new RaisedButton(onPressed: () {
|
child: new RaisedButton(onPressed: () async {
|
||||||
inAppBrowser.open(url: "https://flutter.io/", options: {
|
await inAppBrowser.open(url: "https://flutter.io/", options: {
|
||||||
"useShouldOverrideUrlLoading": true,
|
"useShouldOverrideUrlLoading": true,
|
||||||
"useOnLoadResource": true
|
"useOnLoadResource": true
|
||||||
});
|
});
|
||||||
@ -155,8 +155,10 @@ class _MyAppState extends State<MyApp> {
|
|||||||
|
|
||||||
Opens a URL in a new InAppBrowser instance or the system browser.
|
Opens a URL in a new InAppBrowser instance or the system browser.
|
||||||
|
|
||||||
|
**NOTE**: If you open the given `url` with the system browser (`openWithSystemBrowser: true`), you wont be able to use the `InAppBrowser` methods!
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
inAppBrowser.open({String url = "about:blank", Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}});
|
inAppBrowser.open({String url = "about:blank", Map<String, String> headers = const {}, Map<String, dynamic> options = const {}});
|
||||||
```
|
```
|
||||||
|
|
||||||
Opens an `url` in a new `InAppBrowser` instance or the system browser.
|
Opens an `url` in a new `InAppBrowser` instance or the system browser.
|
||||||
@ -165,17 +167,13 @@ Opens an `url` in a new `InAppBrowser` instance or the system browser.
|
|||||||
|
|
||||||
- `headers`: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
- `headers`: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
||||||
|
|
||||||
- `target`: The target in which to load the `url`, an optional parameter that defaults to `_self`.
|
|
||||||
|
|
||||||
- `_self`: Opens in the `InAppBrowser`.
|
|
||||||
- `_blank`: Opens in the `InAppBrowser`.
|
|
||||||
- `_system`: Opens in the system's web browser.
|
|
||||||
|
|
||||||
- `options`: Options for the `InAppBrowser`.
|
- `options`: Options for the `InAppBrowser`.
|
||||||
|
|
||||||
All platforms support:
|
All platforms support:
|
||||||
- __useShouldOverrideUrlLoading__: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`.
|
- __useShouldOverrideUrlLoading__: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`.
|
||||||
- __useOnLoadResource__: Set to `true` to be able to listen at the `onLoadResource()` event. The default value is `false`.
|
- __useOnLoadResource__: Set to `true` to be able to listen at the `onLoadResource()` event. The default value is `false`.
|
||||||
|
- __openWithSystemBrowser__: Set to `true` to open the given `url` with the system browser. The default value is `false`.
|
||||||
|
- __isLocalFile__: Set to `true` if the `url` is pointing to a local file (the file must be addded in the `assets` section of your `pubspec.yaml`. See `loadFile()` explanation). The default value is `false`.
|
||||||
- __clearCache__: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
- __clearCache__: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
||||||
- __userAgent___: Set the custom WebView's user-agent.
|
- __userAgent___: Set the custom WebView's user-agent.
|
||||||
- __javaScriptEnabled__: Set to `true` to enable JavaScript. The default value is `true`.
|
- __javaScriptEnabled__: Set to `true` to enable JavaScript. The default value is `true`.
|
||||||
@ -233,6 +231,33 @@ inAppBrowser.open('https://flutter.io/', options: {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### static Future\<void\> InAppBrowser.openWithSystemBrowser
|
||||||
|
|
||||||
|
This is a static method that opens an `url` in the system browser.
|
||||||
|
This has the same behaviour of an `InAppBrowser` instance calling the `open()` method with option `openWithSystemBrowser: true`.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
InAppBrowser.openWithSystemBrowser(String url);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Future\<void\> InAppBrowser.openOnLocalhost
|
||||||
|
|
||||||
|
Serve the `assetFilePath` from Flutter assets on http://localhost:`port`/. It is similar to `InAppBrowser.open()` with option `isLocalFile: true`, but it starts a server.
|
||||||
|
|
||||||
|
**NOTE for iOS**: For the iOS Platform, you need to add the `NSAllowsLocalNetworking` key with `true` in the `Info.plist` file (See [ATS Configuration Basics](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35):
|
||||||
|
```xml
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
```
|
||||||
|
The `NSAllowsLocalNetworking` key is available since **iOS 10**.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
inAppBrowser.openOnLocalhost(String assetFilePath, {int port = 8080, Map<String, String> headers = const {}, Map<String, dynamic> options = const {}});
|
||||||
|
```
|
||||||
|
|
||||||
#### Events
|
#### Events
|
||||||
|
|
||||||
Event fires when the `InAppBrowser` starts to load an `url`.
|
Event fires when the `InAppBrowser` starts to load an `url`.
|
||||||
@ -305,6 +330,42 @@ Loads the given `url` with optional `headers` specified as a map from name to va
|
|||||||
inAppBrowser.loadUrl(String url, {Map<String, String> headers = const {}});
|
inAppBrowser.loadUrl(String url, {Map<String, String> headers = const {}});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Future\<void\> InAppBrowser.loadFile
|
||||||
|
|
||||||
|
Loads the given `assetFilePath` with optional `headers` specified as a map from name to value.
|
||||||
|
|
||||||
|
To be able to load your local files (assets, js, css, etc.), you need to add them in the `assets` section of the `pubspec.yaml` file, otherwise they cannot be found!
|
||||||
|
|
||||||
|
Example of a `pubspec.yaml` file:
|
||||||
|
```yaml
|
||||||
|
...
|
||||||
|
|
||||||
|
# The following section is specific to Flutter.
|
||||||
|
flutter:
|
||||||
|
|
||||||
|
# The following line ensures that the Material Icons font is
|
||||||
|
# included with your application, so that you can use the icons in
|
||||||
|
# the material Icons class.
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
assets:
|
||||||
|
- assets/index.html
|
||||||
|
- assets/css/
|
||||||
|
- assets/images/
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
Example of a `main.dart` file:
|
||||||
|
```dart
|
||||||
|
...
|
||||||
|
inAppBrowser.loadFile("assets/index.html");
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
```dart
|
||||||
|
inAppBrowser.loadFile(String assetFilePath, {Map<String, String> headers = const {}});
|
||||||
|
```
|
||||||
|
|
||||||
#### Future\<void\> InAppBrowser.show
|
#### Future\<void\> InAppBrowser.show
|
||||||
|
|
||||||
Displays an `InAppBrowser` window that was opened hidden. Calling this has no effect if the `InAppBrowser` was already visible.
|
Displays an `InAppBrowser` window that was opened hidden. Calling this has no effect if the `InAppBrowser` was already visible.
|
||||||
@ -379,7 +440,7 @@ inAppBrowser.isHidden();
|
|||||||
|
|
||||||
#### Future\<String\> InAppBrowser.injectScriptCode
|
#### Future\<String\> InAppBrowser.injectScriptCode
|
||||||
|
|
||||||
Injects JavaScript code into the `InAppBrowser` window and returns the result of the evaluation. (Only available when the target is set to `_blank` or to `_self`)
|
Injects JavaScript code into the `InAppBrowser` window and returns the result of the evaluation.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
inAppBrowser.injectScriptCode(String source);
|
inAppBrowser.injectScriptCode(String source);
|
||||||
@ -387,7 +448,7 @@ inAppBrowser.injectScriptCode(String source);
|
|||||||
|
|
||||||
#### Future\<void\> InAppBrowser.injectScriptFile
|
#### Future\<void\> InAppBrowser.injectScriptFile
|
||||||
|
|
||||||
Injects a JavaScript file into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)
|
Injects a JavaScript file into the `InAppBrowser` window.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
inAppBrowser.injectScriptFile(String urlFile);
|
inAppBrowser.injectScriptFile(String urlFile);
|
||||||
@ -395,7 +456,7 @@ inAppBrowser.injectScriptFile(String urlFile);
|
|||||||
|
|
||||||
#### Future\<void\> InAppBrowser.injectStyleCode
|
#### Future\<void\> InAppBrowser.injectStyleCode
|
||||||
|
|
||||||
Injects CSS into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)
|
Injects CSS into the `InAppBrowser` window.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
inAppBrowser.injectStyleCode(String source);
|
inAppBrowser.injectStyleCode(String source);
|
||||||
@ -403,7 +464,7 @@ inAppBrowser.injectStyleCode(String source);
|
|||||||
|
|
||||||
#### Future\<void\> InAppBrowser.injectStyleFile
|
#### Future\<void\> InAppBrowser.injectStyleFile
|
||||||
|
|
||||||
Injects a CSS file into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)
|
Injects a CSS file into the `InAppBrowser` window.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
inAppBrowser.injectStyleFile(String urlFile);
|
inAppBrowser.injectStyleFile(String urlFile);
|
||||||
|
@ -25,6 +25,7 @@ import android.app.Activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.Browser;
|
import android.provider.Browser;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -40,8 +41,10 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs.ChromeCustomTabsActivity;
|
import com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs.ChromeCustomTabsActivity;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs.ChromeCustomTabsOptions;
|
import com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs.ChromeCustomTabsOptions;
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs.CustomTabActivityHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -55,7 +58,9 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
|||||||
import io.flutter.plugin.common.MethodChannel.Result;
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||||
|
|
||||||
/** InAppBrowserFlutterPlugin */
|
/**
|
||||||
|
* InAppBrowserFlutterPlugin
|
||||||
|
*/
|
||||||
public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
||||||
|
|
||||||
public static Registrar registrar;
|
public static Registrar registrar;
|
||||||
@ -64,9 +69,9 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
public static Map<String, WebViewActivity> webViewActivities = new HashMap<>();
|
public static Map<String, WebViewActivity> webViewActivities = new HashMap<>();
|
||||||
public static Map<String, ChromeCustomTabsActivity> chromeCustomTabsActivities = new HashMap<>();
|
public static Map<String, ChromeCustomTabsActivity> chromeCustomTabsActivities = new HashMap<>();
|
||||||
|
|
||||||
private static final String NULL = "null";
|
protected static final String LOG_TAG = "IABFlutterPlugin";
|
||||||
protected static final String LOG_TAG = "InAppBrowserFlutterP";
|
|
||||||
|
|
||||||
|
static final String ANDROID_ASSET_URL = "file:///android_asset/";
|
||||||
|
|
||||||
public InAppBrowserFlutterPlugin(Registrar r, Activity activity) {
|
public InAppBrowserFlutterPlugin(Registrar r, Activity activity) {
|
||||||
registrar = r;
|
registrar = r;
|
||||||
@ -74,7 +79,9 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
|
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Plugin registration. */
|
/**
|
||||||
|
* Plugin registration.
|
||||||
|
*/
|
||||||
public static void registerWith(Registrar registrar) {
|
public static void registerWith(Registrar registrar) {
|
||||||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
|
final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
|
||||||
channel.setMethodCallHandler(new InAppBrowserFlutterPlugin(registrar, registrar.activity()));
|
channel.setMethodCallHandler(new InAppBrowserFlutterPlugin(registrar, registrar.activity()));
|
||||||
@ -89,15 +96,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "open":
|
case "open":
|
||||||
final String url = call.argument("url").toString();
|
final String url_final = call.argument("url").toString();
|
||||||
|
|
||||||
String t = call.argument("target").toString();
|
|
||||||
if (t == null || t.equals("") || t.equals(NULL)) {
|
|
||||||
t = "_self";
|
|
||||||
}
|
|
||||||
final String target = t;
|
|
||||||
|
|
||||||
Log.d(LOG_TAG, "target = " + target);
|
|
||||||
|
|
||||||
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
|
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
|
||||||
|
|
||||||
@ -119,19 +118,48 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
final InAppBrowserOptions optionsFallback = new InAppBrowserOptions();
|
final InAppBrowserOptions optionsFallback = new InAppBrowserOptions();
|
||||||
optionsFallback.parse((HashMap<String, Object>) call.argument("optionsFallback"));
|
optionsFallback.parse((HashMap<String, Object>) call.argument("optionsFallback"));
|
||||||
|
|
||||||
open(uuid, uuidFallback, url, options, headers,true, optionsFallback);
|
open(uuid, uuidFallback, url_final, options, headers, true, optionsFallback, result);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
String url = url_final;
|
||||||
|
|
||||||
final InAppBrowserOptions options = new InAppBrowserOptions();
|
final InAppBrowserOptions options = new InAppBrowserOptions();
|
||||||
options.parse((HashMap<String, Object>) call.argument("options"));
|
options.parse((HashMap<String, Object>) call.argument("options"));
|
||||||
|
|
||||||
if ("_self".equals(target)) {
|
if (options.isLocalFile) {
|
||||||
Log.d(LOG_TAG, "in self");
|
// check if the asset file exists
|
||||||
|
String key = registrar.lookupKeyForAsset(url);
|
||||||
|
AssetManager mg = registrar.activeContext().getResources().getAssets();
|
||||||
|
InputStream is = null;
|
||||||
|
boolean assetExists = false;
|
||||||
|
try {
|
||||||
|
is = mg.open(key);
|
||||||
|
assetExists = true;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!assetExists) {
|
||||||
|
result.error(LOG_TAG, key + " asset file cannot be found!", null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
url = ANDROID_ASSET_URL + key;
|
||||||
|
}
|
||||||
|
// SYSTEM
|
||||||
|
if (options.openWithSystemBrowser) {
|
||||||
|
Log.d(LOG_TAG, "in system");
|
||||||
|
openExternal(url, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
//Load the dialer
|
//Load the dialer
|
||||||
if (url.startsWith(WebView.SCHEME_TEL))
|
if (url.startsWith(WebView.SCHEME_TEL)) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
Log.d(LOG_TAG, "loading in dialer");
|
Log.d(LOG_TAG, "loading in dialer");
|
||||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
@ -144,31 +172,21 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
// load in InAppBrowserFlutterPlugin
|
// load in InAppBrowserFlutterPlugin
|
||||||
else {
|
else {
|
||||||
Log.d(LOG_TAG, "loading in InAppBrowserFlutterPlugin");
|
Log.d(LOG_TAG, "loading in InAppBrowserFlutterPlugin");
|
||||||
open(uuid, null, url, options, headers, false, null);
|
open(uuid, null, url, options, headers, false, null, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SYSTEM
|
|
||||||
else if ("_system".equals(target)) {
|
|
||||||
Log.d(LOG_TAG, "in system");
|
|
||||||
openExternal(url);
|
|
||||||
}
|
}
|
||||||
// BLANK - or anything else
|
|
||||||
else {
|
|
||||||
Log.d(LOG_TAG, "in blank");
|
|
||||||
open(uuid, null, url, options, headers, false, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.success(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "loadUrl":
|
case "loadUrl":
|
||||||
loadUrl(uuid, call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
|
loadUrl(uuid, call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
|
||||||
break;
|
break;
|
||||||
|
case "loadFile":
|
||||||
|
loadFile(uuid, call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
|
||||||
|
break;
|
||||||
case "close":
|
case "close":
|
||||||
close(uuid);
|
close(uuid, result);
|
||||||
result.success(true);
|
|
||||||
break;
|
break;
|
||||||
case "injectScriptCode":
|
case "injectScriptCode":
|
||||||
source = call.argument("source").toString();
|
source = call.argument("source").toString();
|
||||||
@ -237,13 +255,14 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject an object (script or style) into the InAppBrowserFlutterPlugin WebView.
|
* Inject an object (script or style) into the InAppBrowserFlutterPlugin WebView.
|
||||||
*
|
* <p>
|
||||||
* This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
* This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
||||||
* provides a consistent method for injecting JavaScript code into the document.
|
* provides a consistent method for injecting JavaScript code into the document.
|
||||||
*
|
* <p>
|
||||||
* If a wrapper string is supplied, then the source string will be JSON-encoded (adding
|
* If a wrapper string is supplied, then the source string will be JSON-encoded (adding
|
||||||
* quotes) and wrapped using string formatting. (The wrapper string should have a single
|
* quotes) and wrapped using string formatting. (The wrapper string should have a single
|
||||||
* '%s' marker)
|
* '%s' marker)
|
||||||
|
*
|
||||||
* @param uuid
|
* @param uuid
|
||||||
* @param source The source object (filename or script/style text) to inject into
|
* @param source The source object (filename or script/style text) to inject into
|
||||||
* the document.
|
* the document.
|
||||||
@ -295,8 +314,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
msg = reader2.nextString();
|
msg = reader2.nextString();
|
||||||
|
|
||||||
result.success(msg);
|
result.success(msg);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.success("");
|
result.success("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,9 +350,10 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
* Display a new browser with the specified URL.
|
* Display a new browser with the specified URL.
|
||||||
*
|
*
|
||||||
* @param url the url to load.
|
* @param url the url to load.
|
||||||
|
* @param result
|
||||||
* @return "" if ok, or error message.
|
* @return "" if ok, or error message.
|
||||||
*/
|
*/
|
||||||
public void openExternal(String url) {
|
public void openExternal(String url, Result result) {
|
||||||
try {
|
try {
|
||||||
Intent intent;
|
Intent intent;
|
||||||
intent = new Intent(Intent.ACTION_VIEW);
|
intent = new Intent(Intent.ACTION_VIEW);
|
||||||
@ -349,9 +368,11 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
|
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
|
||||||
// CB-10795: Avoid circular loops by preventing it from opening in the current app
|
// CB-10795: Avoid circular loops by preventing it from opening in the current app
|
||||||
this.openExternalExcludeCurrentApp(intent);
|
this.openExternalExcludeCurrentApp(intent);
|
||||||
|
result.success(true);
|
||||||
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
|
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
|
||||||
} catch (java.lang.RuntimeException e) {
|
} catch (java.lang.RuntimeException e) {
|
||||||
Log.d(LOG_TAG, "InAppBrowserFlutterPlugin: Error loading url "+url+":"+ e.toString());
|
Log.d(LOG_TAG, url + " cannot be opened: " + e.toString());
|
||||||
|
result.error(LOG_TAG, url + " cannot be opened!", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,8 +391,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
Intent targetIntent = (Intent) intent.clone();
|
Intent targetIntent = (Intent) intent.clone();
|
||||||
targetIntent.setPackage(ri.activityInfo.packageName);
|
targetIntent.setPackage(ri.activityInfo.packageName);
|
||||||
targetIntents.add(targetIntent);
|
targetIntents.add(targetIntent);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
hasCurrentPackage = true;
|
hasCurrentPackage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,25 +412,47 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void open(String uuid, String uuidFallback, final String url, Options options, Map<String, String> headers, boolean useChromeSafariBrowser, InAppBrowserOptions optionsFallback) {
|
public void open(String uuid, String uuidFallback, String url, Options options, Map<String, String> headers, boolean useChromeSafariBrowser, InAppBrowserOptions optionsFallback, Result result) {
|
||||||
Intent intent = new Intent(registrar.activity(), (useChromeSafariBrowser) ? ChromeCustomTabsActivity.class : WebViewActivity.class);
|
|
||||||
|
|
||||||
|
Intent intent = null;
|
||||||
Bundle extras = new Bundle();
|
Bundle extras = new Bundle();
|
||||||
extras.putString("uuid", uuid);
|
|
||||||
extras.putString("url", url);
|
extras.putString("url", url);
|
||||||
|
|
||||||
|
extras.putString("uuid", uuid);
|
||||||
extras.putSerializable("options", options.getHashMap());
|
extras.putSerializable("options", options.getHashMap());
|
||||||
extras.putSerializable("headers", (Serializable) headers);
|
extras.putSerializable("headers", (Serializable) headers);
|
||||||
if (useChromeSafariBrowser) {
|
|
||||||
extras.putString("uuidFallback", uuidFallback);
|
if (useChromeSafariBrowser && CustomTabActivityHelper.isAvailable(activity)) {
|
||||||
|
intent = new Intent(activity, ChromeCustomTabsActivity.class);
|
||||||
|
}
|
||||||
|
// check for webview fallback
|
||||||
|
else if (useChromeSafariBrowser && !CustomTabActivityHelper.isAvailable(activity) && !uuidFallback.isEmpty()) {
|
||||||
|
Log.d(LOG_TAG, "WebView fallback declared.");
|
||||||
|
// overwrite with extras fallback parameters
|
||||||
|
extras.putString("uuid", uuidFallback);
|
||||||
if (optionsFallback != null)
|
if (optionsFallback != null)
|
||||||
extras.putSerializable("optionsFallback", optionsFallback.getHashMap());
|
extras.putSerializable("options", optionsFallback.getHashMap());
|
||||||
else
|
else
|
||||||
extras.putSerializable("optionsFallback", (new InAppBrowserOptions()).getHashMap());
|
extras.putSerializable("options", (new InAppBrowserOptions()).getHashMap());
|
||||||
|
extras.putSerializable("headers", (Serializable) headers);
|
||||||
|
intent = new Intent(activity, WebViewActivity.class);
|
||||||
|
}
|
||||||
|
// native webview
|
||||||
|
else if (!useChromeSafariBrowser) {
|
||||||
|
intent = new Intent(activity, WebViewActivity.class);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.d(LOG_TAG, "No WebView fallback declared.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (intent != null) {
|
||||||
intent.putExtras(extras);
|
intent.putExtras(extras);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
result.success(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
registrar.activity().startActivity(intent);
|
result.error(LOG_TAG, "No WebView fallback declared.", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadUrl(String uuid, String url, Map<String, String> headers, Result result) {
|
public void loadUrl(String uuid, String url, Map<String, String> headers, Result result) {
|
||||||
@ -423,6 +465,16 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadFile(String uuid, String url, Map<String, String> headers, Result result) {
|
||||||
|
WebViewActivity webViewActivity = webViewActivities.get(uuid);
|
||||||
|
if (webViewActivity != null) {
|
||||||
|
if (headers != null)
|
||||||
|
webViewActivity.loadFile(url, headers, result);
|
||||||
|
else
|
||||||
|
webViewActivity.loadFile(url, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void show(String uuid) {
|
public void show(String uuid) {
|
||||||
WebViewActivity webViewActivity = webViewActivities.get(uuid);
|
WebViewActivity webViewActivity = webViewActivities.get(uuid);
|
||||||
if (webViewActivity != null)
|
if (webViewActivity != null)
|
||||||
@ -488,7 +540,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void close(final String uuid) {
|
public static void close(final String uuid, final Result result) {
|
||||||
final WebViewActivity webViewActivity = webViewActivities.get(uuid);
|
final WebViewActivity webViewActivity = webViewActivities.get(uuid);
|
||||||
if (webViewActivity != null) {
|
if (webViewActivity != null) {
|
||||||
registrar.activity().runOnUiThread(new Runnable() {
|
registrar.activity().runOnUiThread(new Runnable() {
|
||||||
@ -501,8 +553,12 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
// The JS protects against multiple calls, so this should happen only when
|
// The JS protects against multiple calls, so this should happen only when
|
||||||
// close() is called by other native code.
|
// close() is called by other native code.
|
||||||
if (webViewActivity == null)
|
if (webViewActivity == null) {
|
||||||
|
if (result != null) {
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
webViewActivity.webView.setWebViewClient(new WebViewClient() {
|
webViewActivity.webView.setWebViewClient(new WebViewClient() {
|
||||||
// NB: wait for about:blank before dismissing
|
// NB: wait for about:blank before dismissing
|
||||||
@ -514,8 +570,14 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
// other than your app's UI thread, it can cause unexpected results."
|
// other than your app's UI thread, it can cause unexpected results."
|
||||||
// http://developer.android.com/guide/webapps/migrating.html#Threads
|
// http://developer.android.com/guide/webapps/migrating.html#Threads
|
||||||
webViewActivity.webView.loadUrl("about:blank");
|
webViewActivity.webView.loadUrl("about:blank");
|
||||||
|
if (result != null) {
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (result != null) {
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,11 @@ package com.pichillilorenzo.flutter_inappbrowser;
|
|||||||
|
|
||||||
public class InAppBrowserOptions extends Options {
|
public class InAppBrowserOptions extends Options {
|
||||||
|
|
||||||
final static String LOG_TAG = "InAppBrowserOptions";
|
static final String LOG_TAG = "InAppBrowserOptions";
|
||||||
|
|
||||||
public boolean useShouldOverrideUrlLoading = false;
|
public boolean useShouldOverrideUrlLoading = false;
|
||||||
public boolean useOnLoadResource = false;
|
public boolean useOnLoadResource = false;
|
||||||
|
public boolean openWithSystemBrowser = false;
|
||||||
public boolean clearCache = false;
|
public boolean clearCache = false;
|
||||||
public String userAgent = "";
|
public String userAgent = "";
|
||||||
public boolean javaScriptEnabled = true;
|
public boolean javaScriptEnabled = true;
|
||||||
@ -16,6 +17,7 @@ public class InAppBrowserOptions extends Options {
|
|||||||
public String toolbarTopFixedTitle = "";
|
public String toolbarTopFixedTitle = "";
|
||||||
public boolean hideUrlBar = false;
|
public boolean hideUrlBar = false;
|
||||||
public boolean mediaPlaybackRequiresUserGesture = true;
|
public boolean mediaPlaybackRequiresUserGesture = true;
|
||||||
|
public boolean isLocalFile = false;
|
||||||
|
|
||||||
public boolean hideTitleBar = false;
|
public boolean hideTitleBar = false;
|
||||||
public boolean closeOnCannotGoBack = true;
|
public boolean closeOnCannotGoBack = true;
|
||||||
|
@ -45,8 +45,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
|
|||||||
activity.progressBar.setVisibility(View.VISIBLE);
|
activity.progressBar.setVisibility(View.VISIBLE);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
activity.progressBar.setProgress(progress, true);
|
activity.progressBar.setProgress(progress, true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
activity.progressBar.setProgress(progress);
|
activity.progressBar.setProgress(progress);
|
||||||
}
|
}
|
||||||
if (progress == 100) {
|
if (progress == 100) {
|
||||||
|
@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
@ -106,8 +107,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
} else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) {
|
||||||
else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) {
|
|
||||||
try {
|
try {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(url));
|
intent.setData(Uri.parse(url));
|
||||||
@ -180,7 +180,6 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void onPageFinished(WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
super.onPageFinished(view, url);
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
@ -201,6 +200,10 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||||||
view.evaluateJavascript(WebViewActivity.consoleLogJS, null);
|
view.evaluateJavascript(WebViewActivity.consoleLogJS, null);
|
||||||
view.evaluateJavascript(JavaScriptBridgeInterface.flutterInAppBroserJSClass, null);
|
view.evaluateJavascript(JavaScriptBridgeInterface.flutterInAppBroserJSClass, null);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
view.loadUrl("javascript:"+WebViewActivity.consoleLogJS);
|
||||||
|
view.loadUrl("javascript:"+JavaScriptBridgeInterface.flutterInAppBroserJSClass);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
obj.put("uuid", activity.uuid);
|
obj.put("uuid", activity.uuid);
|
||||||
@ -281,6 +284,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||||||
long startResourceTime = System.currentTimeMillis();
|
long startResourceTime = System.currentTimeMillis();
|
||||||
Response response = activity.httpClient.newCall(mRequest).execute();
|
Response response = activity.httpClient.newCall(mRequest).execute();
|
||||||
long startTime = startResourceTime - startPageTime;
|
long startTime = startResourceTime - startPageTime;
|
||||||
|
startTime = (startTime < 0) ? 0 : startTime;
|
||||||
long duration = System.currentTimeMillis() - startResourceTime;
|
long duration = System.currentTimeMillis() - startResourceTime;
|
||||||
|
|
||||||
if (response.cacheResponse() != null) {
|
if (response.cacheResponse() != null) {
|
||||||
|
@ -10,9 +10,9 @@ public class JavaScriptBridgeInterface {
|
|||||||
static final String name = "flutter_inappbrowser";
|
static final String name = "flutter_inappbrowser";
|
||||||
WebViewActivity activity;
|
WebViewActivity activity;
|
||||||
|
|
||||||
static final String flutterInAppBroserJSClass = "window." + name + ".callHandler = function(handlerName, ...args) {\n" +
|
static final String flutterInAppBroserJSClass = "window." + name + ".callHandler = function(handlerName, ...args) {" +
|
||||||
"window." + name + "._callHandler(handlerName, JSON.stringify(args));\n" +
|
"window." + name + "._callHandler(handlerName, JSON.stringify(args));" +
|
||||||
"}\n";
|
"}";
|
||||||
|
|
||||||
JavaScriptBridgeInterface(WebViewActivity a) {
|
JavaScriptBridgeInterface(WebViewActivity a) {
|
||||||
activity = a;
|
activity = a;
|
||||||
|
@ -9,9 +9,9 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
public class Options {
|
public class Options {
|
||||||
|
|
||||||
final static String LOG_TAG = "";
|
static String LOG_TAG = "";
|
||||||
|
|
||||||
public void parse(HashMap<String, Object> options) {
|
public Options parse(HashMap<String, Object> options) {
|
||||||
Iterator it = options.entrySet().iterator();
|
Iterator it = options.entrySet().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Map.Entry<String, Object> pair = (Map.Entry<String, Object>) it.next();
|
Map.Entry<String, Object> pair = (Map.Entry<String, Object>) it.next();
|
||||||
@ -23,6 +23,7 @@ public class Options {
|
|||||||
Log.d(LOG_TAG, e.getMessage());
|
Log.d(LOG_TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, Object> getHashMap() {
|
public HashMap<String, Object> getHashMap() {
|
||||||
|
@ -41,30 +41,30 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
public boolean isHidden = false;
|
public boolean isHidden = false;
|
||||||
OkHttpClient httpClient;
|
OkHttpClient httpClient;
|
||||||
|
|
||||||
static final String consoleLogJS = "(function() {\n"+
|
static final String consoleLogJS = "(function() {" +
|
||||||
" var oldLogs = {\n"+
|
" var oldLogs = {" +
|
||||||
" 'log': console.log,\n"+
|
" 'log': console.log," +
|
||||||
" 'debug': console.debug,\n"+
|
" 'debug': console.debug," +
|
||||||
" 'error': console.error,\n"+
|
" 'error': console.error," +
|
||||||
" 'info': console.info,\n"+
|
" 'info': console.info," +
|
||||||
" 'warn': console.warn\n"+
|
" 'warn': console.warn" +
|
||||||
" };\n"+
|
" };" +
|
||||||
" for (var k in oldLogs) {\n"+
|
" for (var k in oldLogs) {" +
|
||||||
" (function(oldLog) {\n"+
|
" (function(oldLog) {" +
|
||||||
" console[oldLog] = function() {\n"+
|
" console[oldLog] = function() {" +
|
||||||
" var message = ''\n"+
|
" var message = '';" +
|
||||||
" for (var i in arguments) {\n"+
|
" for (var i in arguments) {" +
|
||||||
" if (message == '') {\n"+
|
" if (message == '') {" +
|
||||||
" message += arguments[i];\n"+
|
" message += arguments[i];" +
|
||||||
" }\n"+
|
" }" +
|
||||||
" else {\n"+
|
" else {" +
|
||||||
" message += ' ' + arguments[i];\n"+
|
" message += ' ' + arguments[i];" +
|
||||||
" }\n"+
|
" }" +
|
||||||
" }\n"+
|
" }" +
|
||||||
" oldLogs[oldLog].call(console, message);\n"+
|
" oldLogs[oldLog].call(console, message);" +
|
||||||
" }\n"+
|
" }" +
|
||||||
" })(k);\n"+
|
" })(k);" +
|
||||||
" }\n"+
|
" }" +
|
||||||
"})();";
|
"})();";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,7 +94,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
httpClient = new OkHttpClient().newBuilder().cache(new Cache(getApplicationContext().getCacheDir(), cacheSize)).build();
|
httpClient = new OkHttpClient().newBuilder().cache(new Cache(getApplicationContext().getCacheDir(), cacheSize)).build();
|
||||||
|
|
||||||
webView.loadUrl(url, headers);
|
webView.loadUrl(url, headers);
|
||||||
//webView.loadData("<!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>Document</title> </head> <body> ciao <img src=\"https://via.placeholder.com/350x150\" /> <img src=\"./images/test\" alt=\"not found\" /></body> </html>", "text/html", "utf8");
|
//webView.loadData("<!DOCTYPE assets> <assets lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>Document</title> </head> <body> ciao <img src=\"https://via.placeholder.com/350x150\" /> <img src=\"./images/test\" alt=\"not found\" /></body> </assets>", "text/assets", "utf8");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,8 +259,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
public void loadUrl(String url, MethodChannel.Result result) {
|
public void loadUrl(String url, MethodChannel.Result result) {
|
||||||
if (webView != null && !url.isEmpty()) {
|
if (webView != null && !url.isEmpty()) {
|
||||||
webView.loadUrl(url);
|
webView.loadUrl(url);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.error("Cannot load url", "", null);
|
result.error("Cannot load url", "", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,8 +267,23 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
public void loadUrl(String url, Map<String, String> headers, MethodChannel.Result result) {
|
public void loadUrl(String url, Map<String, String> headers, MethodChannel.Result result) {
|
||||||
if (webView != null && !url.isEmpty()) {
|
if (webView != null && !url.isEmpty()) {
|
||||||
webView.loadUrl(url, headers);
|
webView.loadUrl(url, headers);
|
||||||
|
} else {
|
||||||
|
result.error("Cannot load url", "", null);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
|
||||||
|
public void loadFile(String url, MethodChannel.Result result) {
|
||||||
|
if (webView != null && !url.isEmpty()) {
|
||||||
|
webView.loadUrl(url);
|
||||||
|
} else {
|
||||||
|
result.error("Cannot load url", "", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadFile(String url, Map<String, String> headers, MethodChannel.Result result) {
|
||||||
|
if (webView != null && !url.isEmpty()) {
|
||||||
|
webView.loadUrl(url, headers);
|
||||||
|
} else {
|
||||||
result.error("Cannot load url", "", null);
|
result.error("Cannot load url", "", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,7 +293,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
if (canGoBack())
|
if (canGoBack())
|
||||||
goBack();
|
goBack();
|
||||||
else if (options.closeOnCannotGoBack)
|
else if (options.closeOnCannotGoBack)
|
||||||
InAppBrowserFlutterPlugin.close(uuid);
|
InAppBrowserFlutterPlugin.close(uuid, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
@ -319,6 +333,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
openActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
openActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||||
startActivityIfNeeded(openActivity, 0);
|
startActivityIfNeeded(openActivity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
isHidden = false;
|
isHidden = false;
|
||||||
Intent openActivity = new Intent(InAppBrowserFlutterPlugin.registrar.activity(), WebViewActivity.class);
|
Intent openActivity = new Intent(InAppBrowserFlutterPlugin.registrar.activity(), WebViewActivity.class);
|
||||||
@ -376,7 +391,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void closeButtonClicked(MenuItem item) {
|
public void closeButtonClicked(MenuItem item) {
|
||||||
InAppBrowserFlutterPlugin.close(uuid);
|
InAppBrowserFlutterPlugin.close(uuid, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,8 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
|
|
||||||
protected static final String LOG_TAG = "CustomTabsActivity";
|
protected static final String LOG_TAG = "CustomTabsActivity";
|
||||||
String uuid;
|
String uuid;
|
||||||
String uuidFallback;
|
|
||||||
CustomTabsIntent.Builder builder;
|
CustomTabsIntent.Builder builder;
|
||||||
ChromeCustomTabsOptions options;
|
ChromeCustomTabsOptions options;
|
||||||
Map<String, String> headersFallback;
|
|
||||||
InAppBrowserOptions optionsFallback;
|
|
||||||
private CustomTabActivityHelper customTabActivityHelper;
|
private CustomTabActivityHelper customTabActivityHelper;
|
||||||
private final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
private final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
||||||
|
|
||||||
@ -34,18 +31,13 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
setContentView(R.layout.chrome_custom_tabs_layout);
|
setContentView(R.layout.chrome_custom_tabs_layout);
|
||||||
|
|
||||||
Bundle b = getIntent().getExtras();
|
Bundle b = getIntent().getExtras();
|
||||||
|
assert b != null;
|
||||||
uuid = b.getString("uuid");
|
uuid = b.getString("uuid");
|
||||||
uuidFallback = b.getString("uuidFallback");
|
|
||||||
String url = b.getString("url");
|
String url = b.getString("url");
|
||||||
|
|
||||||
options = new ChromeCustomTabsOptions();
|
options = new ChromeCustomTabsOptions();
|
||||||
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
||||||
|
|
||||||
headersFallback = (HashMap<String, String>) b.getSerializable("headers");
|
|
||||||
|
|
||||||
optionsFallback = new InAppBrowserOptions();
|
|
||||||
optionsFallback.parse((HashMap<String, Object>) b.getSerializable("optionsFallback"));
|
|
||||||
|
|
||||||
InAppBrowserFlutterPlugin.chromeCustomTabsActivities.put(uuid, this);
|
InAppBrowserFlutterPlugin.chromeCustomTabsActivities.put(uuid, this);
|
||||||
|
|
||||||
customTabActivityHelper = new CustomTabActivityHelper();
|
customTabActivityHelper = new CustomTabActivityHelper();
|
||||||
@ -55,26 +47,13 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
|
|
||||||
CustomTabsIntent customTabsIntent = builder.build();
|
CustomTabsIntent customTabsIntent = builder.build();
|
||||||
|
|
||||||
boolean chromeCustomTabsOpened = customTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), CHROME_CUSTOM_TAB_REQUEST_CODE,
|
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||||
new CustomTabActivityHelper.CustomTabFallback() {
|
|
||||||
@Override
|
|
||||||
public void openUri(Activity activity, Uri uri) {
|
|
||||||
if (!uuidFallback.isEmpty())
|
|
||||||
InAppBrowserFlutterPlugin.open(uuidFallback, null, uri.toString(), optionsFallback, headersFallback, false, null);
|
|
||||||
else {
|
|
||||||
Log.d(LOG_TAG, "No WebView fallback declared.");
|
|
||||||
activity.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (chromeCustomTabsOpened) {
|
|
||||||
Map<String, Object> obj = new HashMap<>();
|
Map<String, Object> obj = new HashMap<>();
|
||||||
obj.put("uuid", uuid);
|
obj.put("uuid", uuid);
|
||||||
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserOpened", obj);
|
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserOpened", obj);
|
||||||
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserLoaded", obj);
|
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserLoaded", obj);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void prepareCustomTabs() {
|
private void prepareCustomTabs() {
|
||||||
if (options.addShareButton)
|
if (options.addShareButton)
|
||||||
|
@ -27,26 +27,13 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
* @param activity The host activity.
|
* @param activity The host activity.
|
||||||
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
|
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
|
||||||
* @param uri the Uri to be opened.
|
* @param uri the Uri to be opened.
|
||||||
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
|
|
||||||
*/
|
*/
|
||||||
public static boolean openCustomTab(Activity activity,
|
public static void openCustomTab(Activity activity,
|
||||||
CustomTabsIntent customTabsIntent,
|
CustomTabsIntent customTabsIntent,
|
||||||
Uri uri,
|
Uri uri,
|
||||||
int requestCode,
|
int requestCode) {
|
||||||
CustomTabFallback fallback) {
|
|
||||||
//If we cant find a package name, it means theres no browser that supports
|
|
||||||
//Chrome Custom Tabs installed. So, we fallback to the webview
|
|
||||||
if (!isAvailable(activity)) {
|
|
||||||
if (fallback != null) {
|
|
||||||
fallback.openUri(activity, uri);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//customTabsIntent.intent.setPackage(packageName);
|
|
||||||
customTabsIntent.intent.setData(uri);
|
customTabsIntent.intent.setData(uri);
|
||||||
activity.startActivityForResult(customTabsIntent.intent, requestCode);
|
activity.startActivityForResult(customTabsIntent.intent, requestCode);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAvailable(Activity activity) {
|
public static boolean isAvailable(Activity activity) {
|
||||||
@ -144,16 +131,4 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
void onCustomTabsDisconnected();
|
void onCustomTabsDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* To be used as a fallback to open the Uri when Custom Tabs is not available.
|
|
||||||
*/
|
|
||||||
public interface CustomTabFallback {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param activity The Activity that wants to open the Uri.
|
|
||||||
* @param uri The uri to be opened by the fallback.
|
|
||||||
*/
|
|
||||||
void openUri(Activity activity, Uri uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
7
example/assets/css/style.css
Normal file
7
example/assets/css/style.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
body {
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
50
example/assets/images/dart.svg
Normal file
50
example/assets/images/dart.svg
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 439 137.29" enable-background="new 0 0 439 137.29" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g opacity="0.54">
|
||||||
|
<path d="M207.08,20.2h27.55c9.35,0,17.51,1.93,24.49,5.8c6.97,3.87,12.33,9.25,16.07,16.13c3.74,6.89,5.61,14.79,5.61,23.72
|
||||||
|
s-1.87,16.83-5.61,23.72s-9.1,12.26-16.07,16.13c-6.97,3.87-15.13,5.8-24.49,5.8h-27.55V20.2z M234.63,101.19
|
||||||
|
c10.8,0,19.36-3.1,25.7-9.31c6.33-6.21,9.5-14.88,9.5-26.02s-3.17-19.81-9.5-26.02c-6.33-6.21-14.9-9.31-25.7-9.31H217.8v70.65
|
||||||
|
h16.83V101.19z"/>
|
||||||
|
<path d="M297.49,110.75c-3.74-1.87-6.63-4.44-8.67-7.72c-2.04-3.27-3.06-6.99-3.06-11.16c0-6.89,2.59-12.26,7.78-16.13
|
||||||
|
c5.18-3.87,11.73-5.8,19.64-5.8c3.91,0,7.54,0.43,10.9,1.28s5.93,1.83,7.72,2.93V70.2c0-4.85-1.7-8.74-5.1-11.67
|
||||||
|
c-3.4-2.93-7.7-4.4-12.88-4.4c-3.66,0-7.01,0.79-10.08,2.36c-3.06,1.57-5.48,3.76-7.27,6.57l-8.16-6.12
|
||||||
|
c2.55-3.91,6.06-6.97,10.52-9.18c4.46-2.21,9.42-3.32,14.86-3.32c8.84,0,15.79,2.32,20.85,6.95c5.06,4.64,7.59,10.95,7.59,18.94
|
||||||
|
v41.19H331.8v-9.31h-0.51c-1.87,3.15-4.68,5.82-8.42,8.03c-3.74,2.21-7.95,3.32-12.63,3.32
|
||||||
|
C305.49,113.56,301.24,112.62,297.49,110.75z M321.47,101.19c3.14-1.87,5.65-4.38,7.52-7.52s2.81-6.59,2.81-10.33
|
||||||
|
c-2.04-1.36-4.55-2.47-7.52-3.32c-2.98-0.85-6.12-1.28-9.44-1.28c-5.95,0-10.44,1.23-13.45,3.7c-3.02,2.47-4.53,5.66-4.53,9.56
|
||||||
|
c0,3.57,1.36,6.46,4.08,8.67c2.72,2.21,6.16,3.32,10.33,3.32C314.92,103.99,318.33,103.06,321.47,101.19z"/>
|
||||||
|
<path d="M353.57,47.5h10.33v10.33h0.51c1.53-3.83,4.12-6.8,7.78-8.93c3.65-2.12,7.65-3.19,11.99-3.19c1.87,0,3.44,0.13,4.72,0.38
|
||||||
|
v11.1c-1.45-0.34-3.4-0.51-5.87-0.51c-5.53,0-10.01,1.83-13.45,5.48c-3.44,3.66-5.17,8.42-5.17,14.28v36.09h-10.84V47.5
|
||||||
|
L353.57,47.5z M420.89,112.26c-2.25-0.86-4.14-2.03-5.68-3.51c-1.7-1.64-2.98-3.55-3.83-5.71c-0.85-2.16-1.28-4.8-1.28-7.92V56.3
|
||||||
|
h-11.35v-9.82h11.35V28.12h10.84v18.36h15.81v9.82h-15.81v36.24c0,3.65,0.68,6.34,2.04,8.08c1.61,1.91,3.95,2.87,7.01,2.87
|
||||||
|
c2.46,0,4.85-0.72,7.14-2.17v10.59c-1.28,0.59-2.57,1.02-3.89,1.28s-3,0.38-5.04,0.38C425.59,113.56,423.15,113.12,420.89,112.26z
|
||||||
|
"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#01579B" d="M29.64,108.94L6.36,85.66c-2.76-2.84-4.48-6.84-4.48-10.75c0-1.81,1.02-4.64,1.79-6.27l21.49-44.77
|
||||||
|
L29.64,108.94z"/>
|
||||||
|
<path fill="#40C4FF" d="M109.34,28.35L86.06,5.07c-2.03-2.04-6.27-4.48-9.85-4.48c-3.08,0-6.1,0.62-8.06,1.79L25.17,23.87
|
||||||
|
L109.34,28.35z"/>
|
||||||
|
<polygon fill="#40C4FF" points="57.4,136.7 113.82,136.7 113.82,112.52 71.73,99.09 33.23,112.52 "/>
|
||||||
|
<path fill="#29B6F6" d="M25.17,96.41c0,7.18,0.9,8.95,4.48,12.54l3.58,3.58h80.59l-39.4-44.77L25.17,23.88V96.41z"/>
|
||||||
|
<path fill="#01579B" d="M96.8,23.87H25.16l88.65,88.65h24.18V57l-28.65-28.65C105.32,24.31,101.74,23.87,96.8,23.87z"/>
|
||||||
|
<path opacity="0.2" fill="#FFFFFF" enable-background="new " d="M30.54,109.84c-3.58-3.6-4.48-7.14-4.48-13.43V24.77l-0.9-0.9
|
||||||
|
V96.4C25.17,102.7,25.17,104.44,30.54,109.84l2.69,2.69l0,0L30.54,109.84z"/>
|
||||||
|
<polygon opacity="0.2" fill="#263238" enable-background="new " points="137.1,56.11 137.1,111.63 112.92,111.63
|
||||||
|
113.82,112.52 138,112.52 138,57.01 "/>
|
||||||
|
<path opacity="0.2" fill="#FFFFFF" enable-background="new " d="M109.34,28.35c-4.44-4.44-8.08-4.48-13.43-4.48H25.17l0.9,0.9
|
||||||
|
h69.85C98.58,24.77,105.33,24.32,109.34,28.35L109.34,28.35z"/>
|
||||||
|
|
||||||
|
<radialGradient id="SVGID_1_" cx="69.955" cy="60.8864" r="68.065" gradientTransform="matrix(1 0 0 -1 0 129.5328)" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.1"/>
|
||||||
|
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||||
|
</radialGradient>
|
||||||
|
<path opacity="0.2" fill="url(#SVGID_1_)" enable-background="new " d="M137.1,56.11l-27.76-27.76L86.06,5.07
|
||||||
|
c-2.03-2.04-6.27-4.48-9.85-4.48c-3.08,0-6.1,0.62-8.06,1.79L25.17,23.87L3.68,68.64c-0.77,1.63-1.79,4.46-1.79,6.27
|
||||||
|
c0,3.91,1.72,7.91,4.48,10.75l21.46,21.3c0.51,0.63,1.11,1.27,1.83,1.98l0.9,0.9l2.69,2.69l23.28,23.28l0.9,0.9h55.52h0.9v-24.18
|
||||||
|
h24.18v-0.06V57.01L137.1,56.11z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After (image error) Size: 4.1 KiB |
34
example/assets/index.html
Normal file
34
example/assets/index.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="container">
|
||||||
|
<img src="images/dart.svg" alt="dart logo">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm">
|
||||||
|
One of three columns
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
One of three columns
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
One of three columns
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
console.log("hello");
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -2,6 +2,11 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
|
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
|
||||||
|
|
||||||
class MyInAppBrowser extends InAppBrowser {
|
class MyInAppBrowser extends InAppBrowser {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onLoadStart(String url) async {
|
Future onLoadStart(String url) async {
|
||||||
print("\n\nStarted $url\n\n");
|
print("\n\nStarted $url\n\n");
|
||||||
@ -13,6 +13,8 @@ class MyInAppBrowser extends InAppBrowser {
|
|||||||
Future onLoadStop(String url) async {
|
Future onLoadStop(String url) async {
|
||||||
print("\n\nStopped $url\n\n");
|
print("\n\nStopped $url\n\n");
|
||||||
|
|
||||||
|
//print("\n\n ${await this.isHidden()} \n\n");
|
||||||
|
|
||||||
// await this.injectScriptCode("window.flutter_inappbrowser.callHandler('handlerTest', 1, 5,'string', {'key': 5}, [4,6,8]);");
|
// await this.injectScriptCode("window.flutter_inappbrowser.callHandler('handlerTest', 1, 5,'string', {'key': 5}, [4,6,8]);");
|
||||||
// await this.injectScriptCode("window.flutter_inappbrowser.callHandler('handlerTest2', false, null, undefined);");
|
// await this.injectScriptCode("window.flutter_inappbrowser.callHandler('handlerTest2', false, null, undefined);");
|
||||||
// await this.injectScriptCode("setTimeout(function(){window.flutter_inappbrowser.callHandler('handlerTest', 'anotherString');}, 1000);");
|
// await this.injectScriptCode("setTimeout(function(){window.flutter_inappbrowser.callHandler('handlerTest', 'anotherString');}, 1000);");
|
||||||
@ -40,8 +42,7 @@ class MyInAppBrowser extends InAppBrowser {
|
|||||||
// var x = {"as":4, "dfdfg": 6};
|
// var x = {"as":4, "dfdfg": 6};
|
||||||
// x;
|
// x;
|
||||||
// """));
|
// """));
|
||||||
//print("\n\n ${await this.isHidden()} \n\n");
|
//
|
||||||
|
|
||||||
// await this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js");
|
// await this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js");
|
||||||
// this.injectScriptCode("""
|
// this.injectScriptCode("""
|
||||||
// \$( "body" ).html( "Next Step..." )
|
// \$( "body" ).html( "Next Step..." )
|
||||||
@ -73,29 +74,33 @@ class MyInAppBrowser extends InAppBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
|
void onLoadResource(
|
||||||
|
WebResourceResponse response, WebResourceRequest request) {
|
||||||
print("Started at: " + response.startTime.toString() + "ms ---> duration: " + response.duration.toString() + "ms " + response.url);
|
print("Started at: " +
|
||||||
|
response.startTime.toString() +
|
||||||
|
"ms ---> duration: " +
|
||||||
|
response.duration.toString() +
|
||||||
|
"ms " +
|
||||||
|
response.url);
|
||||||
// if (response.headers["content-length"] != null)
|
// if (response.headers["content-length"] != null)
|
||||||
// print(response.headers["content-length"] + " length");
|
// print(response.headers["content-length"] + " length");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onConsoleMessage(ConsoleMessage consoleMessage) {
|
void onConsoleMessage(ConsoleMessage consoleMessage) {
|
||||||
// print("""
|
print("""
|
||||||
// console output:
|
console output:
|
||||||
// sourceURL: ${consoleMessage.sourceURL}
|
sourceURL: ${consoleMessage.sourceURL}
|
||||||
// lineNumber: ${consoleMessage.lineNumber}
|
lineNumber: ${consoleMessage.lineNumber}
|
||||||
// message: ${consoleMessage.message}
|
message: ${consoleMessage.message}
|
||||||
// messageLevel: ${consoleMessage.messageLevel}
|
messageLevel: ${consoleMessage.messageLevel}
|
||||||
// """);
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyInAppBrowser inAppBrowserFallback = new MyInAppBrowser();
|
MyInAppBrowser inAppBrowserFallback = new MyInAppBrowser();
|
||||||
|
|
||||||
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||||
|
|
||||||
MyChromeSafariBrowser(browserFallback) : super(browserFallback);
|
MyChromeSafariBrowser(browserFallback) : super(browserFallback);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -115,9 +120,10 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// adding a webview fallback
|
// adding a webview fallback
|
||||||
MyChromeSafariBrowser chromeSafariBrowser = new MyChromeSafariBrowser(inAppBrowserFallback);
|
MyChromeSafariBrowser chromeSafariBrowser =
|
||||||
|
new MyChromeSafariBrowser(inAppBrowserFallback);
|
||||||
|
|
||||||
void main() {
|
Future main() async {
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,11 +133,11 @@ class MyApp extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
// int indexTest = inAppBrowserFallback.addJavaScriptHandler("handlerTest", (arguments) async {
|
// int indexTest = inAppBrowserFallback.addJavaScriptHandler("handlerTest",
|
||||||
|
// (arguments) async {
|
||||||
// print("handlerTest arguments");
|
// print("handlerTest arguments");
|
||||||
// print(arguments);
|
// print(arguments);
|
||||||
// });
|
// });
|
||||||
@ -150,10 +156,14 @@ class _MyAppState extends State<MyApp> {
|
|||||||
title: const Text('Flutter InAppBrowser Plugin example app'),
|
title: const Text('Flutter InAppBrowser Plugin example app'),
|
||||||
),
|
),
|
||||||
body: new Center(
|
body: new Center(
|
||||||
child: new RaisedButton(onPressed: () {
|
child: new RaisedButton(
|
||||||
//chromeSafariBrowser.open("https://flutter.io/");
|
onPressed: () async {
|
||||||
inAppBrowserFallback.open(url: "https://flutter.io/", options: {
|
// await chromeSafariBrowser.open("https://flutter.io/");
|
||||||
//"useOnLoadResource": true,
|
|
||||||
|
// await InAppBrowser.openWithSystemBrowser("https://flutter.io/");
|
||||||
|
|
||||||
|
await inAppBrowserFallback.openOnLocalhost("assets/index.html", options: {
|
||||||
|
"useOnLoadResource": true,
|
||||||
//"hidden": true,
|
//"hidden": true,
|
||||||
//"toolbarTopFixedTitle": "Fixed title",
|
//"toolbarTopFixedTitle": "Fixed title",
|
||||||
//"useShouldOverrideUrlLoading": true
|
//"useShouldOverrideUrlLoading": true
|
||||||
@ -162,9 +172,29 @@ class _MyAppState extends State<MyApp> {
|
|||||||
//"toolbarBottom": false
|
//"toolbarBottom": false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// await inAppBrowserFallback.open(url: "assets/index.html", options: {
|
||||||
|
// "isLocalFile": true,
|
||||||
|
// "useOnLoadResource": true,
|
||||||
|
// //"hidden": true,
|
||||||
|
// //"toolbarTopFixedTitle": "Fixed title",
|
||||||
|
// //"useShouldOverrideUrlLoading": true
|
||||||
|
// //"hideUrlBar": true,
|
||||||
|
// //"toolbarTop": false,
|
||||||
|
// //"toolbarBottom": false
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await inAppBrowserFallback.open(url: "https://flutter.io/", options: {
|
||||||
|
// //"useOnLoadResource": true,
|
||||||
|
// //"hidden": true,
|
||||||
|
// //"toolbarTopFixedTitle": "Fixed title",
|
||||||
|
// //"useShouldOverrideUrlLoading": true
|
||||||
|
// //"hideUrlBar": true,
|
||||||
|
// //"toolbarTop": false,
|
||||||
|
// //"toolbarBottom": false
|
||||||
|
// });
|
||||||
|
//await inAppBrowserFallback.openOnLocalhost("assets/index.html");
|
||||||
},
|
},
|
||||||
child: Text("Open InAppBrowser")
|
child: Text("Open InAppBrowser")),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,11 @@ flutter:
|
|||||||
# the material Icons class.
|
# the material Icons class.
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
|
assets:
|
||||||
|
- assets/index.html
|
||||||
|
- assets/css/
|
||||||
|
- assets/images/
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
# assets:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
|
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
@ -12,6 +12,7 @@ public class InAppBrowserOptions: Options {
|
|||||||
|
|
||||||
var useShouldOverrideUrlLoading = false
|
var useShouldOverrideUrlLoading = false
|
||||||
var useOnLoadResource = false
|
var useOnLoadResource = false
|
||||||
|
var openWithSystemBrowser = false;
|
||||||
var clearCache = false
|
var clearCache = false
|
||||||
var userAgent = ""
|
var userAgent = ""
|
||||||
var javaScriptEnabled = true
|
var javaScriptEnabled = true
|
||||||
@ -21,6 +22,7 @@ public class InAppBrowserOptions: Options {
|
|||||||
var toolbarTopBackgroundColor = ""
|
var toolbarTopBackgroundColor = ""
|
||||||
var hideUrlBar = false
|
var hideUrlBar = false
|
||||||
var mediaPlaybackRequiresUserGesture = true
|
var mediaPlaybackRequiresUserGesture = true
|
||||||
|
var isLocalFile = false
|
||||||
|
|
||||||
var disallowOverScroll = false
|
var disallowOverScroll = false
|
||||||
var toolbarBottom = true
|
var toolbarBottom = true
|
||||||
|
@ -81,7 +81,6 @@ func convertToDictionary(text: String) -> [String: Any]? {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//extension WKWebView{
|
//extension WKWebView{
|
||||||
//
|
//
|
||||||
// var keyboardDisplayRequiresUserAction: Bool? {
|
// var keyboardDisplayRequiresUserAction: Bool? {
|
||||||
@ -139,6 +138,7 @@ class WKWebView_IBWrapper: WKWebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
|
class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
|
||||||
|
|
||||||
@IBOutlet var webView: WKWebView_IBWrapper!
|
@IBOutlet var webView: WKWebView_IBWrapper!
|
||||||
@IBOutlet var closeButton: UIButton!
|
@IBOutlet var closeButton: UIButton!
|
||||||
@IBOutlet var reloadButton: UIBarButtonItem!
|
@IBOutlet var reloadButton: UIBarButtonItem!
|
||||||
@ -421,11 +421,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc func close() {
|
@objc func close() {
|
||||||
currentURL = nil
|
//currentURL = nil
|
||||||
|
|
||||||
if (navigationDelegate != nil) {
|
|
||||||
navigationDelegate?.browserExit(uuid: self.uuid)
|
|
||||||
}
|
|
||||||
|
|
||||||
weak var weakSelf = self
|
weak var weakSelf = self
|
||||||
|
|
||||||
@ -435,12 +431,18 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
weakSelf?.presentingViewController?.dismiss(animated: true, completion: {() -> Void in
|
weakSelf?.presentingViewController?.dismiss(animated: true, completion: {() -> Void in
|
||||||
self.tmpWindow?.windowLevel = 0.0
|
self.tmpWindow?.windowLevel = 0.0
|
||||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||||
|
if (self.navigationDelegate != nil) {
|
||||||
|
self.navigationDelegate?.browserExit(uuid: self.uuid)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
weakSelf?.parent?.dismiss(animated: true, completion: {() -> Void in
|
weakSelf?.parent?.dismiss(animated: true, completion: {() -> Void in
|
||||||
self.tmpWindow?.windowLevel = 0.0
|
self.tmpWindow?.windowLevel = 0.0
|
||||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||||
|
if (self.navigationDelegate != nil) {
|
||||||
|
self.navigationDelegate?.browserExit(uuid: self.uuid)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -527,7 +529,9 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
if navigationAction.navigationType == .linkActivated && (browserOptions?.useShouldOverrideUrlLoading)! {
|
if navigationAction.navigationType == .linkActivated && (browserOptions?.useShouldOverrideUrlLoading)! {
|
||||||
|
if navigationDelegate != nil {
|
||||||
navigationDelegate?.shouldOverrideUrlLoading(uuid: self.uuid, webView: webView, url: url)
|
navigationDelegate?.shouldOverrideUrlLoading(uuid: self.uuid, webView: webView, url: url)
|
||||||
|
}
|
||||||
decisionHandler(.cancel)
|
decisionHandler(.cancel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -606,7 +610,9 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
spinner.startAnimating()
|
spinner.startAnimating()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (navigationDelegate?.onLoadStart(uuid: self.uuid, webView: webView))!
|
if navigationDelegate != nil {
|
||||||
|
navigationDelegate?.onLoadStart(uuid: self.uuid, webView: webView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
@ -617,8 +623,11 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
backButton.isEnabled = webView.canGoBack
|
backButton.isEnabled = webView.canGoBack
|
||||||
forwardButton.isEnabled = webView.canGoForward
|
forwardButton.isEnabled = webView.canGoForward
|
||||||
spinner.stopAnimating()
|
spinner.stopAnimating()
|
||||||
|
|
||||||
|
if navigationDelegate != nil {
|
||||||
navigationDelegate?.onLoadStop(uuid: self.uuid, webView: webView)
|
navigationDelegate?.onLoadStop(uuid: self.uuid, webView: webView)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func webView(_ view: WKWebView,
|
func webView(_ view: WKWebView,
|
||||||
didFailProvisionalNavigation navigation: WKNavigation!,
|
didFailProvisionalNavigation navigation: WKNavigation!,
|
||||||
@ -627,16 +636,20 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
||||||
print("webView:didFailNavigationWithError - \(Int(error._code)): \(error.localizedDescription)")
|
|
||||||
backButton.isEnabled = webView.canGoBack
|
backButton.isEnabled = webView.canGoBack
|
||||||
forwardButton.isEnabled = webView.canGoForward
|
forwardButton.isEnabled = webView.canGoForward
|
||||||
spinner.stopAnimating()
|
spinner.stopAnimating()
|
||||||
|
|
||||||
|
if navigationDelegate != nil {
|
||||||
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
|
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func didReceiveResourceResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int, duration: Int) {
|
func didReceiveResourceResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int, duration: Int) {
|
||||||
|
if navigationDelegate != nil {
|
||||||
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, startTime: startTime, duration: duration)
|
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, startTime: startTime, duration: duration)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||||
if message.name.starts(with: "console") {
|
if message.name.starts(with: "console") {
|
||||||
@ -663,8 +676,10 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
messageLevel = "LOG"
|
messageLevel = "LOG"
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if navigationDelegate != nil {
|
||||||
navigationDelegate?.onConsoleMessage(uuid: self.uuid, sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
|
navigationDelegate?.onConsoleMessage(uuid: self.uuid, sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if message.name == "resourceLoaded" {
|
else if message.name == "resourceLoaded" {
|
||||||
if let resource = convertToDictionary(text: message.body as! String) {
|
if let resource = convertToDictionary(text: message.body as! String) {
|
||||||
let url = URL(string: resource["name"] as! String)!
|
let url = URL(string: resource["name"] as! String)!
|
||||||
@ -695,7 +710,9 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
let body = message.body as! [String: Any]
|
let body = message.body as! [String: Any]
|
||||||
let handlerName = body["handlerName"] as! String
|
let handlerName = body["handlerName"] as! String
|
||||||
let args = body["args"] as! String
|
let args = body["args"] as! String
|
||||||
|
if navigationDelegate != nil {
|
||||||
self.navigationDelegate?.onCallJsHandler(uuid: self.uuid, webView: webView, handlerName: handlerName, args: args)
|
self.navigationDelegate?.onCallJsHandler(uuid: self.uuid, webView: webView, handlerName: handlerName, args: args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -14,12 +14,13 @@ public class Options: NSObject {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parse(options: [String: Any]) {
|
public func parse(options: [String: Any]) -> Options {
|
||||||
for (key, value) in options {
|
for (key, value) in options {
|
||||||
if self.responds(to: Selector(key)) {
|
if self.responds(to: Selector(key)) {
|
||||||
self.setValue(value, forKey: key)
|
self.setValue(value, forKey: key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,15 +40,15 @@ class SafariViewController: SFSafariViewController, SFSafariViewControllerDelega
|
|||||||
}
|
}
|
||||||
|
|
||||||
func close() {
|
func close() {
|
||||||
if (statusDelegate != nil) {
|
|
||||||
statusDelegate?.safariExit(uuid: self.uuid)
|
|
||||||
}
|
|
||||||
|
|
||||||
dismiss(animated: true)
|
dismiss(animated: true)
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
|
||||||
self.tmpWindow?.windowLevel = 0.0
|
self.tmpWindow?.windowLevel = 0.0
|
||||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||||
|
|
||||||
|
if (self.statusDelegate != nil) {
|
||||||
|
self.statusDelegate?.safariExit(uuid: self.uuid)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,19 +22,6 @@ import Foundation
|
|||||||
import AVFoundation
|
import AVFoundation
|
||||||
import SafariServices
|
import SafariServices
|
||||||
|
|
||||||
//class CustomURLCache: URLCache {
|
|
||||||
// override func cachedResponse(for request: URLRequest) -> CachedURLResponse? {
|
|
||||||
// dump(request.url)
|
|
||||||
// return super.cachedResponse(for: request)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override func getCachedResponse(for dataTask: URLSessionDataTask,
|
|
||||||
// completionHandler: @escaping (CachedURLResponse?) -> Void) {
|
|
||||||
// dump(dataTask.response)
|
|
||||||
// super.getCachedResponse(for: dataTask, completionHandler: completionHandler)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
let WEBVIEW_STORYBOARD = "WebView"
|
let WEBVIEW_STORYBOARD = "WebView"
|
||||||
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
|
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
|
||||||
|
|
||||||
@ -47,6 +34,9 @@ extension Dictionary where Key: ExpressibleByStringLiteral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
|
static var registrar: FlutterPluginRegistrar?
|
||||||
|
|
||||||
var webViewControllers: [String: InAppBrowserWebViewController?] = [:]
|
var webViewControllers: [String: InAppBrowserWebViewController?] = [:]
|
||||||
var safariViewControllers: [String: Any?] = [:]
|
var safariViewControllers: [String: Any?] = [:]
|
||||||
|
|
||||||
@ -59,11 +49,8 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
// URLProtocol.wk_registerScheme("http")
|
|
||||||
// URLProtocol.wk_registerScheme("https")
|
|
||||||
// URLProtocol.registerClass(MyURLProtocol.self)
|
|
||||||
|
|
||||||
//URLCache.shared = CustomURLCache()
|
SwiftFlutterPlugin.registrar = registrar
|
||||||
|
|
||||||
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
|
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
|
||||||
let instance = SwiftFlutterPlugin(with: registrar)
|
let instance = SwiftFlutterPlugin(with: registrar)
|
||||||
@ -177,7 +164,6 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print("IAB.close() called but it was already closed.")
|
print("IAB.close() called but it was already closed.")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,41 +178,38 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
let url: String = (arguments["url"] as? String)!
|
let url: String = (arguments["url"] as? String)!
|
||||||
|
|
||||||
let headers = (arguments["headers"] as? [String: String])!
|
let headers = (arguments["headers"] as? [String: String])!
|
||||||
var target: String? = (arguments["target"] as? String)!
|
|
||||||
target = target != nil ? target : "_self"
|
|
||||||
let absoluteUrl = URL(string: url)?.absoluteURL
|
let absoluteUrl = URL(string: url)?.absoluteURL
|
||||||
|
|
||||||
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)
|
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)
|
||||||
|
|
||||||
if useChromeSafariBrowser! {
|
if useChromeSafariBrowser! {
|
||||||
let uuidFallback = (arguments["uuidFallback"] as? String)!
|
let uuidFallback = (arguments["uuidFallback"] as? String)!
|
||||||
let options = (arguments["options"] as? [String: Any])!
|
let safariOptions = SafariBrowserOptions()
|
||||||
let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
|
safariOptions.parse(options: (arguments["options"] as? [String: Any])!)
|
||||||
|
|
||||||
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback);
|
let optionsFallback = InAppBrowserOptions()
|
||||||
|
optionsFallback.parse(options: (arguments["optionsFallback"] as? [String: Any])!)
|
||||||
|
|
||||||
|
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let options = (arguments["options"] as? [String: Any])!
|
let options = InAppBrowserOptions()
|
||||||
|
options.parse(options: (arguments["options"] as? [String: Any])!)
|
||||||
|
|
||||||
if isSystemUrl(absoluteUrl!) {
|
if isSystemUrl(absoluteUrl!) {
|
||||||
target = "_system"
|
options.openWithSystemBrowser = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target == "_self" || target == "_target") {
|
if (options.openWithSystemBrowser) {
|
||||||
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil)
|
open(inSystem: absoluteUrl!, result: result)
|
||||||
}
|
|
||||||
else if (target == "_system") {
|
|
||||||
open(inSystem: absoluteUrl!)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// anything else
|
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil, result: result)
|
||||||
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers,withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func open(uuid: String, uuidFallback: String?, inAppBrowser url: URL, headers: [String: String], withOptions options: [String: Any], useChromeSafariBrowser: Bool, withOptionsFallback optionsFallback: [String: Any]?) {
|
func open(uuid: String, uuidFallback: String?, inAppBrowser url: URL, headers: [String: String], withOptions options: Options, useChromeSafariBrowser: Bool, withOptionsFallback optionsFallback: Options?, result: @escaping FlutterResult) {
|
||||||
|
|
||||||
var uuid = uuid
|
var uuid = uuid
|
||||||
|
|
||||||
@ -235,7 +218,6 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let safariViewController = self.safariViewControllers[uuid]
|
let safariViewController = self.safariViewControllers[uuid]
|
||||||
|
|
||||||
if safariViewController != nil {
|
if safariViewController != nil {
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
(safariViewController! as! SafariViewController).close()
|
(safariViewController! as! SafariViewController).close()
|
||||||
@ -264,8 +246,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
if useChromeSafariBrowser == true {
|
if useChromeSafariBrowser == true {
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
let safariOptions = SafariBrowserOptions()
|
let safariOptions = options as! SafariBrowserOptions
|
||||||
safariOptions.parse(options: options)
|
|
||||||
|
|
||||||
let safari: SafariViewController
|
let safari: SafariViewController
|
||||||
|
|
||||||
@ -290,22 +271,35 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
tmpController.present(self.safariViewControllers[uuid]! as! SFSafariViewController, animated: true)
|
tmpController.present(self.safariViewControllers[uuid]! as! SFSafariViewController, animated: true)
|
||||||
onChromeSafariBrowserOpened(uuid: uuid)
|
onChromeSafariBrowserOpened(uuid: uuid)
|
||||||
|
result(true)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if uuidFallback == nil {
|
if uuidFallback == nil {
|
||||||
print("No WebView fallback declared.")
|
print("No WebView fallback declared.")
|
||||||
|
result(true)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uuid = uuidFallback!
|
uuid = uuidFallback!
|
||||||
browserOptions = InAppBrowserOptions()
|
browserOptions = optionsFallback as! InAppBrowserOptions
|
||||||
browserOptions.parse(options: optionsFallback!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
browserOptions = InAppBrowserOptions()
|
browserOptions = options as! InAppBrowserOptions
|
||||||
browserOptions.parse(options: options)
|
}
|
||||||
|
|
||||||
|
var currentURL = url
|
||||||
|
|
||||||
|
if browserOptions.isLocalFile {
|
||||||
|
let key = SwiftFlutterPlugin.registrar!.lookupKey(forAsset: url.absoluteString)
|
||||||
|
let assetURL = Bundle.main.url(forResource: key, withExtension: nil)
|
||||||
|
if assetURL == nil {
|
||||||
|
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url.absoluteString + " asset file cannot be found!", details: nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentURL = assetURL!
|
||||||
}
|
}
|
||||||
|
|
||||||
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppBrowserFlutterPlugin.self))
|
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppBrowserFlutterPlugin.self))
|
||||||
@ -316,7 +310,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
webViewController.browserOptions = browserOptions
|
webViewController.browserOptions = browserOptions
|
||||||
webViewController.isHidden = browserOptions.hidden
|
webViewController.isHidden = browserOptions.hidden
|
||||||
webViewController.tmpWindow = tmpWindow
|
webViewController.tmpWindow = tmpWindow
|
||||||
webViewController.currentURL = url
|
webViewController.currentURL = currentURL
|
||||||
webViewController.initHeaders = headers
|
webViewController.initHeaders = headers
|
||||||
webViewController.navigationDelegate = self
|
webViewController.navigationDelegate = self
|
||||||
|
|
||||||
@ -338,6 +332,8 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
else {
|
else {
|
||||||
tmpController.present(webViewController, animated: true, completion: nil)
|
tmpController.present(webViewController, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||||
@ -350,7 +346,6 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
webViewController.loadUrl(url: absoluteUrl, headers: headers)
|
webViewController.loadUrl(url: absoluteUrl, headers: headers)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print("url is empty")
|
|
||||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
@ -403,18 +398,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func open(inSystem url: URL) {
|
func open(inSystem url: URL, result: @escaping FlutterResult) {
|
||||||
if !UIApplication.shared.canOpenURL(url) {
|
if !UIApplication.shared.canOpenURL(url) {
|
||||||
NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "PluginHandleOpenURLNotification"), object: url))
|
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url.absoluteString + " cannot be opened!", details: nil))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if #available(iOS 10.0, *) {
|
if #available(iOS 10.0, *) {
|
||||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||||
} else {
|
} else {
|
||||||
UIApplication.shared.openURL(url)
|
UIApplication.shared.openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result(true)
|
||||||
|
}
|
||||||
|
|
||||||
// This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
// This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
||||||
// provides a consistent method for injecting JavaScript code into the document.
|
// provides a consistent method for injecting JavaScript code into the document.
|
||||||
@ -429,7 +425,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: [])
|
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: [])
|
||||||
let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8)
|
let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8)
|
||||||
if sourceArrayString != nil {
|
if sourceArrayString != nil {
|
||||||
let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.characters.count ?? 0) - 2))
|
let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.count ?? 0) - 2))
|
||||||
let jsToInject = String(format: jsWrapper, sourceString!)
|
let jsToInject = String(format: jsWrapper, sourceString!)
|
||||||
|
|
||||||
webViewController?.webView?.evaluateJavaScript(jsToInject, completionHandler: {(value, error) in
|
webViewController?.webView?.evaluateJavaScript(jsToInject, completionHandler: {(value, error) in
|
||||||
@ -439,7 +435,6 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
if error != nil {
|
if error != nil {
|
||||||
let userInfo = (error! as NSError).userInfo
|
let userInfo = (error! as NSError).userInfo
|
||||||
dump(userInfo)
|
|
||||||
self.onConsoleMessage(uuid: uuid, sourceURL: (userInfo["WKJavaScriptExceptionSourceURL"] as? URL)?.absoluteString ?? "", lineNumber: userInfo["WKJavaScriptExceptionLineNumber"] as! Int, message: userInfo["WKJavaScriptExceptionMessage"] as! String, messageLevel: "ERROR")
|
self.onConsoleMessage(uuid: uuid, sourceURL: (userInfo["WKJavaScriptExceptionSourceURL"] as? URL)?.absoluteString ?? "", lineNumber: userInfo["WKJavaScriptExceptionLineNumber"] as! Int, message: userInfo["WKJavaScriptExceptionMessage"] as! String, messageLevel: "ERROR")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +453,6 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
result!(value)
|
result!(value)
|
||||||
}
|
}
|
||||||
} catch let error as NSError {
|
} catch let error as NSError {
|
||||||
print("Failed to load: \(error.localizedDescription)")
|
|
||||||
result!(FlutterError(code: "InAppBrowserFlutterPlugin", message: "Failed to load: \(error.localizedDescription)", details: error))
|
result!(FlutterError(code: "InAppBrowserFlutterPlugin", message: "Failed to load: \(error.localizedDescription)", details: error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
@ -26,6 +27,7 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
import 'package:mime/mime.dart';
|
||||||
|
|
||||||
typedef Future<dynamic> ListenerCallback(MethodCall call);
|
typedef Future<dynamic> ListenerCallback(MethodCall call);
|
||||||
typedef Future<void> JavaScriptHandlerCallback(List<dynamic> arguments);
|
typedef Future<void> JavaScriptHandlerCallback(List<dynamic> arguments);
|
||||||
@ -85,8 +87,7 @@ class _ChannelManager {
|
|||||||
|
|
||||||
static Future<dynamic> _handleMethod(MethodCall call) async {
|
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
String uuid = call.arguments["uuid"];
|
String uuid = call.arguments["uuid"];
|
||||||
listeners[uuid](call);
|
return await listeners[uuid](call);
|
||||||
return new Future.value("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addListener (String key, ListenerCallback callback) {
|
static void addListener (String key, ListenerCallback callback) {
|
||||||
@ -107,11 +108,14 @@ class InAppBrowser {
|
|||||||
|
|
||||||
String uuid;
|
String uuid;
|
||||||
Map<String, List<JavaScriptHandlerCallback>> javaScriptHandlersMap = HashMap<String, List<JavaScriptHandlerCallback>>();
|
Map<String, List<JavaScriptHandlerCallback>> javaScriptHandlersMap = HashMap<String, List<JavaScriptHandlerCallback>>();
|
||||||
|
HttpServer _server;
|
||||||
|
bool _isOpened = false;
|
||||||
|
|
||||||
///
|
///
|
||||||
InAppBrowser () {
|
InAppBrowser () {
|
||||||
uuid = _uuidGenerator.v4();
|
uuid = _uuidGenerator.v4();
|
||||||
_ChannelManager.addListener(uuid, _handleMethod);
|
_ChannelManager.addListener(uuid, _handleMethod);
|
||||||
|
_isOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
@ -131,6 +135,8 @@ class InAppBrowser {
|
|||||||
onLoadError(url, code, message);
|
onLoadError(url, code, message);
|
||||||
break;
|
break;
|
||||||
case "onExit":
|
case "onExit":
|
||||||
|
this._closeServer();
|
||||||
|
this._isOpened = false;
|
||||||
onExit();
|
onExit();
|
||||||
break;
|
break;
|
||||||
case "shouldOverrideUrlLoading":
|
case "shouldOverrideUrlLoading":
|
||||||
@ -183,27 +189,26 @@ class InAppBrowser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||||
}
|
}
|
||||||
return new Future.value("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Opens an [url] in a new [InAppBrowser] instance or the system browser.
|
///Opens an [url] in a new [InAppBrowser] instance or in the system browser (`openWithSystemBrowser: true`).
|
||||||
|
///
|
||||||
|
///**NOTE**: If you open the given [url] with the system browser (`openWithSystemBrowser: true`), you wont be able to use the [InAppBrowser] methods!
|
||||||
///
|
///
|
||||||
///- [url]: The [url] to load. Call [encodeUriComponent()] on this if the [url] contains Unicode characters. The default value is `about:blank`.
|
///- [url]: The [url] to load. Call [encodeUriComponent()] on this if the [url] contains Unicode characters. The default value is `about:blank`.
|
||||||
///
|
///
|
||||||
///- [headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
///- [headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
|
||||||
///
|
///
|
||||||
///- [target]: The target in which to load the [url], an optional parameter that defaults to `_self`.
|
|
||||||
///
|
|
||||||
/// - `_self`: Opens in the [InAppBrowser].
|
|
||||||
/// - `_blank`: Opens in the [InAppBrowser].
|
|
||||||
/// - `_system`: Opens in the system's web browser.
|
|
||||||
///
|
|
||||||
///- [options]: Options for the [InAppBrowser].
|
///- [options]: Options for the [InAppBrowser].
|
||||||
///
|
///
|
||||||
/// All platforms support:
|
/// - All platforms support:
|
||||||
/// - __useShouldOverrideUrlLoading__: Set to `true` to be able to listen at the [shouldOverrideUrlLoading()] event. The default value is `false`.
|
/// - __useShouldOverrideUrlLoading__: Set to `true` to be able to listen at the [shouldOverrideUrlLoading()] event. The default value is `false`.
|
||||||
/// - __useOnLoadResource__: Set to `true` to be able to listen at the [onLoadResource()] event. The default value is `false`.
|
/// - __useOnLoadResource__: Set to `true` to be able to listen at the [onLoadResource()] event. The default value is `false`.
|
||||||
|
/// - __openWithSystemBrowser__: Set to `true` to open the given `url` with the system browser. The default value is `false`.
|
||||||
|
/// - __isLocalFile__: Set to `true` if the [url] is pointing to a local file (the file must be addded in the `assets` section of your `pubspec.yaml`. See [loadFile()] explanation). The default value is `false`.
|
||||||
/// - __clearCache__: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
/// - __clearCache__: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
|
||||||
/// - __userAgent___: Set the custom WebView's user-agent.
|
/// - __userAgent___: Set the custom WebView's user-agent.
|
||||||
/// - __javaScriptEnabled__: Set to `true` to enable JavaScript. The default value is `true`.
|
/// - __javaScriptEnabled__: Set to `true` to enable JavaScript. The default value is `true`.
|
||||||
@ -214,7 +219,7 @@ class InAppBrowser {
|
|||||||
/// - __hideUrlBar__: Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`.
|
/// - __hideUrlBar__: Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`.
|
||||||
/// - __mediaPlaybackRequiresUserGesture__: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`.
|
/// - __mediaPlaybackRequiresUserGesture__: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`.
|
||||||
///
|
///
|
||||||
/// **Android** supports these additional options:
|
/// - **Android** supports these additional options:
|
||||||
///
|
///
|
||||||
/// - __hideTitleBar__: Set to `true` if you want the title should be displayed. The default value is `false`.
|
/// - __hideTitleBar__: Set to `true` if you want the title should be displayed. The default value is `false`.
|
||||||
/// - __closeOnCannotGoBack__: Set to `false` to not close the InAppBrowser when the user click on the back button and the WebView cannot go back to the history. The default value is `true`.
|
/// - __closeOnCannotGoBack__: Set to `false` to not close the InAppBrowser when the user click on the back button and the WebView cannot go back to the history. The default value is `true`.
|
||||||
@ -227,7 +232,7 @@ class InAppBrowser {
|
|||||||
/// - __safeBrowsingEnabled__: Set to `true` if you want the Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. The default value is `true`.
|
/// - __safeBrowsingEnabled__: Set to `true` if you want the Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. The default value is `true`.
|
||||||
/// - __progressBar__: Set to `false` to hide the progress bar at the bottom of the toolbar at the top. The default value is `true`.
|
/// - __progressBar__: Set to `false` to hide the progress bar at the bottom of the toolbar at the top. The default value is `true`.
|
||||||
///
|
///
|
||||||
/// **iOS** supports these additional options:
|
/// - **iOS** supports these additional options:
|
||||||
///
|
///
|
||||||
/// - __disallowOverScroll__: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`.
|
/// - __disallowOverScroll__: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`.
|
||||||
/// - __toolbarBottom__: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`.
|
/// - __toolbarBottom__: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`.
|
||||||
@ -246,70 +251,209 @@ class InAppBrowser {
|
|||||||
/// - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`.
|
/// - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`.
|
||||||
/// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`.
|
/// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`.
|
||||||
/// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
|
/// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
|
||||||
Future<void> open({String url = "about:blank", Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}}) async {
|
Future<void> open({String url = "about:blank", Map<String, String> headers = const {}, Map<String, dynamic> options = const {}}) async {
|
||||||
|
this._throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
args.putIfAbsent('headers', () => headers);
|
args.putIfAbsent('headers', () => headers);
|
||||||
args.putIfAbsent('target', () => target);
|
|
||||||
args.putIfAbsent('options', () => options);
|
args.putIfAbsent('options', () => options);
|
||||||
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||||
|
await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
|
this._isOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///This is a static method that opens an [url] in the system browser.
|
||||||
|
///This has the same behaviour of an [InAppBrowser] instance calling the [open()] method with option `openWithSystemBrowser: true`.
|
||||||
|
static Future<void> openWithSystemBrowser(String url) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent('uuid', () => "");
|
||||||
|
args.putIfAbsent('url', () => url);
|
||||||
|
args.putIfAbsent('headers', () => {});
|
||||||
|
args.putIfAbsent('options', () => {"openWithSystemBrowser": true});
|
||||||
|
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||||
return await _ChannelManager.channel.invokeMethod('open', args);
|
return await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _startServer({int port = 8080}) async {
|
||||||
|
|
||||||
|
this._closeServer();
|
||||||
|
var completer = new Completer();
|
||||||
|
|
||||||
|
runZoned(() {
|
||||||
|
HttpServer.bind('127.0.0.1', port).then((server) {
|
||||||
|
print('Server running at http://127.0.0.1:' + port.toString());
|
||||||
|
|
||||||
|
this._server = server;
|
||||||
|
|
||||||
|
server.listen((HttpRequest request) async {
|
||||||
|
var body = List<int>();
|
||||||
|
var path = request.requestedUri.path;
|
||||||
|
path = (path.startsWith('/')) ? path.substring(1) : path;
|
||||||
|
path += (path.endsWith('/')) ? 'index.html' : '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
body = (await rootBundle.load(path))
|
||||||
|
.buffer.asUint8List();
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
request.response.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentType = ['text', 'html'];
|
||||||
|
if (!request.requestedUri.path.endsWith('/') && request.requestedUri.pathSegments.isNotEmpty) {
|
||||||
|
var mimeType = lookupMimeType(request.requestedUri.path, headerBytes: body);
|
||||||
|
if (mimeType != null) {
|
||||||
|
contentType = mimeType.split('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.response.headers.contentType = new ContentType(contentType[0], contentType[1], charset: 'utf-8');
|
||||||
|
request.response.add(body);
|
||||||
|
request.response.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
completer.complete();
|
||||||
|
});
|
||||||
|
}, onError: (e, stackTrace) => print('Error: $e $stackTrace'));
|
||||||
|
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _closeServer() async {
|
||||||
|
if (this._server != null) {
|
||||||
|
final port = this._server.port;
|
||||||
|
await this._server.close(force: true);
|
||||||
|
print('Server running at http://127.0.0.1:$port closed');
|
||||||
|
this._server = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Serve the [assetFilePath] from Flutter assets on http://localhost:[port]/. It is similar to [InAppBrowser.open()] with option `isLocalFile: true`, but it starts a server.
|
||||||
|
///
|
||||||
|
///**NOTE for iOS**: For the iOS Platform, you need to add the `NSAllowsLocalNetworking` key with `true` in the `Info.plist` file (See [ATS Configuration Basics](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35):
|
||||||
|
///```xml
|
||||||
|
///<key>NSAppTransportSecurity</key>
|
||||||
|
///<dict>
|
||||||
|
/// <key>NSAllowsLocalNetworking</key>
|
||||||
|
/// <true/>
|
||||||
|
///</dict>
|
||||||
|
///```
|
||||||
|
///The `NSAllowsLocalNetworking` key is available since **iOS 10**.
|
||||||
|
Future<void> openOnLocalhost(String assetFilePath, {int port = 8080, Map<String, String> headers = const {}, Map<String, dynamic> options = const {}}) async {
|
||||||
|
this._throwIsAlreadyOpened(message: 'Cannot open $assetFilePath!');
|
||||||
|
await this._startServer(port: port);
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
|
args.putIfAbsent('url', () => 'http://localhost:${this._server.port}/' + assetFilePath);
|
||||||
|
args.putIfAbsent('headers', () => headers);
|
||||||
|
options["isLocalFile"] = false;
|
||||||
|
args.putIfAbsent('options', () => options);
|
||||||
|
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||||
|
await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
|
this._isOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
///Loads the given [url] with optional [headers] specified as a map from name to value.
|
///Loads the given [url] with optional [headers] specified as a map from name to value.
|
||||||
Future<void> loadUrl(String url, {Map<String, String> headers = const {}}) async {
|
Future<void> loadUrl(String url, {Map<String, String> headers = const {}}) async {
|
||||||
|
this._throwIsNotOpened(message: 'Cannot laod $url!');
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
args.putIfAbsent('headers', () => headers);
|
args.putIfAbsent('headers', () => headers);
|
||||||
return await _ChannelManager.channel.invokeMethod('loadUrl', args);
|
await _ChannelManager.channel.invokeMethod('loadUrl', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Loads the given [assetFilePath] with optional [headers] specified as a map from name to value.
|
||||||
|
///
|
||||||
|
///To be able to load your local files (assets, js, css, etc.), you need to add them in the `assets` section of the `pubspec.yaml` file, otherwise they cannot be found!
|
||||||
|
///
|
||||||
|
///Example of a `pubspec.yaml` file:
|
||||||
|
///```yaml
|
||||||
|
///...
|
||||||
|
///
|
||||||
|
///# The following section is specific to Flutter.
|
||||||
|
///flutter:
|
||||||
|
///
|
||||||
|
/// # The following line ensures that the Material Icons font is
|
||||||
|
/// # included with your application, so that you can use the icons in
|
||||||
|
/// # the material Icons class.
|
||||||
|
/// uses-material-design: true
|
||||||
|
///
|
||||||
|
/// assets:
|
||||||
|
/// - assets/index.html
|
||||||
|
/// - assets/css/
|
||||||
|
/// - assets/images/
|
||||||
|
///
|
||||||
|
///...
|
||||||
|
///```
|
||||||
|
///Example of a `main.dart` file:
|
||||||
|
///```dart
|
||||||
|
///...
|
||||||
|
///inAppBrowser.loadFile("assets/index.html");
|
||||||
|
///...
|
||||||
|
///```
|
||||||
|
Future<void> loadFile(String assetFilePath, {Map<String, String> headers = const {}}) async {
|
||||||
|
this._throwIsNotOpened(message: 'Cannot laod $assetFilePath!');
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
|
args.putIfAbsent('url', () => assetFilePath);
|
||||||
|
args.putIfAbsent('headers', () => headers);
|
||||||
|
await _ChannelManager.channel.invokeMethod('loadFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible.
|
///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible.
|
||||||
Future<void> show() async {
|
Future<void> show() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('show', args);
|
await _ChannelManager.channel.invokeMethod('show', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Hides the [InAppBrowser] window. Calling this has no effect if the [InAppBrowser] was already hidden.
|
///Hides the [InAppBrowser] window. Calling this has no effect if the [InAppBrowser] was already hidden.
|
||||||
Future<void> hide() async {
|
Future<void> hide() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('hide', args);
|
await _ChannelManager.channel.invokeMethod('hide', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Closes the [InAppBrowser] window.
|
///Closes the [InAppBrowser] window.
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('close', args);
|
await _ChannelManager.channel.invokeMethod('close', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Reloads the [InAppBrowser] window.
|
///Reloads the [InAppBrowser] window.
|
||||||
Future<void> reload() async {
|
Future<void> reload() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('reload', args);
|
await _ChannelManager.channel.invokeMethod('reload', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Goes back in the history of the [InAppBrowser] window.
|
///Goes back in the history of the [InAppBrowser] window.
|
||||||
Future<void> goBack() async {
|
Future<void> goBack() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('goBack', args);
|
await _ChannelManager.channel.invokeMethod('goBack', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Goes forward in the history of the [InAppBrowser] window.
|
///Goes forward in the history of the [InAppBrowser] window.
|
||||||
Future<void> goForward() async {
|
Future<void> goForward() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('goForward', args);
|
await _ChannelManager.channel.invokeMethod('goForward', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Check if the Web View of the [InAppBrowser] instance is in a loading state.
|
///Check if the Web View of the [InAppBrowser] instance is in a loading state.
|
||||||
Future<bool> isLoading() async {
|
Future<bool> isLoading() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('isLoading', args);
|
return await _ChannelManager.channel.invokeMethod('isLoading', args);
|
||||||
@ -317,48 +461,54 @@ class InAppBrowser {
|
|||||||
|
|
||||||
///Stops the Web View of the [InAppBrowser] instance from loading.
|
///Stops the Web View of the [InAppBrowser] instance from loading.
|
||||||
Future<void> stopLoading() async {
|
Future<void> stopLoading() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('stopLoading', args);
|
await _ChannelManager.channel.invokeMethod('stopLoading', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Check if the Web View of the [InAppBrowser] instance is hidden.
|
///Check if the Web View of the [InAppBrowser] instance is hidden.
|
||||||
Future<bool> isHidden() async {
|
Future<bool> isHidden() async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
return await _ChannelManager.channel.invokeMethod('isHidden', args);
|
return await _ChannelManager.channel.invokeMethod('isHidden', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects JavaScript code into the [InAppBrowser] window and returns the result of the evaluation. (Only available when the target is set to `_blank` or to `_self`)
|
///Injects JavaScript code into the [InAppBrowser] window and returns the result of the evaluation.
|
||||||
Future<String> injectScriptCode(String source) async {
|
Future<String> injectScriptCode(String source) async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
return await _ChannelManager.channel.invokeMethod('injectScriptCode', args);
|
return await _ChannelManager.channel.invokeMethod('injectScriptCode', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a JavaScript file into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`)
|
///Injects a JavaScript file into the [InAppBrowser] window.
|
||||||
Future<void> injectScriptFile(String urlFile) async {
|
Future<void> injectScriptFile(String urlFile) async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
return await _ChannelManager.channel.invokeMethod('injectScriptFile', args);
|
await _ChannelManager.channel.invokeMethod('injectScriptFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects CSS into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`)
|
///Injects CSS into the [InAppBrowser] window.
|
||||||
Future<void> injectStyleCode(String source) async {
|
Future<void> injectStyleCode(String source) async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
return await _ChannelManager.channel.invokeMethod('injectStyleCode', args);
|
await _ChannelManager.channel.invokeMethod('injectStyleCode', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Injects a CSS file into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`)
|
///Injects a CSS file into the [InAppBrowser] window.
|
||||||
Future<void> injectStyleFile(String urlFile) async {
|
Future<void> injectStyleFile(String urlFile) async {
|
||||||
|
this._throwIsNotOpened();
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
return await _ChannelManager.channel.invokeMethod('injectStyleFile', args);
|
await _ChannelManager.channel.invokeMethod('injectStyleFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Adds/Appends a JavaScript message handler [callback] ([JavaScriptHandlerCallback]) that listen to post messages sent from JavaScript by the handler with name [handlerName].
|
///Adds/Appends a JavaScript message handler [callback] ([JavaScriptHandlerCallback]) that listen to post messages sent from JavaScript by the handler with name [handlerName].
|
||||||
@ -419,7 +569,7 @@ class InAppBrowser {
|
|||||||
///
|
///
|
||||||
///**NOTE**: In order to be able to listen this event, you need to set `useOnLoadResource` option to `true`.
|
///**NOTE**: In order to be able to listen this event, you need to set `useOnLoadResource` option to `true`.
|
||||||
///
|
///
|
||||||
///**NOTE only for iOS**: In some cases, the [response.data] of a [response] with `text/html` encoding could be empty.
|
///**NOTE only for iOS**: In some cases, the [response.data] of a [response] with `text/assets` encoding could be empty.
|
||||||
void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
|
void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -429,6 +579,22 @@ class InAppBrowser {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Returns `true` if the browser is opened, otherwise `false`.
|
||||||
|
bool isOpened() {
|
||||||
|
return this._isOpened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _throwIsAlreadyOpened({String message = ''}) {
|
||||||
|
if (this.isOpened()) {
|
||||||
|
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _throwIsNotOpened({String message = ''}) {
|
||||||
|
if (!this.isOpened()) {
|
||||||
|
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is not opened.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///ChromeSafariBrowser class.
|
///ChromeSafariBrowser class.
|
||||||
@ -440,12 +606,14 @@ class InAppBrowser {
|
|||||||
class ChromeSafariBrowser {
|
class ChromeSafariBrowser {
|
||||||
String uuid;
|
String uuid;
|
||||||
InAppBrowser browserFallback;
|
InAppBrowser browserFallback;
|
||||||
|
bool _isOpened = false;
|
||||||
|
|
||||||
///Initialize the [ChromeSafariBrowser] instance with a [InAppBrowser] fallback instance or `null`.
|
///Initialize the [ChromeSafariBrowser] instance with a [InAppBrowser] fallback instance or `null`.
|
||||||
ChromeSafariBrowser (bf) {
|
ChromeSafariBrowser (bf) {
|
||||||
uuid = _uuidGenerator.v4();
|
uuid = _uuidGenerator.v4();
|
||||||
browserFallback = bf;
|
browserFallback = bf;
|
||||||
_ChannelManager.addListener(uuid, _handleMethod);
|
_ChannelManager.addListener(uuid, _handleMethod);
|
||||||
|
_isOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
@ -458,9 +626,11 @@ class ChromeSafariBrowser {
|
|||||||
break;
|
break;
|
||||||
case "onChromeSafariBrowserClosed":
|
case "onChromeSafariBrowserClosed":
|
||||||
onClosed();
|
onClosed();
|
||||||
|
this._isOpened = false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||||
}
|
}
|
||||||
return new Future.value("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Opens an [url] in a new [ChromeSafariBrowser] instance or the system browser.
|
///Opens an [url] in a new [ChromeSafariBrowser] instance or the system browser.
|
||||||
@ -491,16 +661,17 @@ class ChromeSafariBrowser {
|
|||||||
///- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles.
|
///- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles.
|
||||||
///- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.
|
///- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.
|
||||||
Future<void> open(String url, {Map<String, dynamic> options = const {}, Map<String, String> headersFallback = const {}, Map<String, dynamic> optionsFallback = const {}}) async {
|
Future<void> open(String url, {Map<String, dynamic> options = const {}, Map<String, String> headersFallback = const {}, Map<String, dynamic> optionsFallback = const {}}) async {
|
||||||
|
this._throwIsAlreadyOpened(message: 'Cannot open $url!');
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('uuid', () => uuid);
|
args.putIfAbsent('uuid', () => uuid);
|
||||||
args.putIfAbsent('uuidFallback', () => (browserFallback != null) ? browserFallback.uuid : '');
|
args.putIfAbsent('uuidFallback', () => (browserFallback != null) ? browserFallback.uuid : '');
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
args.putIfAbsent('headers', () => headersFallback);
|
args.putIfAbsent('headers', () => headersFallback);
|
||||||
args.putIfAbsent('target', () => "");
|
|
||||||
args.putIfAbsent('options', () => options);
|
args.putIfAbsent('options', () => options);
|
||||||
args.putIfAbsent('optionsFallback', () => optionsFallback);
|
args.putIfAbsent('optionsFallback', () => optionsFallback);
|
||||||
args.putIfAbsent('useChromeSafariBrowser', () => true);
|
args.putIfAbsent('useChromeSafariBrowser', () => true);
|
||||||
return await _ChannelManager.channel.invokeMethod('open', args);
|
await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
|
this._isOpened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Event fires when the [ChromeSafariBrowser] is opened.
|
///Event fires when the [ChromeSafariBrowser] is opened.
|
||||||
@ -517,4 +688,20 @@ class ChromeSafariBrowser {
|
|||||||
void onClosed() {
|
void onClosed() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOpened() {
|
||||||
|
return this._isOpened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _throwIsAlreadyOpened({String message = ''}) {
|
||||||
|
if (this.isOpened()) {
|
||||||
|
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _throwIsNotOpened({String message = ''}) {
|
||||||
|
if (!this.isOpened()) {
|
||||||
|
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is not opened.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
name: flutter_inappbrowser
|
name: flutter_inappbrowser
|
||||||
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
|
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
|
||||||
version: 0.3.2
|
version: 0.4.0
|
||||||
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
||||||
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
uuid: ^1.0.3
|
uuid: ^1.0.3
|
||||||
|
mime: ^0.9.6+2
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||||
|
Loading…
x
Reference in New Issue
Block a user