added initial support of SFSafariViewController for iOS, updated ChromeCustomTabs for android, added initial version of _ChannelManager dart class
This commit is contained in:
parent
c4afea9191
commit
5db9575a6f
94
.idea/workspace.xml
generated
94
.idea/workspace.xml
generated
@ -10,21 +10,20 @@
|
|||||||
</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 beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsActivity.java" />
|
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/Options.java" />
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabActivityHelper.java" />
|
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsOptions.java" />
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabsHelper.java" />
|
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/KeepAliveService.java" />
|
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ServiceConnection.java" />
|
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ServiceConnectionCallback.java" />
|
|
||||||
<change beforePath="" afterPath="$PROJECT_DIR$/android/src/main/res/layout/chrome_custom_tabs_layout.xml" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/AndroidManifest.xml" afterPath="$PROJECT_DIR$/android/src/main/AndroidManifest.xml" />
|
<change beforePath="$PROJECT_DIR$/README.md" afterPath="$PROJECT_DIR$/README.md" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" />
|
||||||
<change beforePath="$PROJECT_DIR$/android/src/main/res/values/styles.xml" afterPath="$PROJECT_DIR$/android/src/main/res/values/styles.xml" />
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsActivity.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/ChromeCustomTabsActivity.java" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabActivityHelper.java" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/chrome_custom_tabs/CustomTabActivityHelper.java" />
|
||||||
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" afterPath="$PROJECT_DIR$/example/lib/main.dart" />
|
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" afterPath="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
<change beforePath="$PROJECT_DIR$/pubspec.yaml" afterPath="$PROJECT_DIR$/pubspec.yaml" />
|
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
</list>
|
</list>
|
||||||
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
||||||
<ignored path="$PROJECT_DIR$/.idea/" />
|
<ignored path="$PROJECT_DIR$/.idea/" />
|
||||||
@ -44,8 +43,8 @@
|
|||||||
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="true">
|
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="true">
|
||||||
<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="463">
|
<state relative-caret-position="465">
|
||||||
<caret line="233" column="3" lean-forward="false" selection-start-line="233" selection-start-column="3" selection-end-line="233" selection-end-column="3" />
|
<caret line="50" column="54" lean-forward="false" selection-start-line="50" selection-start-column="54" selection-end-line="50" selection-end-column="54" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#814#834#0" expanded="true" />
|
<element signature="e#814#834#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
@ -56,8 +55,8 @@
|
|||||||
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
|
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="614">
|
<state relative-caret-position="87">
|
||||||
<caret line="92" column="18" lean-forward="false" selection-start-line="92" selection-start-column="18" selection-end-line="92" selection-end-column="18" />
|
<caret line="111" column="20" lean-forward="true" selection-start-line="111" selection-start-column="20" selection-end-line="111" selection-end-column="20" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#39#0" expanded="true" />
|
<element signature="e#0#39#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
@ -145,15 +144,15 @@
|
|||||||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||||
<option value="$PROJECT_DIR$/android/build.gradle" />
|
<option value="$PROJECT_DIR$/android/build.gradle" />
|
||||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||||
<option value="$PROJECT_DIR$/README.md" />
|
|
||||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||||
|
<option value="$PROJECT_DIR$/README.md" />
|
||||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectFrameBounds">
|
<component name="ProjectFrameBounds">
|
||||||
<option name="x" value="288" />
|
<option name="x" value="85" />
|
||||||
<option name="y" value="23" />
|
<option name="y" value="23" />
|
||||||
<option name="width" value="1632" />
|
<option name="width" value="1632" />
|
||||||
<option name="height" value="1057" />
|
<option name="height" value="1057" />
|
||||||
@ -174,8 +173,9 @@
|
|||||||
<foldersAlwaysOnTop value="true" />
|
<foldersAlwaysOnTop value="true" />
|
||||||
</navigator>
|
</navigator>
|
||||||
<panes>
|
<panes>
|
||||||
<pane id="AndroidView" />
|
<pane id="PackagesPane" />
|
||||||
<pane id="Scope" />
|
<pane id="Scope" />
|
||||||
|
<pane id="AndroidView" />
|
||||||
<pane id="ProjectPane">
|
<pane id="ProjectPane">
|
||||||
<subPane>
|
<subPane>
|
||||||
<expand>
|
<expand>
|
||||||
@ -199,7 +199,6 @@
|
|||||||
<option name="show-excluded-files" value="false" />
|
<option name="show-excluded-files" value="false" />
|
||||||
</pane>
|
</pane>
|
||||||
<pane id="Scratches" />
|
<pane id="Scratches" />
|
||||||
<pane id="PackagesPane" />
|
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
@ -389,7 +388,7 @@
|
|||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="ToolWindowManager">
|
<component name="ToolWindowManager">
|
||||||
<frame x="288" y="23" width="1632" height="1057" extended-state="0" />
|
<frame x="85" y="23" width="1632" height="1057" extended-state="0" />
|
||||||
<editor active="true" />
|
<editor active="true" />
|
||||||
<layout>
|
<layout>
|
||||||
<window_info id="Android Profiler" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
<window_info id="Android Profiler" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||||
@ -464,7 +463,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
<option name="time" value="4" />
|
<option name="time" value="5" />
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
<watches-manager />
|
<watches-manager />
|
||||||
</component>
|
</component>
|
||||||
@ -752,16 +751,6 @@
|
|||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/README.md">
|
|
||||||
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
|
||||||
<state split_layout="SPLIT">
|
|
||||||
<first_editor relative-caret-position="313">
|
|
||||||
<caret line="300" column="7" lean-forward="true" selection-start-line="300" selection-start-column="7" selection-end-line="300" selection-end-column="7" />
|
|
||||||
</first_editor>
|
|
||||||
<second_editor />
|
|
||||||
</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">
|
||||||
@ -776,10 +765,47 @@
|
|||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
||||||
|
<state split_layout="SPLIT">
|
||||||
|
<first_editor relative-caret-position="302">
|
||||||
|
<caret line="225" column="29" lean-forward="false" selection-start-line="225" selection-start-column="29" selection-end-line="225" selection-end-column="29" />
|
||||||
|
<folding>
|
||||||
|
<marker date="1537920487557" expanded="false" signature="863:961" ph="..." />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1005:2050" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1051:1091" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1143:1717" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1429:1482" ph=""""..."""" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1537:1609" ph=""""..."""" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1788:1849" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1879:1922" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="1982:2047" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2177:2242" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2283:2872" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2317:2345" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2396:2870" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2424:2865" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2450:2858" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2478:2561" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2507:2550" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2587:2849" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2622:2838" ph="(...)" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="2701:2768" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="10453:10461" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="10580:10588" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="10748:10756" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="10852:10860" ph="{...}" />
|
||||||
|
<marker date="1537920487557" expanded="true" signature="11144:11150" ph="{...}" />
|
||||||
|
</folding>
|
||||||
|
</first_editor>
|
||||||
|
<second_editor />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="614">
|
<state relative-caret-position="87">
|
||||||
<caret line="92" column="18" lean-forward="false" selection-start-line="92" selection-start-column="18" selection-end-line="92" selection-end-column="18" />
|
<caret line="111" column="20" lean-forward="true" selection-start-line="111" selection-start-column="20" selection-end-line="111" selection-end-column="20" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#0#39#0" expanded="true" />
|
<element signature="e#0#39#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
@ -788,8 +814,8 @@
|
|||||||
</entry>
|
</entry>
|
||||||
<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="463">
|
<state relative-caret-position="465">
|
||||||
<caret line="233" column="3" lean-forward="false" selection-start-line="233" selection-start-column="3" selection-end-line="233" selection-end-column="3" />
|
<caret line="50" column="54" lean-forward="false" selection-start-line="50" selection-start-column="54" selection-end-line="50" selection-end-column="54" />
|
||||||
<folding>
|
<folding>
|
||||||
<element signature="e#814#834#0" expanded="true" />
|
<element signature="e#814#834#0" expanded="true" />
|
||||||
</folding>
|
</folding>
|
||||||
|
@ -223,6 +223,7 @@ Event fires when the `InAppBrowser` window is closed.
|
|||||||
```
|
```
|
||||||
|
|
||||||
Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
||||||
|
In order to be able to listen this event, you need to set `useShouldOverrideUrlLoading` option to `true`.
|
||||||
```dart
|
```dart
|
||||||
@override
|
@override
|
||||||
void shouldOverrideUrlLoading(String url) {
|
void shouldOverrideUrlLoading(String url) {
|
||||||
|
@ -39,8 +39,10 @@ import android.webkit.WebViewClient;
|
|||||||
import android.util.Log;
|
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 java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -79,7 +81,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMethodCall(MethodCall call, final Result result) {
|
public void onMethodCall(final MethodCall call, final Result result) {
|
||||||
String source;
|
String source;
|
||||||
String jsWrapper;
|
String jsWrapper;
|
||||||
String urlFile;
|
String urlFile;
|
||||||
@ -94,19 +96,33 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
final String target = t;
|
final String target = t;
|
||||||
|
|
||||||
final InAppBrowserOptions options = new InAppBrowserOptions();
|
|
||||||
options.parse((HashMap<String, Object>) call.argument("options"));
|
|
||||||
|
|
||||||
Log.d(LOG_TAG, "target = " + target);
|
Log.d(LOG_TAG, "target = " + target);
|
||||||
|
|
||||||
|
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
|
||||||
|
|
||||||
|
final Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
||||||
|
|
||||||
|
Log.d(LOG_TAG, "use Chrome Custom Tabs = " + useChromeSafariBrowser);
|
||||||
|
|
||||||
this.activity.runOnUiThread(new Runnable() {
|
this.activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
if (options.useChromeCustomTabs) {
|
if (useChromeSafariBrowser) {
|
||||||
open(url, options);
|
|
||||||
|
final ChromeCustomTabsOptions options = new ChromeCustomTabsOptions();
|
||||||
|
options.parse((HashMap<String, Object>) call.argument("options"));
|
||||||
|
|
||||||
|
final InAppBrowserOptions optionsFallback = new InAppBrowserOptions();
|
||||||
|
optionsFallback.parse((HashMap<String, Object>) call.argument("optionsFallback"));
|
||||||
|
|
||||||
|
open(url, options, headers,true, optionsFallback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
final InAppBrowserOptions options = new InAppBrowserOptions();
|
||||||
|
options.parse((HashMap<String, Object>) call.argument("options"));
|
||||||
|
|
||||||
if ("_self".equals(target)) {
|
if ("_self".equals(target)) {
|
||||||
Log.d(LOG_TAG, "in self");
|
Log.d(LOG_TAG, "in self");
|
||||||
|
|
||||||
@ -125,7 +141,7 @@ 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(url, options);
|
open(url, options, headers, false, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SYSTEM
|
// SYSTEM
|
||||||
@ -136,7 +152,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
// BLANK - or anything else
|
// BLANK - or anything else
|
||||||
else {
|
else {
|
||||||
Log.d(LOG_TAG, "in blank");
|
Log.d(LOG_TAG, "in blank");
|
||||||
open(url, options);
|
open(url, options, headers, false, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
@ -365,12 +381,17 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void open(final String url, InAppBrowserOptions options) {
|
public static void open(final String url, Options options, Map<String, String> headers, boolean useChromeSafariBrowser, InAppBrowserOptions optionsFallback) {
|
||||||
Intent intent = new Intent(registrar.activity(), (options.useChromeCustomTabs) ? ChromeCustomTabsActivity.class : WebViewActivity.class);
|
Intent intent = new Intent(registrar.activity(), (useChromeSafariBrowser) ? ChromeCustomTabsActivity.class : WebViewActivity.class);
|
||||||
|
|
||||||
Bundle extras = new Bundle();
|
Bundle extras = new Bundle();
|
||||||
extras.putString("url", url);
|
extras.putString("url", url);
|
||||||
extras.putSerializable("options", options.getHashMap());
|
extras.putSerializable("options", options.getHashMap());
|
||||||
|
extras.putSerializable("headers", (Serializable) headers);
|
||||||
|
if (useChromeSafariBrowser && optionsFallback != null)
|
||||||
|
extras.putSerializable("optionsFallback", optionsFallback.getHashMap());
|
||||||
|
else
|
||||||
|
extras.putSerializable("optionsFallback", (new InAppBrowserOptions()).getHashMap());
|
||||||
|
|
||||||
intent.putExtras(extras);
|
intent.putExtras(extras);
|
||||||
|
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package com.pichillilorenzo.flutter_inappbrowser;
|
package com.pichillilorenzo.flutter_inappbrowser;
|
||||||
|
|
||||||
import android.util.Log;
|
public class InAppBrowserOptions extends Options {
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
final static String LOG_TAG = "InAppBrowserOptions";
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class InAppBrowserOptions {
|
|
||||||
|
|
||||||
public boolean useShouldOverrideUrlLoading = false;
|
public boolean useShouldOverrideUrlLoading = false;
|
||||||
public boolean clearCache = false;
|
public boolean clearCache = false;
|
||||||
@ -31,38 +26,4 @@ public class InAppBrowserOptions {
|
|||||||
public boolean useWideViewPort = true;
|
public boolean useWideViewPort = true;
|
||||||
public boolean safeBrowsingEnabled = true;
|
public boolean safeBrowsingEnabled = true;
|
||||||
public boolean progressBar = true;
|
public boolean progressBar = true;
|
||||||
|
|
||||||
public boolean useChromeCustomTabs = false;
|
|
||||||
public boolean CCT_addShareButton = true;
|
|
||||||
public boolean CCT_showTitle = true;
|
|
||||||
public String CCT_toolbarColor = "";
|
|
||||||
public boolean CCT_enableUrlBarHiding = false;
|
|
||||||
public boolean CCT_instantAppsEnabled = false;
|
|
||||||
|
|
||||||
public void parse(HashMap<String, Object> options) {
|
|
||||||
Iterator it = options.entrySet().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Map.Entry<String, Object> pair = (Map.Entry<String, Object>)it.next();
|
|
||||||
try {
|
|
||||||
this.getClass().getDeclaredField(pair.getKey()).set(this, pair.getValue());
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
Log.d("InAppBrowserOptions", e.getMessage());
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
Log.d("InAppBrowserOptions", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, Object> getHashMap() {
|
|
||||||
HashMap<String, Object> options = new HashMap<>();
|
|
||||||
for (Field f: this.getClass().getDeclaredFields()) {
|
|
||||||
try {
|
|
||||||
options.put(f.getName(), f.get(this));
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
Log.d("InAppBrowserOptions", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.pichillilorenzo.flutter_inappbrowser;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Options {
|
||||||
|
|
||||||
|
final static String LOG_TAG = "";
|
||||||
|
|
||||||
|
public void parse(HashMap<String, Object> options) {
|
||||||
|
Iterator it = options.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry<String, Object> pair = (Map.Entry<String, Object>)it.next();
|
||||||
|
try {
|
||||||
|
this.getClass().getDeclaredField(pair.getKey()).set(this, pair.getValue());
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
Log.d(LOG_TAG, e.getMessage());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.d(LOG_TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Object> getHashMap() {
|
||||||
|
HashMap<String, Object> options = new HashMap<>();
|
||||||
|
for (Field f: this.getClass().getDeclaredFields()) {
|
||||||
|
try {
|
||||||
|
options.put(f.getName(), f.get(this));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.d(LOG_TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -33,6 +33,7 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
InAppBrowserWebChromeClient inAppBrowserWebChromeClient;
|
InAppBrowserWebChromeClient inAppBrowserWebChromeClient;
|
||||||
SearchView searchView;
|
SearchView searchView;
|
||||||
InAppBrowserOptions options;
|
InAppBrowserOptions options;
|
||||||
|
Map<String, String> headers;
|
||||||
ProgressBar progressBar;
|
ProgressBar progressBar;
|
||||||
public boolean isLoading = false;
|
public boolean isLoading = false;
|
||||||
public boolean isHidden = false;
|
public boolean isHidden = false;
|
||||||
@ -51,13 +52,15 @@ public class WebViewActivity extends AppCompatActivity {
|
|||||||
options = new InAppBrowserOptions();
|
options = new InAppBrowserOptions();
|
||||||
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
||||||
|
|
||||||
|
headers = (HashMap<String, String>) b.getSerializable("headers");
|
||||||
|
|
||||||
InAppBrowserFlutterPlugin.webViewActivity = this;
|
InAppBrowserFlutterPlugin.webViewActivity = this;
|
||||||
|
|
||||||
actionBar = getSupportActionBar();
|
actionBar = getSupportActionBar();
|
||||||
|
|
||||||
prepareWebView();
|
prepareWebView();
|
||||||
|
|
||||||
webView.loadUrl(url);
|
webView.loadUrl(url, headers);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,19 +6,20 @@ import android.graphics.Color;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.customtabs.CustomTabsIntent;
|
import android.support.customtabs.CustomTabsIntent;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserOptions;
|
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserOptions;
|
||||||
import com.pichillilorenzo.flutter_inappbrowser.R;
|
import com.pichillilorenzo.flutter_inappbrowser.R;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ChromeCustomTabsActivity extends Activity {
|
public class ChromeCustomTabsActivity extends Activity {
|
||||||
|
|
||||||
CustomTabsIntent.Builder builder;
|
CustomTabsIntent.Builder builder;
|
||||||
InAppBrowserOptions 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;
|
||||||
|
|
||||||
@ -31,9 +32,14 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
Bundle b = getIntent().getExtras();
|
Bundle b = getIntent().getExtras();
|
||||||
String url = b.getString("url");
|
String url = b.getString("url");
|
||||||
|
|
||||||
options = new InAppBrowserOptions();
|
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"));
|
||||||
|
|
||||||
customTabActivityHelper = new CustomTabActivityHelper();
|
customTabActivityHelper = new CustomTabActivityHelper();
|
||||||
|
|
||||||
builder = new CustomTabsIntent.Builder();
|
builder = new CustomTabsIntent.Builder();
|
||||||
@ -42,28 +48,33 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
|
|
||||||
CustomTabsIntent customTabsIntent = builder.build();
|
CustomTabsIntent customTabsIntent = builder.build();
|
||||||
|
|
||||||
customTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), CHROME_CUSTOM_TAB_REQUEST_CODE,
|
boolean chromeCustomTabsOpened = customTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), CHROME_CUSTOM_TAB_REQUEST_CODE,
|
||||||
new CustomTabActivityHelper.CustomTabFallback() {
|
new CustomTabActivityHelper.CustomTabFallback() {
|
||||||
@Override
|
@Override
|
||||||
public void openUri(Activity activity, Uri uri) {
|
public void openUri(Activity activity, Uri uri) {
|
||||||
InAppBrowserFlutterPlugin.open(uri.toString(), options);
|
InAppBrowserFlutterPlugin.open(uri.toString(), optionsFallback, headersFallback, false, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (chromeCustomTabsOpened) {
|
||||||
|
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserOpened", null);
|
||||||
|
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserLoaded", null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabs() {
|
private void prepareCustomTabs() {
|
||||||
if (options.CCT_addShareButton)
|
if (options.addShareButton)
|
||||||
builder.addDefaultShareMenuItem();
|
builder.addDefaultShareMenuItem();
|
||||||
|
|
||||||
if (!options.CCT_toolbarColor.isEmpty())
|
if (!options.toolbarBackgroundColor.isEmpty())
|
||||||
builder.setToolbarColor(Color.parseColor(options.CCT_toolbarColor));
|
builder.setToolbarColor(Color.parseColor(options.toolbarBackgroundColor));
|
||||||
|
|
||||||
builder.setShowTitle(options.CCT_showTitle);
|
builder.setShowTitle(options.showTitle);
|
||||||
|
|
||||||
if (options.CCT_enableUrlBarHiding)
|
if (options.enableUrlBarHiding)
|
||||||
builder.enableUrlBarHiding();
|
builder.enableUrlBarHiding();
|
||||||
|
|
||||||
builder.setInstantAppsEnabled(options.CCT_instantAppsEnabled);
|
builder.setInstantAppsEnabled(options.instantAppsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -82,6 +93,7 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
if (requestCode == CHROME_CUSTOM_TAB_REQUEST_CODE) {
|
if (requestCode == CHROME_CUSTOM_TAB_REQUEST_CODE) {
|
||||||
finish();
|
finish();
|
||||||
|
InAppBrowserFlutterPlugin.channel.invokeMethod("onChromeSafariBrowserClosed", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs;
|
||||||
|
|
||||||
|
import com.pichillilorenzo.flutter_inappbrowser.Options;
|
||||||
|
|
||||||
|
public class ChromeCustomTabsOptions extends Options {
|
||||||
|
|
||||||
|
final static String LOG_TAG = "ChromeCustomTabsOptions";
|
||||||
|
|
||||||
|
public boolean addShareButton = true;
|
||||||
|
public boolean showTitle = true;
|
||||||
|
public String toolbarBackgroundColor = "";
|
||||||
|
public boolean enableUrlBarHiding = false;
|
||||||
|
public boolean instantAppsEnabled = false;
|
||||||
|
|
||||||
|
}
|
@ -29,24 +29,28 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
* @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.
|
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
|
||||||
*/
|
*/
|
||||||
public static void openCustomTab(Activity activity,
|
public static boolean openCustomTab(Activity activity,
|
||||||
CustomTabsIntent customTabsIntent,
|
CustomTabsIntent customTabsIntent,
|
||||||
Uri uri,
|
Uri uri,
|
||||||
int requestCode,
|
int requestCode,
|
||||||
CustomTabFallback fallback) {
|
CustomTabFallback fallback) {
|
||||||
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
|
|
||||||
|
|
||||||
//If we cant find a package name, it means theres no browser that supports
|
//If we cant find a package name, it means theres no browser that supports
|
||||||
//Chrome Custom Tabs installed. So, we fallback to the webview
|
//Chrome Custom Tabs installed. So, we fallback to the webview
|
||||||
if (packageName == null) {
|
if (!isAvailable(activity)) {
|
||||||
if (fallback != null) {
|
if (fallback != null) {
|
||||||
fallback.openUri(activity, uri);
|
fallback.openUri(activity, uri);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
customTabsIntent.intent.setPackage(packageName);
|
//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) {
|
||||||
|
return CustomTabsHelper.getPackageNameToUse(activity) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,28 @@ class MyInAppBrowser extends InAppBrowser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyInAppBrowser inAppBrowser = new MyInAppBrowser();
|
MyInAppBrowser inAppBrowserFallback = new MyInAppBrowser();
|
||||||
|
|
||||||
|
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||||
|
MyChromeSafariBrowser(browserFallback) : super(browserFallback);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onOpened() {
|
||||||
|
print("ChromeSafari browser opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onLoaded() {
|
||||||
|
print("ChromeSafari browser loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClosed() {
|
||||||
|
print("ChromeSafari browser closed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyChromeSafariBrowser chromeSafariBrowser = new MyChromeSafariBrowser(inAppBrowserFallback);
|
||||||
|
|
||||||
void main() => runApp(new MyApp());
|
void main() => runApp(new MyApp());
|
||||||
|
|
||||||
@ -86,15 +107,28 @@ class _MyAppState extends State<MyApp> {
|
|||||||
),
|
),
|
||||||
body: new Center(
|
body: new Center(
|
||||||
child: new RaisedButton(onPressed: () {
|
child: new RaisedButton(onPressed: () {
|
||||||
inAppBrowser.open("https://flutter.io/", options: {
|
chromeSafariBrowser.open("https://flutter.io/", options: {
|
||||||
"useChromeCustomTabs": true,
|
"addShareButton": false,
|
||||||
//"hidden": true,
|
"toolbarBackgroundColor": "#000000",
|
||||||
|
"dismissButtonStyle": 1,
|
||||||
|
"preferredBarTintColor": "#000000",
|
||||||
|
},
|
||||||
|
optionsFallback: {
|
||||||
|
"hidden": true,
|
||||||
//"toolbarTopFixedTitle": "Fixed title",
|
//"toolbarTopFixedTitle": "Fixed title",
|
||||||
//"useShouldOverrideUrlLoading": true
|
//"useShouldOverrideUrlLoading": true
|
||||||
//"hideUrlBar": true,
|
//"hideUrlBar": true,
|
||||||
//"toolbarTop": false,
|
//"toolbarTop": false,
|
||||||
//"toolbarBottom": false
|
//"toolbarBottom": false
|
||||||
});
|
});
|
||||||
|
// inAppBrowserFallback.open("https://flutter.io/", options: {
|
||||||
|
// //"hidden": true,
|
||||||
|
// //"toolbarTopFixedTitle": "Fixed title",
|
||||||
|
// //"useShouldOverrideUrlLoading": true
|
||||||
|
// //"hideUrlBar": true,
|
||||||
|
// //"toolbarTop": false,
|
||||||
|
// //"toolbarBottom": false
|
||||||
|
// });
|
||||||
|
|
||||||
},
|
},
|
||||||
child: Text("Open InAppBrowser")
|
child: Text("Open InAppBrowser")
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers
|
@objcMembers
|
||||||
public class InAppBrowserOptions: NSObject {
|
public class InAppBrowserOptions: Options {
|
||||||
|
|
||||||
var useShouldOverrideUrlLoading = false
|
var useShouldOverrideUrlLoading = false
|
||||||
var clearCache = false
|
var clearCache = false
|
||||||
@ -44,12 +44,5 @@ public class InAppBrowserOptions: NSObject {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parse(options: [String: Any]) {
|
|
||||||
for (key, value) in options {
|
|
||||||
if self.responds(to: Selector(key)) {
|
|
||||||
self.setValue(value, forKey: key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +86,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
UIApplication.shared.statusBarStyle = preferredStatusBarStyle
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
prepareWebView()
|
prepareWebView()
|
||||||
|
super.viewWillAppear(animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
@ -133,6 +132,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||||||
|
|
||||||
func prepareWebView() {
|
func prepareWebView() {
|
||||||
|
|
||||||
|
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
|
||||||
|
|
||||||
self.webView.configuration.userContentController = WKUserContentController()
|
self.webView.configuration.userContentController = WKUserContentController()
|
||||||
self.webView.configuration.preferences = WKPreferences()
|
self.webView.configuration.preferences = WKPreferences()
|
||||||
|
|
||||||
|
25
ios/Classes/Options.swift
Normal file
25
ios/Classes/Options.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Options.swift
|
||||||
|
// flutter_inappbrowser
|
||||||
|
//
|
||||||
|
// Created by Lorenzo on 26/09/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers
|
||||||
|
public class Options: NSObject {
|
||||||
|
|
||||||
|
override init(){
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func parse(options: [String: Any]) {
|
||||||
|
for (key, value) in options {
|
||||||
|
if self.responds(to: Selector(key)) {
|
||||||
|
self.setValue(value, forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
23
ios/Classes/SafariBrowserOptions.swift
Normal file
23
ios/Classes/SafariBrowserOptions.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// SafariBrowserOptions.swift
|
||||||
|
// flutter_inappbrowser
|
||||||
|
//
|
||||||
|
// Created by Lorenzo on 26/09/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers
|
||||||
|
public class SafariBrowserOptions: Options {
|
||||||
|
|
||||||
|
var entersReaderIfAvailable = false
|
||||||
|
var barCollapsingEnabled = false
|
||||||
|
var dismissButtonStyle = 0 //done
|
||||||
|
var preferredBarTintColor = ""
|
||||||
|
var preferredControlTintColor = ""
|
||||||
|
|
||||||
|
override init(){
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
ios/Classes/SafariViewController.swift
Normal file
93
ios/Classes/SafariViewController.swift
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// SafariViewController.swift
|
||||||
|
// flutter_inappbrowser
|
||||||
|
//
|
||||||
|
// Created by Lorenzo on 25/09/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SafariServices
|
||||||
|
|
||||||
|
@available(iOS 9.0, *)
|
||||||
|
class SafariViewController: SFSafariViewController, SFSafariViewControllerDelegate {
|
||||||
|
|
||||||
|
weak var statusDelegate: SwiftFlutterPlugin?
|
||||||
|
var tmpWindow: UIWindow?
|
||||||
|
var safariOptions: SafariBrowserOptions?
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
prepareSafariBrowser()
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareSafariBrowser() {
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: (safariOptions?.dismissButtonStyle)!)!
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
if !(safariOptions?.preferredBarTintColor.isEmpty)! {
|
||||||
|
self.preferredBarTintColor = color(fromHexString: (safariOptions?.preferredBarTintColor)!)
|
||||||
|
}
|
||||||
|
if !(safariOptions?.preferredControlTintColor.isEmpty)! {
|
||||||
|
self.preferredControlTintColor = color(fromHexString: (safariOptions?.preferredControlTintColor)!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func close() {
|
||||||
|
if (statusDelegate != nil) {
|
||||||
|
statusDelegate?.safariExit()
|
||||||
|
}
|
||||||
|
|
||||||
|
dismiss(animated: true)
|
||||||
|
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
|
||||||
|
self.tmpWindow?.windowLevel = 0.0
|
||||||
|
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func safariViewController(_ controller: SFSafariViewController,
|
||||||
|
didCompleteInitialLoad didLoadSuccessfully: Bool) {
|
||||||
|
if didLoadSuccessfully {
|
||||||
|
statusDelegate?.onChromeSafariBrowserLoaded()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print("Cant load successfully the 'SafariViewController'.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to convert hex color string to UIColor
|
||||||
|
// Assumes input like "#00FF00" (#RRGGBB).
|
||||||
|
// Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
|
||||||
|
|
||||||
|
func color(fromHexString: String, alpha:CGFloat? = 1.0) -> UIColor {
|
||||||
|
|
||||||
|
// Convert hex string to an integer
|
||||||
|
let hexint = Int(self.intFromHexString(hexStr: fromHexString))
|
||||||
|
let red = CGFloat((hexint & 0xff0000) >> 16) / 255.0
|
||||||
|
let green = CGFloat((hexint & 0xff00) >> 8) / 255.0
|
||||||
|
let blue = CGFloat((hexint & 0xff) >> 0) / 255.0
|
||||||
|
let alpha = alpha!
|
||||||
|
|
||||||
|
// Create color object, specifying alpha as well
|
||||||
|
let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
|
||||||
|
func intFromHexString(hexStr: String) -> UInt32 {
|
||||||
|
var hexInt: UInt32 = 0
|
||||||
|
// Create scanner
|
||||||
|
let scanner: Scanner = Scanner(string: hexStr)
|
||||||
|
// Tell scanner to skip the # character
|
||||||
|
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
|
||||||
|
// Scan hex value
|
||||||
|
scanner.scanHexInt32(&hexInt)
|
||||||
|
return hexInt
|
||||||
|
}
|
||||||
|
}
|
@ -20,12 +20,14 @@ import UIKit
|
|||||||
import WebKit
|
import WebKit
|
||||||
import Foundation
|
import Foundation
|
||||||
import AVFoundation
|
import AVFoundation
|
||||||
|
import SafariServices
|
||||||
|
|
||||||
let WEBVIEW_STORYBOARD = "WebView"
|
let WEBVIEW_STORYBOARD = "WebView"
|
||||||
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
|
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
|
||||||
|
|
||||||
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
var webViewController: InAppBrowserWebViewController?
|
var webViewController: InAppBrowserWebViewController?
|
||||||
|
var safariViewController: Any?
|
||||||
|
|
||||||
var tmpWindow: UIWindow?
|
var tmpWindow: UIWindow?
|
||||||
var channel: FlutterMethodChannel
|
var channel: FlutterMethodChannel
|
||||||
@ -128,34 +130,38 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func open(arguments: NSDictionary, result: @escaping FlutterResult) {
|
public func open(arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||||
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)!
|
var target: String? = (arguments["target"] as? String)!
|
||||||
target = target != nil ? target : "_self"
|
target = target != nil ? target : "_self"
|
||||||
|
let absoluteUrl = URL(string: url)?.absoluteURL
|
||||||
|
|
||||||
|
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)
|
||||||
|
|
||||||
|
if useChromeSafariBrowser! {
|
||||||
let options = (arguments["options"] as? [String: Any])!
|
let options = (arguments["options"] as? [String: Any])!
|
||||||
|
let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
|
||||||
|
|
||||||
if url != nil {
|
open(inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback);
|
||||||
let absoluteUrl = URL(string: url!)?.absoluteURL
|
}
|
||||||
|
else {
|
||||||
|
let options = (arguments["options"] as? [String: Any])!
|
||||||
if isSystemUrl(absoluteUrl!) {
|
if isSystemUrl(absoluteUrl!) {
|
||||||
target = "_system"
|
target = "_system"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target == "_self" || target == "_target") {
|
if (target == "_self" || target == "_target") {
|
||||||
open(inAppBrowser: absoluteUrl!, headers: headers, withOptions: options)
|
open(inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil)
|
||||||
}
|
}
|
||||||
else if (target == "_system") {
|
else if (target == "_system") {
|
||||||
open(inSystem: absoluteUrl!)
|
open(inSystem: absoluteUrl!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// anything else
|
// anything else
|
||||||
open(inAppBrowser: absoluteUrl!, headers: headers,withOptions: options)
|
open(inAppBrowser: absoluteUrl!, headers: headers,withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
print("url is empty")
|
|
||||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
|
||||||
}
|
|
||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,15 +180,22 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func open(inAppBrowser url: URL, headers: [String: String], withOptions options: [String: Any]) {
|
func open(inAppBrowser url: URL, headers: [String: String], withOptions options: [String: Any], useChromeSafariBrowser: Bool, withOptionsFallback optionsFallback: [String: Any]?) {
|
||||||
|
|
||||||
let browserOptions = InAppBrowserOptions()
|
|
||||||
browserOptions.parse(options: options)
|
|
||||||
|
|
||||||
if webViewController != nil {
|
if webViewController != nil {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
else if self.previousStatusBarStyle == -1 {
|
|
||||||
|
if safariViewController != nil {
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
(safariViewController! as! SafariViewController).close()
|
||||||
|
safariViewController = nil
|
||||||
|
} else {
|
||||||
|
// Fallback on earlier versions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.previousStatusBarStyle == -1 {
|
||||||
self.previousStatusBarStyle = UIApplication.shared.statusBarStyle.rawValue
|
self.previousStatusBarStyle = UIApplication.shared.statusBarStyle.rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +204,54 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
self.tmpWindow = UIWindow(frame: frame)
|
self.tmpWindow = UIWindow(frame: frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tmpController = UIViewController()
|
||||||
|
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
|
||||||
|
self.tmpWindow?.rootViewController = tmpController
|
||||||
|
self.tmpWindow?.windowLevel = UIWindowLevel(baseWindowLevel! + 1)
|
||||||
|
self.tmpWindow?.makeKeyAndVisible()
|
||||||
|
|
||||||
|
let browserOptions: InAppBrowserOptions
|
||||||
|
|
||||||
|
if useChromeSafariBrowser == true {
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
let safariOptions = SafariBrowserOptions()
|
||||||
|
safariOptions.parse(options: options)
|
||||||
|
|
||||||
|
let safari: SafariViewController
|
||||||
|
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
let config = SFSafariViewController.Configuration()
|
||||||
|
config.entersReaderIfAvailable = safariOptions.entersReaderIfAvailable
|
||||||
|
config.barCollapsingEnabled = safariOptions.barCollapsingEnabled
|
||||||
|
|
||||||
|
safari = SafariViewController(url: url, configuration: config)
|
||||||
|
} else {
|
||||||
|
// Fallback on earlier versions
|
||||||
|
safari = SafariViewController(url: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
safari.delegate = safari
|
||||||
|
safari.statusDelegate = self
|
||||||
|
safari.tmpWindow = tmpWindow
|
||||||
|
safari.safariOptions = safariOptions
|
||||||
|
|
||||||
|
safariViewController = safari
|
||||||
|
|
||||||
|
tmpController.present(safariViewController! as! SFSafariViewController, animated: true)
|
||||||
|
onChromeSafariBrowserOpened()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
browserOptions = InAppBrowserOptions()
|
||||||
|
browserOptions.parse(options: optionsFallback!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
browserOptions = InAppBrowserOptions()
|
||||||
|
browserOptions.parse(options: options)
|
||||||
|
}
|
||||||
|
|
||||||
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: nil)
|
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: nil)
|
||||||
let vc = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID)
|
let vc = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID)
|
||||||
webViewController = vc as? InAppBrowserWebViewController
|
webViewController = vc as? InAppBrowserWebViewController
|
||||||
@ -201,27 +262,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
webViewController?.initHeaders = headers
|
webViewController?.initHeaders = headers
|
||||||
webViewController?.navigationDelegate = self
|
webViewController?.navigationDelegate = self
|
||||||
|
|
||||||
let tmpController = UIViewController()
|
|
||||||
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
|
|
||||||
self.tmpWindow?.rootViewController = tmpController
|
|
||||||
self.tmpWindow?.windowLevel = UIWindowLevel(baseWindowLevel! + 1)
|
|
||||||
self.tmpWindow?.makeKeyAndVisible()
|
|
||||||
if browserOptions.hidden {
|
if browserOptions.hidden {
|
||||||
webViewController!.view.isHidden = true
|
webViewController!.view.isHidden = true
|
||||||
tmpController.present(self.webViewController!, animated: false, completion: {() -> Void in
|
tmpController.present(self.webViewController!, animated: false, completion: {() -> Void in
|
||||||
if self.previousStatusBarStyle != -1 {
|
// if self.previousStatusBarStyle != -1 {
|
||||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
// UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||||
}
|
// }
|
||||||
})
|
})
|
||||||
if self.previousStatusBarStyle != -1 {
|
// if self.previousStatusBarStyle != -1 {
|
||||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
// UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||||
}
|
// }
|
||||||
webViewController?.presentingViewController?.dismiss(animated: false, completion: {() -> Void in
|
webViewController?.presentingViewController?.dismiss(animated: false, 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.previousStatusBarStyle != -1 {
|
|
||||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -355,14 +408,36 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
channel.invokeMethod("onLoadError", arguments: arguments)
|
channel.invokeMethod("onLoadError", arguments: arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func onExit() {
|
||||||
|
channel.invokeMethod("onExit", arguments: [])
|
||||||
|
}
|
||||||
|
|
||||||
func shouldOverrideUrlLoading(_ webView: WKWebView, url: URL) {
|
func shouldOverrideUrlLoading(_ webView: WKWebView, url: URL) {
|
||||||
channel.invokeMethod("shouldOverrideUrlLoading", arguments: ["url": url.absoluteString])
|
channel.invokeMethod("shouldOverrideUrlLoading", arguments: ["url": url.absoluteString])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func onChromeSafariBrowserOpened() {
|
||||||
|
channel.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
func onChromeSafariBrowserLoaded() {
|
||||||
|
channel.invokeMethod("onChromeSafariBrowserLoaded", arguments: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
func onChromeSafariBrowserClosed() {
|
||||||
|
channel.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
func safariExit() {
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
(safariViewController as! SafariViewController).statusDelegate = nil
|
||||||
|
(safariViewController as! SafariViewController).delegate = nil
|
||||||
|
}
|
||||||
|
safariViewController = nil
|
||||||
|
onChromeSafariBrowserClosed()
|
||||||
|
}
|
||||||
|
|
||||||
func browserExit() {
|
func browserExit() {
|
||||||
|
|
||||||
channel.invokeMethod("onExit", arguments: [])
|
|
||||||
|
|
||||||
// Set navigationDelegate to nil to ensure no callbacks are received from it.
|
// Set navigationDelegate to nil to ensure no callbacks are received from it.
|
||||||
webViewController?.navigationDelegate = nil
|
webViewController?.navigationDelegate = nil
|
||||||
// Don't recycle the ViewController since it may be consuming a lot of memory.
|
// Don't recycle the ViewController since it may be consuming a lot of memory.
|
||||||
@ -373,6 +448,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: previousStatusBarStyle)!
|
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: previousStatusBarStyle)!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,37 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
///Main class of the plugin.
|
class _ChannelManager {
|
||||||
|
static const MethodChannel channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
||||||
|
static final initialized = false;
|
||||||
|
static final listeners = <Function>[];
|
||||||
|
|
||||||
|
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
|
for (var listener in listeners) {
|
||||||
|
listener(call);
|
||||||
|
}
|
||||||
|
return new Future.value("");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addListener (Function callback) {
|
||||||
|
if (!initialized)
|
||||||
|
init();
|
||||||
|
listeners.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init () {
|
||||||
|
channel.setMethodCallHandler(_handleMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///InAppBrowser class.
|
||||||
|
///
|
||||||
|
/// This class uses the native WebView of the platform.
|
||||||
class InAppBrowser {
|
class InAppBrowser {
|
||||||
static const MethodChannel _channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
|
|
||||||
|
|
||||||
///
|
///
|
||||||
InAppBrowser () {
|
InAppBrowser () {
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
_ChannelManager.addListener(_handleMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
@ -124,7 +148,8 @@ class InAppBrowser {
|
|||||||
args.putIfAbsent('headers', () => headers);
|
args.putIfAbsent('headers', () => headers);
|
||||||
args.putIfAbsent('target', () => target);
|
args.putIfAbsent('target', () => target);
|
||||||
args.putIfAbsent('options', () => options);
|
args.putIfAbsent('options', () => options);
|
||||||
return await _channel.invokeMethod('open', args);
|
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||||
|
return await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///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.
|
||||||
@ -132,80 +157,80 @@ class InAppBrowser {
|
|||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url);
|
args.putIfAbsent('url', () => url);
|
||||||
args.putIfAbsent('headers', () => headers);
|
args.putIfAbsent('headers', () => headers);
|
||||||
return await _channel.invokeMethod('loadUrl', args);
|
return await _ChannelManager.channel.invokeMethod('loadUrl', 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 {
|
||||||
return await _channel.invokeMethod('show');
|
return await _ChannelManager.channel.invokeMethod('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('hide');
|
return await _ChannelManager.channel.invokeMethod('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
///Closes the [InAppBrowser] window.
|
///Closes the [InAppBrowser] window.
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
return await _channel.invokeMethod('close');
|
return await _ChannelManager.channel.invokeMethod('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
///Reloads the [InAppBrowser] window.
|
///Reloads the [InAppBrowser] window.
|
||||||
Future<void> reload() async {
|
Future<void> reload() async {
|
||||||
return await _channel.invokeMethod('reload');
|
return await _ChannelManager.channel.invokeMethod('reload');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('goBack');
|
return await _ChannelManager.channel.invokeMethod('goBack');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('goForward');
|
return await _ChannelManager.channel.invokeMethod('goForward');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('isLoading');
|
return await _ChannelManager.channel.invokeMethod('isLoading');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('stopLoading');
|
return await _ChannelManager.channel.invokeMethod('stopLoading');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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 {
|
||||||
return await _channel.invokeMethod('isHidden');
|
return await _ChannelManager.channel.invokeMethod('isHidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
///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. (Only available when the target is set to `_blank` or to `_self`)
|
||||||
Future<String> injectScriptCode(String source) async {
|
Future<String> injectScriptCode(String source) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
return await _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. (Only available when the target is set to `_blank` or to `_self`)
|
||||||
Future<void> injectScriptFile(String urlFile) async {
|
Future<void> injectScriptFile(String urlFile) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
return await _channel.invokeMethod('injectScriptFile', args);
|
return 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. (Only available when the target is set to `_blank` or to `_self`)
|
||||||
Future<void> injectStyleCode(String source) async {
|
Future<void> injectStyleCode(String source) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
return await _channel.invokeMethod('injectStyleCode', args);
|
return 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. (Only available when the target is set to `_blank` or to `_self`)
|
||||||
Future<void> injectStyleFile(String urlFile) async {
|
Future<void> injectStyleFile(String urlFile) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('urlFile', () => urlFile);
|
args.putIfAbsent('urlFile', () => urlFile);
|
||||||
return await _channel.invokeMethod('injectStyleFile', args);
|
return await _ChannelManager.channel.invokeMethod('injectStyleFile', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Event fires when the [InAppBrowser] starts to load an [url].
|
///Event fires when the [InAppBrowser] starts to load an [url].
|
||||||
@ -229,8 +254,67 @@ class InAppBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
///Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
|
||||||
|
///In order to be able to listen this event, you need to set `useShouldOverrideUrlLoading` option to `true`.
|
||||||
void shouldOverrideUrlLoading(String url) {
|
void shouldOverrideUrlLoading(String url) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///ChromeSafariBrowser class.
|
||||||
|
///
|
||||||
|
///This class uses native [Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android
|
||||||
|
///and [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.
|
||||||
|
///
|
||||||
|
///[browserFallback] represents the [InAppBrowser] instance fallback in case [Chrome Custom Tabs]/[SFSafariViewController] is not available.
|
||||||
|
class ChromeSafariBrowser {
|
||||||
|
InAppBrowser browserFallback;
|
||||||
|
|
||||||
|
///
|
||||||
|
ChromeSafariBrowser (browserFallback) {
|
||||||
|
this.browserFallback = browserFallback;
|
||||||
|
_ChannelManager.addListener(_handleMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
|
switch(call.method) {
|
||||||
|
case "onChromeSafariBrowserOpened":
|
||||||
|
onOpened();
|
||||||
|
break;
|
||||||
|
case "onChromeSafariBrowserLoaded":
|
||||||
|
onLoaded();
|
||||||
|
break;
|
||||||
|
case "onChromeSafariBrowserClosed":
|
||||||
|
onClosed();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new Future.value("");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Future<void> open(String url, {Map<String, dynamic> options = const {}, Map<String, String> headersFallback = const {}, Map<String, dynamic> optionsFallback = const {}}) async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent('url', () => url);
|
||||||
|
args.putIfAbsent('headers', () => headersFallback);
|
||||||
|
args.putIfAbsent('target', () => "");
|
||||||
|
args.putIfAbsent('options', () => options);
|
||||||
|
args.putIfAbsent('optionsFallback', () => optionsFallback);
|
||||||
|
args.putIfAbsent('useChromeSafariBrowser', () => true);
|
||||||
|
return await _ChannelManager.channel.invokeMethod('open', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///Event fires when the [ChromeSafariBrowser] is opened.
|
||||||
|
void onOpened() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///Event fires when the [ChromeSafariBrowser] is loaded.
|
||||||
|
void onLoaded() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///Event fires when the [ChromeSafariBrowser] is closed.
|
||||||
|
void onClosed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user