This commit is contained in:
pichillilorenzo 2018-11-07 01:11:27 +01:00
parent 53e9ecbfa2
commit b043b435d2
14 changed files with 737 additions and 205 deletions

View File

@ -16,8 +16,19 @@
<component name="ChangeListManager">
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" 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/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppWebView.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
</list>
<ignored path="$PROJECT_DIR$/.dart_tool/" />
<ignored path="$PROJECT_DIR$/.idea/" />
@ -37,8 +48,8 @@
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="104">
<caret line="932" column="46" selection-start-line="932" selection-start-column="20" selection-end-line="932" selection-end-column="46" />
<state relative-caret-position="176">
<caret line="256" column="65" lean-forward="true" selection-start-line="256" selection-start-column="5" selection-end-line="256" selection-end-column="65" />
<folding>
<element signature="e#814#831#0" expanded="true" />
</folding>
@ -46,28 +57,23 @@
</provider>
</entry>
</file>
<file leaf-file-name="README.md" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/README.md">
<file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="510">
<caret line="427" column="54" selection-start-line="427" selection-start-column="54" selection-end-line="427" selection-end-column="54" />
<state relative-caret-position="513">
<caret line="144" column="3" lean-forward="true" selection-start-line="144" selection-start-column="3" selection-end-line="144" selection-end-column="3" />
<folding>
<element signature="e#0#20#0" expanded="true" />
<element signature="e#0#39#0" expanded="true" />
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<file leaf-file-name="README.md" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="120">
<caret line="8" column="25" lean-forward="true" selection-start-line="8" selection-start-column="25" selection-end-line="8" selection-end-column="25" />
<folding>
<element signature="e#0#20#0" expanded="true" />
</folding>
<state relative-caret-position="2955">
<caret line="197" column="29" selection-start-line="197" selection-start-column="18" selection-end-line="197" selection-end-column="29" />
</state>
</provider>
</entry>
@ -75,8 +81,8 @@
<file leaf-file-name="CHANGELOG.md" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="45">
<caret line="3" column="130" selection-start-line="3" selection-start-column="2" selection-end-line="3" selection-end-column="130" />
<state relative-caret-position="135">
<caret line="9" column="20" selection-start-line="9" selection-start-column="9" selection-end-line="9" selection-end-column="20" />
</state>
</provider>
</entry>
@ -92,22 +98,6 @@
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>getOp</find>
<find>onLoadError</find>
<find>StatefulWidget</find>
<find>onLoadResource</find>
<find>useShouldOverrideUrlLoading</find>
<find>):</find>
<find>InAppLocalhostServer</find>
<find>local</find>
<find>openWithSystemBrowser</find>
<find>__userAgent__</find>
<find>a</find>
<find>InApp</find>
<find>A [InApp</find>
<find>A `InApp</find>
<find>assets</find>
<find>Ui</find>
<find>postUrl</find>
<find>assert(</find>
<find>sNotEmpty()</find>
@ -122,6 +112,22 @@
<find>throw</find>
<find>InAppWeb</find>
<find>Boolean</find>
<find>[WebHistory.list]</find>
<find>open</find>
<find>Cannot laod</find>
<find>_throwIsNotOpened</find>
<find>takeS</find>
<find>Completer</find>
<find>args.putIfAbsent('isLocalFile', () =&gt; true);</find>
<find>args.putIfAbsent('isLocalFile', () =&gt;</find>
<find>Opens the</find>
<find>_isOpened</find>
<find>initialFile</find>
<find>onBrowserCreated</find>
<find>getUrl</find>
<find>onScrollChanged</find>
<find>openData</find>
<find>initialData</find>
</findStrings>
<replaceStrings>
<replace>activity.getPreferences(0)</replace>
@ -165,9 +171,9 @@
<option value="$PROJECT_DIR$/example/pubspec.yaml" />
<option value="$PROJECT_DIR$/pubspec.yaml" />
<option value="$PROJECT_DIR$/CHANGELOG.md" />
<option value="$PROJECT_DIR$/example/lib/main.dart" />
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
<option value="$PROJECT_DIR$/README.md" />
<option value="$PROJECT_DIR$/example/lib/main.dart" />
</list>
</option>
</component>
@ -183,18 +189,8 @@
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="PackagesPane" />
<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>
<pane id="ProjectPane">
<subPane>
<expand>
@ -202,6 +198,30 @@
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
<item name="ios" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
<item name="ios" type="462c0819:PsiDirectoryNode" />
<item name="Runner" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
<item name="example" type="462c0819:PsiDirectoryNode" />
<item name="lib" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="flutter_inappbrowser" type="b2602c69:ProjectViewProjectNode" />
<item name="flutter_inappbrowser" type="462c0819:PsiDirectoryNode" />
@ -212,7 +232,17 @@
</subPane>
<option name="show-excluded-files" value="false" />
</pane>
<pane id="PackagesPane" />
<pane id="Scope">
<subPane subId="Project Files">
<expand>
<path>
<item name="Root" type="cbb8eebc:String" user="Root" />
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
</path>
</expand>
<select />
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
@ -374,16 +404,15 @@
<layout>
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info active="true" anchor="bottom" id="Messages" order="12" visible="true" weight="0.23594266" />
<window_info anchor="right" id="Palette&#9;" order="9" />
<window_info id="Image Layers" order="7" />
<window_info id="Build Variants" order="3" side_tool="true" />
<window_info anchor="right" id="Capture Analysis" order="4" />
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5052169" side_tool="true" weight="0.34068358" />
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3276414" />
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49478307" weight="0.34068358" />
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32745314" />
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49478307" visible="true" weight="0.29437706" />
<window_info anchor="bottom" id="Version Control" order="9" />
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.1786108" />
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.49533224" weight="0.24696803" />
<window_info anchor="right" id="Flutter Outline" order="6" weight="0.32922077" />
<window_info anchor="bottom" id="Logcat" order="11" />
<window_info id="Captures" order="4" weight="0.32936507" />
@ -396,6 +425,7 @@
<window_info anchor="bottom" id="Debug" order="3" weight="0.34288865" />
<window_info id="Favorites" order="5" side_tool="true" />
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32938388" />
<window_info anchor="bottom" id="Messages" order="12" weight="0.23594266" />
<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="Assistant" order="8" visible="true" weight="0.3295129" />
@ -419,11 +449,6 @@
</breakpoint-manager>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/example/android/gradle.properties">
<provider selected="true" editor-type-id="text-editor">
<state />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppBrowser.h" />
<entry file="file://$PROJECT_DIR$/ios/Classes/InAppBrowser.m" />
<entry file="file://$PROJECT_DIR$/LICENSE">
@ -649,34 +674,24 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/ios/Runner/Info.plist">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="390">
<caret line="26" column="44" selection-start-line="26" selection-start-column="44" selection-end-line="26" selection-end-column="44" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="75">
<caret line="5" selection-start-line="5" selection-end-line="5" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="45">
<caret line="3" column="130" selection-start-line="3" selection-start-column="2" selection-end-line="3" selection-end-column="130" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="120">
<caret line="8" column="25" lean-forward="true" selection-start-line="8" selection-start-column="25" selection-end-line="8" selection-end-column="25" />
<folding>
<element signature="e#0#20#0" expanded="true" />
</folding>
<state relative-caret-position="30">
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="104">
<caret line="932" column="46" selection-start-line="932" selection-start-column="20" selection-end-line="932" selection-end-column="46" />
<state relative-caret-position="176">
<caret line="256" column="65" lean-forward="true" selection-start-line="256" selection-start-column="5" selection-end-line="256" selection-end-column="65" />
<folding>
<element signature="e#814#831#0" expanded="true" />
</folding>
@ -685,12 +700,24 @@
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="510">
<caret line="427" column="54" selection-start-line="427" selection-start-column="54" selection-end-line="427" selection-end-column="54" />
<state relative-caret-position="2955">
<caret line="197" column="29" selection-start-line="197" selection-start-column="18" selection-end-line="197" selection-end-column="29" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="135">
<caret line="9" column="20" selection-start-line="9" selection-start-column="9" selection-end-line="9" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="513">
<caret line="144" column="3" lean-forward="true" selection-start-line="144" selection-start-column="3" selection-end-line="144" selection-end-column="3" />
<folding>
<element signature="e#0#20#0" expanded="true" />
<element signature="e#0#39#0" expanded="true" />
<element signature="e#0#39#0" expanded="true" />
</folding>
</state>
</provider>

View File

@ -1,7 +1,18 @@
## 0.5.5
- added `getUrl` method for the `InAppWebViewController` class
- added `getTitle` method for the `InAppWebViewController` class
- added `getProgress` method for the `InAppWebViewController` class
- added `getFavicon` method for the `InAppWebViewController` class
- added `onScrollChanged` event for the `InAppWebViewController` and `InAppBrowser` class
- added `onBrowserCreated` event for the `InAppBrowser` class
- added `openData` method for the `InAppBrowser` class
- added `initialData` property for the `InAppWebView` widget
## 0.5.4
- added `WebHistory` and `WebHistoryItem` class
- added `getCopyBackForwardList`, `goBackOrForward`, `canGoBackOrForward` and `goTo` methods for `InAppWebView` and `InAppBrowser`
- added `getCopyBackForwardList`, `goBackOrForward`, `canGoBackOrForward` and `goTo` methods for the `InAppWebViewController` class
## 0.5.3
@ -10,8 +21,8 @@
## 0.5.2
- fixed some missing `result.success()` on Android and iOS
- added `postUrl()` method for `InAppWebView` and `InAppBrowser`
- added `loadData()` method for `InAppWebView` and `InAppBrowser`
- added `postUrl()` method for the `InAppWebViewController` class
- added `loadData()` method for the `InAppWebViewController` class
## 0.5.1

View File

@ -40,6 +40,8 @@ Classes:
- [InAppLocalhostServer](#inapplocalhostserver-class): This class allows you to create a simple server on `http://localhost:[port]/`. The default `port` value is `8080`.
- [CookieManager](#cookiemanager-class): Manages the cookies used by WebView instances. **NOTE for iOS**: available from iOS 11.0+.
See the online [docs](https://pub.dartlang.org/documentation/flutter_inappbrowser/latest/) to get the full documentation.
### `InAppWebView` class
Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree.
@ -193,6 +195,9 @@ Initial url that will be loaded.
#### InAppWebView.initialFile
Initial asset file that will be loaded. See `InAppWebView.loadFile()` for explanation.
#### InAppWebView.initialData
Initial `InAppWebViewInitialData` that will be loaded.
#### InAppWebView.initialHeaders
Initial headers that will be used.
@ -302,6 +307,49 @@ InAppWebView(
}
```
Event `onScrollChanged` fires when the `InAppWebView` scrolls.
`x` represents the current horizontal scroll origin in pixels.
`y` represents the current vertical scroll origin in pixels.
```dart
InAppWebView(
initialUrl: "https://flutter.io/",
onScrollChanged: (InAppWebViewController controller, int x, int y) {}
}
```
#### Future\<String\> InAppWebViewController.getUrl
Gets the URL for the current page.
This is not always the same as the URL passed to `InAppWebView.onLoadStarted` because although the load for that URL has begun, the current page may not have changed.
```dart
inAppWebViewController.getUrl();
```
#### Future\<String\> InAppWebViewController.getTitle
Gets the title for the current page.
```dart
inAppWebViewController.getTitle();
```
#### Future\<int\> InAppWebViewController.getProgress
Gets the progress for the current page. The progress value is between 0 and 100.
```dart
inAppWebViewController.getProgress();
```
#### Future\<List\<int\>\> InAppWebViewController.getFavicon
Gets the favicon for the current page.
```dart
inAppWebViewController.getFavicon();
```
#### Future\<void\> InAppWebViewController.loadUrl
Loads the given `url` with optional `headers` specified as a map from name to value.
@ -744,7 +792,7 @@ inAppBrowser.open({String url = "about:blank", Map<String, String> headers = con
#### Future\<void\> InAppBrowser.openFile
Opens the giver `assetFilePath` file in a new `InAppBrowser` instance. The other arguments are the same of `InAppBrowser.open()`.
Opens the given `assetFilePath` file in a new `InAppBrowser` instance. The other arguments are the same of `InAppBrowser.open()`.
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!
@ -778,6 +826,16 @@ inAppBrowser.openFile("assets/index.html");
inAppBrowser.openFile(String assetFilePath, {Map<String, String> headers = const {}, Map<String, dynamic> options = const {}});
```
#### static Future\<void\> InAppBrowser.openData
Opens a new `InAppBrowser` instance with `data` as a content, using `baseUrl` as the base URL for it.
The `mimeType` parameter specifies the format of the data.
The `encoding` parameter specifies the encoding of the data.
```dart
InAppBrowser.openData(String data, {String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", Map<String, dynamic> options = const {}});
```
#### static Future\<void\> InAppBrowser.openWithSystemBrowser
This is a static method that opens an `url` in the system browser. You wont be able to use the `InAppBrowser` methods here!
@ -841,6 +899,14 @@ inAppBrowser.isOpened();
#### Events
Event `onBrowserCreated` fires when the `InAppBrowser` is created.
```dart
@override
void onBrowserCreated() {
}
```
Event `onLoadStart` fires when the `InAppBrowser` starts to load an `url`.
```dart
@override
@ -911,6 +977,17 @@ Event `onLoadResource` fires when the `InAppBrowser` webview loads a resource.
}
```
Event `onScrollChanged` fires when the `InAppBrowser` webview scrolls.
`x` represents the current horizontal scroll origin in pixels.
`y` represents the current vertical scroll origin in pixels.
```dart
@override
void onScrollChanged(int x, int y) {
}
```
### `ChromeSafariBrowser` class
[Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android / [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.

View File

@ -40,12 +40,19 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
String initialUrl = (String) params.get("initialUrl");
String initialFile = (String) params.get("initialFile");
Map<String, String> initialData = (Map<String, String>) params.get("initialData");
Map<String, String> initialHeaders = (Map<String, String>) params.get("initialHeaders");
HashMap<String, Object> initialOptions = (HashMap<String, Object>) params.get("initialOptions");
InAppWebViewOptions options = new InAppWebViewOptions();
options.parse(initialOptions);
webView = new InAppWebView(context, this, id, options);
webView.prepare();
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
if (initialFile != null) {
try {
initialUrl = Util.getUrlAsset(registrar, initialFile);
@ -56,13 +63,15 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
}
}
webView = new InAppWebView(context, this, id, options);
webView.prepare();
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
webView.loadUrl(initialUrl, initialHeaders);
if (initialData != null) {
String data = initialData.get("data");
String mimeType = initialData.get("mimeType");
String encoding = initialData.get("encoding");
String baseUrl = initialData.get("baseUrl");
webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, null);
}
else
webView.loadUrl(initialUrl, initialHeaders);
}
@Override
@ -76,6 +85,15 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
String jsWrapper;
String urlFile;
switch (call.method) {
case "getUrl":
result.success((webView != null) ? webView.getUrl() : null);
break;
case "getTitle":
result.success((webView != null) ? webView.getTitle() : null);
break;
case "getProgress":
result.success((webView != null) ? webView.getProgress() : null);
break;
case "loadUrl":
if (webView != null)
webView.loadUrl(call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);

View File

@ -52,7 +52,7 @@ public class InAppBrowserActivity extends AppCompatActivity {
Bundle b = getIntent().getExtras();
uuid = b.getString("uuid");
String url = b.getString("url");
HashMap<String, Object> optionsMap = (HashMap<String, Object>) b.getSerializable("options");
options = new InAppBrowserOptions();
@ -62,16 +62,29 @@ public class InAppBrowserActivity extends AppCompatActivity {
webViewOptions.parse(optionsMap);
webView.options = webViewOptions;
headers = (HashMap<String, String>) b.getSerializable("headers");
InAppBrowserFlutterPlugin.webViewActivities.put(uuid, this);
actionBar = getSupportActionBar();
prepareView();
webView.loadUrl(url, headers);
//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");
Boolean isData = b.getBoolean("isData");
if (!isData) {
headers = (HashMap<String, String>) b.getSerializable("headers");
String url = b.getString("url");
webView.loadUrl(url, headers);
}
else {
String data = b.getString("data");
String mimeType = b.getString("mimeType");
String encoding = b.getString("encoding");
String baseUrl = b.getString("baseUrl");
webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, null);
}
Map<String, Object> obj = new HashMap<>();
obj.put("uuid", uuid);
InAppBrowserFlutterPlugin.channel.invokeMethod("onBrowserCreated", obj);
}
@ -164,6 +177,24 @@ public class InAppBrowserActivity extends AppCompatActivity {
return true;
}
public String getUrl() {
if (webView != null)
return webView.getUrl();
return null;
}
public String getWebViewTitle() {
if (webView != null)
return webView.getTitle();
return null;
}
public Integer getProgress() {
if (webView != null)
return webView.getProgress();
return null;
}
public void loadUrl(String url, MethodChannel.Result result) {
if (webView != null) {
webView.loadUrl(url, result);

View File

@ -97,71 +97,97 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
switch (call.method) {
case "open":
final String url_final = call.argument("url").toString();
boolean isData = (boolean) call.argument("isData");
if (!isData) {
final String url_final = call.argument("url").toString();
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
final Map<String, String> headers = (Map<String, String>) call.argument("headers");
final Map<String, String> headers = (Map<String, String>) call.argument("headers");
Log.d(LOG_TAG, "use Chrome Custom Tabs = " + useChromeSafariBrowser);
Log.d(LOG_TAG, "use Chrome Custom Tabs = " + useChromeSafariBrowser);
this.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
this.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (useChromeSafariBrowser) {
if (useChromeSafariBrowser) {
final String uuidFallback = (String) call.argument("uuidFallback");
final String uuidFallback = (String) call.argument("uuidFallback");
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
final HashMap<String, Object> optionsFallback = (HashMap<String, Object>) call.argument("optionsFallback");
final HashMap<String, Object> optionsFallback = (HashMap<String, Object>) call.argument("optionsFallback");
open(uuid, uuidFallback, url_final, options, headers, true, optionsFallback, result);
} else {
String url = url_final;
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
final boolean isLocalFile = (boolean) call.argument("isLocalFile");
final boolean openWithSystemBrowser = (boolean) call.argument("openWithSystemBrowser");
if (isLocalFile) {
// check if the asset file exists
try {
url = Util.getUrlAsset(registrar, url);
} catch (IOException e) {
e.printStackTrace();
result.error(LOG_TAG, url + " asset file cannot be found!", e);
return;
}
}
// SYSTEM
if (openWithSystemBrowser) {
Log.d(LOG_TAG, "in system");
openExternal(url, result);
open(uuid, uuidFallback, url_final, options, headers, true, optionsFallback, result);
} else {
//Load the dialer
if (url.startsWith(WebView.SCHEME_TEL)) {
String url = url_final;
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
final boolean isLocalFile = (boolean) call.argument("isLocalFile");
final boolean openWithSystemBrowser = (boolean) call.argument("openWithSystemBrowser");
if (isLocalFile) {
// check if the asset file exists
try {
Log.d(LOG_TAG, "loading in dialer");
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
url = Util.getUrlAsset(registrar, url);
} catch (IOException e) {
e.printStackTrace();
result.error(LOG_TAG, url + " asset file cannot be found!", e);
return;
}
}
// load in InAppBrowserFlutterPlugin
else {
Log.d(LOG_TAG, "loading in InAppBrowserFlutterPlugin");
open(uuid, null, url, options, headers, false, null, result);
// SYSTEM
if (openWithSystemBrowser) {
Log.d(LOG_TAG, "in system");
openExternal(url, result);
} else {
//Load the dialer
if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Log.d(LOG_TAG, "loading in dialer");
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
}
}
// load in InAppBrowserFlutterPlugin
else {
Log.d(LOG_TAG, "loading in InAppBrowserFlutterPlugin");
open(uuid, null, url, options, headers, false, null, result);
}
}
}
}
}
});
});
}
else {
this.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
String data = call.argument("data").toString();
String mimeType = call.argument("mimeType").toString();
String encoding = call.argument("encoding").toString();
String baseUrl = call.argument("baseUrl").toString();
openData(uuid, options, data, mimeType, encoding, baseUrl);
result.success(true);
}
});
}
break;
case "getUrl":
result.success(getUrl(uuid));
break;
case "getTitle":
result.success(getTitle(uuid));
break;
case "getProgress":
result.success(getProgress(uuid));
break;
case "loadUrl":
loadUrl(uuid, call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
@ -370,7 +396,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
Intent intent = null;
Bundle extras = new Bundle();
extras.putString("url", url);
extras.putBoolean("isData", false);
extras.putString("uuid", uuid);
extras.putSerializable("options", options);
extras.putSerializable("headers", (Serializable) headers);
@ -408,6 +434,43 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
result.error(LOG_TAG, "No WebView fallback declared.", null);
}
public void openData(String uuid, HashMap<String, Object> options, String data, String mimeType, String encoding, String baseUrl) {
Intent intent = new Intent(activity, InAppBrowserActivity.class);
Bundle extras = new Bundle();
extras.putBoolean("isData", true);
extras.putString("uuid", uuid);
extras.putSerializable("options", options);
extras.putString("data", data);
extras.putString("mimeType", mimeType);
extras.putString("encoding", encoding);
extras.putString("baseUrl", baseUrl);
intent.putExtras(extras);
activity.startActivity(intent);
}
private String getUrl(String uuid) {
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
if (inAppBrowserActivity != null)
return inAppBrowserActivity.getUrl();
return null;
}
private String getTitle(String uuid) {
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
if (inAppBrowserActivity != null)
return inAppBrowserActivity.getWebViewTitle();
return null;
}
private Integer getProgress(String uuid) {
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
if (inAppBrowserActivity != null)
return inAppBrowserActivity.getProgress();
return null;
}
public void loadUrl(String uuid, String url, Map<String, String> headers, Result result) {
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
if (inAppBrowserActivity != null) {

View File

@ -18,6 +18,7 @@ import android.webkit.WebView;
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
import com.pichillilorenzo.flutter_inappbrowser.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappbrowser.Util;
@ -431,4 +432,26 @@ public class InAppWebView extends WebView {
return result;
}
@Override
protected void onScrollChanged (int l,
int t,
int oldl,
int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
float scale = getResources().getDisplayMetrics().density;
int x = (int) (l/scale);
int y = (int) (t/scale);
Map<String, Object> obj = new HashMap<>();
if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("x", x);
obj.put("y", y);
getChannel().invokeMethod("onScrollChanged", obj);
}
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppBrowserFlutterPlugin.channel : flutterWebView.channel;
}
}

View File

@ -4,6 +4,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
class MyInAppBrowser extends InAppBrowser {
@override
Future onBrowserCreated() async {
print("\n\nBrowser Ready!\n\n");
}
@override
Future onLoadStart(String url) async {
print("\n\nStarted $url\n\n");
@ -16,6 +21,7 @@ class MyInAppBrowser extends InAppBrowser {
Future onLoadStop(String url) async {
print("\n\nStopped $url\n\n");
// print(base64.encode(await this.webViewController.getFavicon()));
// WebHistory history = await this.webViewController.getCopyBackForwardList();
// print(history.list.length);
// print(history.currentIndex);
@ -23,6 +29,7 @@ class MyInAppBrowser extends InAppBrowser {
// for(WebHistoryItem item in history.list) {
// print(item.title);
// }
//
// print(await this.webViewController.canGoBackOrForward(1));
// if (await this.webViewController.canGoBackOrForward(-2)) {
@ -132,6 +139,11 @@ class MyInAppBrowser extends InAppBrowser {
// this.webViewController.injectStyleFile("https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css");
}
@override
Future onScrollChanged(int x, int y) async {
// print(x.toString() + " " + y.toString());
}
@override
void onLoadError(String url, int code, String message) {
print("\n\nCan't load $url.. Error: $message\n\n");
@ -308,11 +320,13 @@ class _MyAppState extends State<MyApp> {
// await CookieManager.setCookie("https://flutter.io/", "my_cookie2", "cookieValue2", domain: "flutter.io", expiresDate: 1540838864611);
// await CookieManager.setCookie("https://flutter.io/", "my_cookie", "cookieValue", domain: "flutter.io", expiresDate: 1540838864611);
// await inAppBrowserFallback.openData("<html><head><title>Data example</title></head><body><p>This is a \"p\" tag</p></body></html>", options: {});
await inAppBrowserFallback.open(url: "https://flutter.io/", options: {
//"useOnLoadResource": true,
//"hidden": true,
//"toolbarTopFixedTitle": "Fixed title",
"useShouldOverrideUrlLoading": true
"useShouldOverrideUrlLoading": true,
//"hideUrlBar": true,
//"toolbarTop": false,
//"toolbarBottom": false
@ -382,6 +396,7 @@ class _MyAppState extends State<MyApp> {
// ),
// child: InAppWebView(
// initialUrl: "https://flutter.io/",
// //initialData: InAppWebViewInitialData("<html><head><title>Data example</title></head><body><p>This is a \"p\" tag</p></body></html>"),
// initialHeaders: {
//
// },

View File

@ -20,6 +20,7 @@
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/ios/Flutter/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
</content>
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -137,7 +137,7 @@ class InAppWebView_IBWrapper: InAppWebView {
}
}
class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
@IBOutlet var webView: InAppWebView_IBWrapper!
@IBOutlet var closeButton: UIButton!
@ -161,6 +161,10 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
var browserOptions: InAppBrowserOptions?
var webViewOptions: InAppWebViewOptions?
var initHeaders: [String: String]?
var initData: String?
var initMimeType: String?
var initEncoding: String?
var initBaseUrl: String?
var isHidden = false
var uuid: String = ""
var WKNavigationMap: [String: [String: Any]] = [:]
@ -186,6 +190,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
webView.uiDelegate = self
webView.navigationDelegate = self
webView.scrollView.delegate = self
urlField.delegate = self
urlField.text = self.currentURL?.absoluteString
@ -211,8 +216,14 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
spinner.isHidden = false
spinner.stopAnimating()
loadUrl(url: self.currentURL!, headers: self.initHeaders)
if self.initData == nil {
loadUrl(url: self.currentURL!, headers: self.initHeaders)
}
else {
loadData(data: initData!, mimeType: initMimeType!, encoding: initEncoding!, baseUrl: initBaseUrl!)
}
navigationDelegate?.onBrowserCreated(uuid: uuid, webView: webView)
}
// Prevent crashes on closing windows
@ -369,10 +380,11 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
currentURL = url
updateUrlTextField(url: (currentURL?.absoluteString)!)
if headers != nil {
if let mutableRequest = (request as NSURLRequest).mutableCopy() as? NSMutableURLRequest {
for (key, value) in headers! {
request.setValue(value, forHTTPHeaderField: key)
mutableRequest.setValue(value, forHTTPHeaderField: key)
}
request = mutableRequest as URLRequest
}
webView.load(request)
@ -582,6 +594,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
currentURL = url
updateUrlTextField(url: (url.absoluteString))
}
}
@ -693,6 +706,14 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if navigationDelegate != nil {
let x = Int(scrollView.contentOffset.x / scrollView.contentScaleFactor)
let y = Int(scrollView.contentOffset.y / scrollView.contentScaleFactor)
navigationDelegate?.onScrollChanged(uuid: self.uuid, webView: webView, x: x, y: y)
}
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name.starts(with: "console") {
var messageLevel = "LOG"
@ -960,4 +981,5 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
return result;
}
}

View File

@ -10,6 +10,8 @@ import WebKit
public class InAppWebView: WKWebView {
var historyOffset = 0
public func goBackOrForward(steps: Int) {
if canGoBackOrForward(steps: steps) {
if (steps > 0) {

View File

@ -71,6 +71,31 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
case "open":
self.open(uuid: uuid, arguments: arguments!, result: result)
break
case "getUrl":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController!.webView.url?.absoluteString)
}
else {
result(nil)
}
break
case "getTitle":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController!.webView.title)
}
else {
result(nil)
}
break
case "getProgress":
if let webViewController = self.webViewControllers[uuid] {
let progress = Int(webViewController!.webView.estimatedProgress * 100)
result(progress)
}
else {
result(nil)
}
break
case "loadUrl":
self.loadUrl(uuid: uuid, arguments: arguments!, result: result)
break
@ -97,19 +122,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "reload":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.reload()
webViewController!.reload()
}
result(true)
break
case "goBack":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goBack()
webViewController!.goBack()
}
result(true)
break
case "canGoBack":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoBack() ?? false)
result(webViewController!.canGoBack())
}
else {
result(false)
@ -117,13 +142,13 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "goForward":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goForward()
webViewController!.goForward()
}
result(true)
break
case "canGoForward":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoForward() ?? false)
result(webViewController!.canGoForward())
}
else {
result(false)
@ -132,14 +157,14 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
case "goBackOrForward":
if let webViewController = self.webViewControllers[uuid] {
let steps = arguments!["steps"] as! Int
webViewController?.goBackOrForward(steps: steps)
webViewController!.goBackOrForward(steps: steps)
}
result(true)
break
case "canGoBackOrForward":
if let webViewController = self.webViewControllers[uuid] {
let steps = arguments!["steps"] as! Int
result(webViewController?.canGoBackOrForward(steps: steps) ?? false)
result(webViewController!.canGoBackOrForward(steps: steps))
}
else {
result(false)
@ -147,7 +172,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "isLoading":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.webView.isLoading ?? false) == true)
result(webViewController!.webView.isLoading == true)
}
else {
result(false)
@ -155,13 +180,13 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "stopLoading":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.webView.stopLoading()
webViewController!.webView.stopLoading()
}
result(true)
break
case "isHidden":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.isHidden ?? false) == true)
result(webViewController!.isHidden == true)
}
else {
result(false)
@ -184,7 +209,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "takeScreenshot":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.takeScreenshot(completionHandler: { (screenshot) -> Void in
webViewController!.takeScreenshot(completionHandler: { (screenshot) -> Void in
result(screenshot)
})
}
@ -236,47 +261,60 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
}
public func open(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
let url: String = (arguments["url"] as? String)!
let isData: Bool = (arguments["isData"] as? Bool)!
let headers = (arguments["headers"] as? [String: String])!
var absoluteUrl = URL(string: url)?.absoluteURL
if !isData {
let url: String = (arguments["url"] as? String)!
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)!
let headers = (arguments["headers"] as? [String: String])!
var absoluteUrl = URL(string: url)?.absoluteURL
if useChromeSafariBrowser {
let uuidFallback = (arguments["uuidFallback"] as? String)!
let safariOptions = (arguments["options"] as? [String: Any])!
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)!
let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
if useChromeSafariBrowser {
let uuidFallback = (arguments["uuidFallback"] as? String)!
let safariOptions = (arguments["options"] as? [String: Any])!
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result);
let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result);
}
else {
let options = (arguments["options"] as? [String: Any])!
let isLocalFile = (arguments["isLocalFile"] as? Bool)!
var openWithSystemBrowser = (arguments["openWithSystemBrowser"] as? Bool)!
if isLocalFile {
let key = SwiftFlutterPlugin.registrar!.lookupKey(forAsset: url)
let assetURL = Bundle.main.url(forResource: key, withExtension: nil)
if assetURL == nil {
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url + " asset file cannot be found!", details: nil))
return
}
absoluteUrl = assetURL!
}
if isSystemUrl(absoluteUrl!) {
openWithSystemBrowser = true
}
if (openWithSystemBrowser) {
open(inSystem: absoluteUrl!, result: result)
}
else {
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil, result: result)
}
}
}
else {
let options = (arguments["options"] as? [String: Any])!
let isLocalFile = (arguments["isLocalFile"] as? Bool)!
var openWithSystemBrowser = (arguments["openWithSystemBrowser"] as? Bool)!
if isLocalFile {
let key = SwiftFlutterPlugin.registrar!.lookupKey(forAsset: url)
let assetURL = Bundle.main.url(forResource: key, withExtension: nil)
if assetURL == nil {
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url + " asset file cannot be found!", details: nil))
return
}
absoluteUrl = assetURL!
}
if isSystemUrl(absoluteUrl!) {
openWithSystemBrowser = true
}
if (openWithSystemBrowser) {
open(inSystem: absoluteUrl!, result: result)
}
else {
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil, result: result)
}
let data = (arguments["data"] as? String)!
let mimeType = (arguments["mimeType"] as? String)!
let encoding = (arguments["encoding"] as? String)!
let baseUrl = (arguments["baseUrl"] as? String)!
open(uuid: uuid, options: options, data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
result(true)
}
}
@ -406,6 +444,71 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
result(true)
}
func open(uuid: String, options: [String: Any], data: String, mimeType: String, encoding: String, baseUrl: String) {
var uuid = uuid
if self.webViewControllers[uuid] != nil {
close(uuid: uuid)
}
if self.previousStatusBarStyle == -1 {
self.previousStatusBarStyle = UIApplication.shared.statusBarStyle.rawValue
}
if !(self.tmpWindow != nil) {
let frame: CGRect = UIScreen.main.bounds
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
let webViewOptions: InAppWebViewOptions
browserOptions = InAppBrowserOptions()
browserOptions.parse(options: options)
webViewOptions = InAppWebViewOptions()
webViewOptions.parse(options: options)
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppBrowserFlutterPlugin.self))
let vc = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID)
self.webViewControllers[uuid] = vc as? InAppBrowserWebViewController
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
webViewController.uuid = uuid
webViewController.browserOptions = browserOptions
webViewController.webViewOptions = webViewOptions
webViewController.isHidden = browserOptions.hidden
webViewController.tmpWindow = tmpWindow
webViewController.initData = data
webViewController.initMimeType = mimeType
webViewController.initEncoding = encoding
webViewController.initBaseUrl = baseUrl
webViewController.navigationDelegate = self
if browserOptions.hidden {
webViewController.view.isHidden = true
tmpController.present(webViewController, animated: false, completion: {() -> Void in
webViewController.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
})
webViewController.presentingViewController?.dismiss(animated: false, completion: {() -> Void in
self.tmpWindow?.windowLevel = 0.0
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
})
}
else {
tmpController.present(webViewController, animated: true, completion: {() -> Void in
webViewController.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
})
}
}
public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
if let url = arguments["url"] as? String {
@ -595,6 +698,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
injectDeferredObject(uuid: uuid, source: arguments["urlFile"] as! String, withWrapper: jsWrapper, result: result)
}
func onBrowserCreated(uuid: String, webView: WKWebView) {
if let webViewController = self.webViewControllers[uuid] {
channel.invokeMethod("onBrowserCreated", arguments: ["uuid": uuid])
}
}
func onLoadStart(uuid: String, webView: WKWebView) {
if let webViewController = self.webViewControllers[uuid] {
let url: String = webViewController!.currentURL!.absoluteString
@ -651,6 +760,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
}
}
func onScrollChanged(uuid: String, webView: WKWebView, x: Int, y: Int) {
if let webViewController = self.webViewControllers[uuid] {
channel.invokeMethod("onScrollChanged", arguments: ["uuid": uuid, "x": x, "y": y])
}
}
func onExit(uuid: String) {
channel.invokeMethod("onExit", arguments: ["uuid": uuid])
}

View File

@ -127,6 +127,10 @@ class InAppBrowser {
Future<dynamic> _handleMethod(MethodCall call) async {
switch(call.method) {
case "onBrowserCreated":
this._isOpened = true;
onBrowserCreated();
break;
case "onExit":
this._isOpened = false;
onExit();
@ -199,12 +203,12 @@ class InAppBrowser {
args.putIfAbsent('options', () => options);
args.putIfAbsent('openWithSystemBrowser', () => false);
args.putIfAbsent('isLocalFile', () => false);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('useChromeSafariBrowser', () => false);
await _ChannelManager.channel.invokeMethod('open', args);
this._isOpened = true;
}
///Opens the giver [assetFilePath] file in a new [InAppBrowser] instance. The other arguments are the same of [InAppBrowser.open()].
///Opens the given [assetFilePath] file in a new [InAppBrowser] instance. The other arguments are the same of [InAppBrowser.open()].
///
///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!
///
@ -243,9 +247,28 @@ class InAppBrowser {
args.putIfAbsent('options', () => options);
args.putIfAbsent('openWithSystemBrowser', () => false);
args.putIfAbsent('isLocalFile', () => true);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('useChromeSafariBrowser', () => false);
await _ChannelManager.channel.invokeMethod('open', args);
}
///Opens a new [InAppBrowser] instance with [data] as a content, using [baseUrl] as the base URL for it.
///The [mimeType] parameter specifies the format of the data.
///The [encoding] parameter specifies the encoding of the data.
Future<void> openData(String data, {String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank", Map<String, dynamic> options = const {}}) async {
assert(data != null);
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid);
args.putIfAbsent('options', () => options);
args.putIfAbsent('data', () => data);
args.putIfAbsent('mimeType', () => mimeType);
args.putIfAbsent('encoding', () => encoding);
args.putIfAbsent('baseUrl', () => baseUrl);
args.putIfAbsent('openWithSystemBrowser', () => false);
args.putIfAbsent('isLocalFile', () => false);
args.putIfAbsent('isData', () => true);
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. You wont be able to use the [InAppBrowser] methods here!
@ -256,6 +279,7 @@ class InAppBrowser {
args.putIfAbsent('url', () => url);
args.putIfAbsent('headers', () => {});
args.putIfAbsent('isLocalFile', () => false);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('openWithSystemBrowser', () => true);
args.putIfAbsent('useChromeSafariBrowser', () => false);
return await _ChannelManager.channel.invokeMethod('open', args);
@ -319,6 +343,11 @@ class InAppBrowser {
return this._isOpened;
}
///Event fires when the [InAppBrowser] is created.
void onBrowserCreated() {
}
///Event fires when the [InAppBrowser] starts to load an [url].
void onLoadStart(String url) {
@ -365,6 +394,13 @@ class InAppBrowser {
}
///Event fires when the [InAppBrowser] webview scrolls.
///[x] represents the current horizontal scroll origin in pixels.
///[y] represents the current vertical scroll origin in pixels.
void onScrollChanged(int x, int y) {
}
void _throwIsAlreadyOpened({String message = ''}) {
if (this.isOpened()) {
throw Exception(['Error: ${ (message.isEmpty) ? '' : message + ' '}The browser is already opened.']);
@ -496,6 +532,28 @@ typedef void onWebViewProgressChangedCallback(InAppWebViewController controller,
typedef void onWebViewConsoleMessageCallback(InAppWebViewController controller, ConsoleMessage consoleMessage);
typedef void shouldOverrideUrlLoadingCallback(InAppWebViewController controller, String url);
typedef void onWebViewLoadResourceCallback(InAppWebViewController controller, WebResourceResponse response, WebResourceRequest request);
typedef void onWebViewScrollChangedCallback(InAppWebViewController controller, int x, int y);
///Initial [data] as a content for an [InAppWebView] instance, using [baseUrl] as the base URL for it.
///The [mimeType] property specifies the format of the data.
///The [encoding] property specifies the encoding of the data.
class InAppWebViewInitialData {
String data;
String mimeType;
String encoding;
String baseUrl;
InAppWebViewInitialData(this.data, {this.mimeType = "text/html", this.encoding = "utf8", this.baseUrl = "about:blank"});
Map<String, String> toMap() {
return {
"data": data,
"mimeType": mimeType,
"encoding": encoding,
"baseUrl": baseUrl
};
}
}
///InAppWebView Widget class.
///
@ -563,10 +621,17 @@ class InAppWebView extends StatefulWidget {
///**NOTE only for iOS**: In some cases, the [response.data] of a [response] with `text/assets` encoding could be empty.
final onWebViewLoadResourceCallback onLoadResource;
///Event fires when the [InAppWebView] scrolls.
///[x] represents the current horizontal scroll origin in pixels.
///[y] represents the current vertical scroll origin in pixels.
final onWebViewScrollChangedCallback onScrollChanged;
///Initial url that will be loaded.
final String initialUrl;
///Initial asset file that will be loaded. See [InAppWebView.loadFile()] for explanation.
final String initialFile;
///Initial [InAppWebViewInitialData] that will be loaded.
final InAppWebViewInitialData initialData;
///Initial headers that will be used.
final Map<String, String> initialHeaders;
///Initial options that will be used.
@ -577,6 +642,7 @@ class InAppWebView extends StatefulWidget {
Key key,
this.initialUrl = "about:blank",
this.initialFile,
this.initialData,
this.initialHeaders = const {},
this.initialOptions = const {},
this.onWebViewCreated,
@ -587,6 +653,7 @@ class InAppWebView extends StatefulWidget {
this.onProgressChanged,
this.shouldOverrideUrlLoading,
this.onLoadResource,
this.onScrollChanged,
this.gestureRecognizers,
}) : super(key: key);
@ -620,6 +687,7 @@ class _InAppWebViewState extends State<InAppWebView> {
creationParams: <String, dynamic>{
'initialUrl': widget.initialUrl,
'initialFile': widget.initialFile,
'initialData': widget.initialData?.toMap(),
'initialHeaders': widget.initialHeaders,
'initialOptions': widget.initialOptions
},
@ -754,6 +822,14 @@ class InAppWebViewController {
else
_inAppBrowser.onConsoleMessage(ConsoleMessage(sourceURL, lineNumber, message, messageLevel));
break;
case "onScrollChanged":
int x = call.arguments["x"];
int y = call.arguments["y"];
if (_widget != null)
_widget.onScrollChanged(this, x, y);
else
_inAppBrowser.onScrollChanged(x, y);
break;
case "onCallJsHandler":
String handlerName = call.arguments["handlerName"];
List<dynamic> args = jsonDecode(call.arguments["args"]);
@ -768,6 +844,57 @@ class InAppWebViewController {
}
}
///Gets the URL for the current page.
///This is not always the same as the URL passed to [InAppWebView.onLoadStarted] because although the load for that URL has begun, the current page may not have changed.
Future<String> getUrl() async {
Map<String, dynamic> args = <String, dynamic>{};
if (_inAppBrowserUuid != null) {
_inAppBrowser._throwIsNotOpened();
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
}
return await _channel.invokeMethod('getUrl', args);
}
///Gets the title for the current page.
Future<String> getTitle() async {
Map<String, dynamic> args = <String, dynamic>{};
if (_inAppBrowserUuid != null) {
_inAppBrowser._throwIsNotOpened();
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
}
return await _channel.invokeMethod('getTitle', args);
}
///Gets the progress for the current page. The progress value is between 0 and 100.
Future<int> getProgress() async {
Map<String, dynamic> args = <String, dynamic>{};
if (_inAppBrowserUuid != null) {
_inAppBrowser._throwIsNotOpened();
args.putIfAbsent('uuid', () => _inAppBrowserUuid);
}
return await _channel.invokeMethod('getProgress', args);
}
///Gets the favicon for the current page.
Future<List<int>> getFavicon() async {
var completer = new Completer<List<int>>();
var faviconData = new List<int>();
HttpClient client = new HttpClient();
var url = Uri.parse(await getUrl());
// solution found here: https://stackoverflow.com/a/15750809/4637638
var faviconUrl = Uri.parse("https://plus.google.com/_/favicon?domain_url=" + url.scheme + "://" + url.host);
client.getUrl(faviconUrl).then((HttpClientRequest request) {
return request.close();
}).then((HttpClientResponse response) {
response.listen((List<int> data) {
faviconData = data;
}, onDone: () => completer.complete(faviconData));
});
return completer.future;
}
///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 {
assert(url != null && url.isNotEmpty);

View File

@ -1,6 +1,6 @@
name: flutter_inappbrowser
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
version: 0.5.4
version: 0.5.5
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser