README.md 23.8 KB
Newer Older
pichillilorenzo's avatar
pichillilorenzo committed
1
# Flutter InAppBrowser Plugin [![Share on Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Flutter%20InAppBrowser%20plugin!&url=https://github.com/pichillilorenzo/flutter_inappbrowser&hashtags=flutter,flutterio,dart,dartlang,webview) [![Share on Facebook](https://img.shields.io/badge/share-facebook-blue.svg?longCache=true&style=flat&colorB=%234267b2)](https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/pichillilorenzo/flutter_inappbrowser)
pichillilorenzo's avatar
pichillilorenzo committed
2 3

[![Pub](https://img.shields.io/pub/v/flutter_inappbrowser.svg)](https://pub.dartlang.org/packages/flutter_inappbrowser)
pichillilorenzo's avatar
pichillilorenzo committed
4
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](/LICENSE)
pichillilorenzo's avatar
pichillilorenzo committed
5 6 7

[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/LorenzoPichilli)
[![Donate to this project using Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://www.patreon.com/bePatron?u=9269604)
pichillilorenzo's avatar
pichillilorenzo committed
8 9

A Flutter plugin that allows you to open an in-app browser window.
10
This plugin is inspired by the popular [cordova-plugin-inappbrowser](https://github.com/apache/cordova-plugin-inappbrowser)!
pichillilorenzo's avatar
pichillilorenzo committed
11 12 13 14 15 16 17 18 19 20 21 22

## Getting Started

For help getting started with Flutter, view our online
[documentation](https://flutter.io/).

For help on editing plugin code, view the [documentation](https://flutter.io/developing-packages/#edit-plugin-package).

## Installation
First, add `flutter_inappbrowser` as a [dependency in your pubspec.yaml file](https://flutter.io/using-packages/).

## Usage
23 24 25 26 27 28 29
Classes:
- [InAppBrowser](#inappbrowser): Native WebView.
- [ChromeSafariBrowser](#chromesafaribrowser): [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.

Screenshots [here](#screenshots).

### `InAppBrowser` class
30 31
Native WebView.

pichillilorenzo's avatar
pichillilorenzo committed
32 33 34
Create a Class that extends the `InAppBrowser` Class in order to override the callbacks to manage the browser events.
Example:
```dart
pichillilorenzo's avatar
pichillilorenzo committed
35
import 'package:flutter/material.dart';
pichillilorenzo's avatar
pichillilorenzo committed
36 37 38
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';

class MyInAppBrowser extends InAppBrowser {
pichillilorenzo's avatar
pichillilorenzo committed
39

pichillilorenzo's avatar
pichillilorenzo committed
40 41 42 43
  @override
  void onLoadStart(String url) {
    print("\n\nStarted $url\n\n");
  }
pichillilorenzo's avatar
pichillilorenzo committed
44

pichillilorenzo's avatar
pichillilorenzo committed
45
  @override
pichillilorenzo's avatar
pichillilorenzo committed
46
  Future onLoadStop(String url) async {
pichillilorenzo's avatar
pichillilorenzo committed
47
    print("\n\nStopped $url\n\n");
48 49 50 51

    // call a javascript message handler
    await this.injectScriptCode("window.flutter_inappbrowser.callHandler('handlerNameTest', 1, 5,'string', {'key': 5}, [4,6,8]);");

52 53
    // print body html
    print(await this.injectScriptCode("document.body.innerHTML"));
54 55 56 57 58

    // console messages
    await this.injectScriptCode("console.log({'testObject': 5});"); // the message will be: [object Object]
    await this.injectScriptCode("console.log('testObjectStringify', JSON.stringify({'testObject': 5}));"); // the message will be: testObjectStringify {"testObject": 5}
    await this.injectScriptCode("console.error('testError', false);"); // the message will be: testError false
59 60 61 62 63 64 65 66 67 68 69 70 71 72
    
    // add jquery library and custom javascript
    await this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js");
    this.injectScriptCode("""
      \$( "body" ).html( "Next Step..." )
    """);
    
    // add custom css
    this.injectStyleCode("""
    body {
      background-color: #3c3c3c !important;
    }
    """);
    this.injectStyleFile("https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css");
pichillilorenzo's avatar
pichillilorenzo committed
73
  }
pichillilorenzo's avatar
pichillilorenzo committed
74

pichillilorenzo's avatar
pichillilorenzo committed
75
  @override
76
  void onLoadError(String url, int code, String message) {
pichillilorenzo's avatar
pichillilorenzo committed
77 78
    print("\n\nCan't load $url.. Error: $message\n\n");
  }
pichillilorenzo's avatar
pichillilorenzo committed
79

pichillilorenzo's avatar
pichillilorenzo committed
80 81 82 83
  @override
  void onExit() {
    print("\n\nBrowser closed!\n\n");
  }
84 85 86 87 88 89
  
  @override
  void shouldOverrideUrlLoading(String url) {
    print("\n\n override $url\n\n");
    this.loadUrl(url);
  }
pichillilorenzo's avatar
pichillilorenzo committed
90

91 92 93 94 95
  @override
  void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
    print("Started at: " + response.startTime.toString() + "ms ---> duration: " + response.duration.toString() + "ms " + response.url);
  }

96 97 98 99 100 101 102 103 104 105 106
  @override
  void onConsoleMessage(ConsoleMessage consoleMessage) {
    print("""
    console output:
      sourceURL: ${consoleMessage.sourceURL}
      lineNumber: ${consoleMessage.lineNumber}
      message: ${consoleMessage.message}
      messageLevel: ${consoleMessage.messageLevel}
    """);
  }

pichillilorenzo's avatar
pichillilorenzo committed
107 108 109
}

MyInAppBrowser inAppBrowser = new MyInAppBrowser();
pichillilorenzo's avatar
pichillilorenzo committed
110 111 112 113 114 115 116 117 118 119 120 121 122

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
123 124

    // listen for post messages coming from the JavaScript side
pichillilorenzo's avatar
pichillilorenzo committed
125
    int indexTest = inAppBrowser.addJavaScriptHandler("handlerNameTest", (arguments) async {
126 127 128
      print("handlerNameTest arguments");
      print(arguments); // it prints: [1, 5, string, {key: 5}, [4, 6, 8]]
    });
pichillilorenzo's avatar
pichillilorenzo committed
129 130 131 132 133 134 135 136 137 138 139
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Flutter InAppBrowser Plugin example app'),
        ),
        body: new Center(
          child: new RaisedButton(onPressed: () {
pichillilorenzo's avatar
pichillilorenzo committed
140
            inAppBrowser.open(url: "https://flutter.io/", options: {
141 142
               "useShouldOverrideUrlLoading": true,
               "useOnLoadResource": true
143
             });
pichillilorenzo's avatar
pichillilorenzo committed
144 145 146 147 148 149 150 151
          },
          child: Text("Open InAppBrowser")
          ),
        ),
      ),
    );
  }
}
pichillilorenzo's avatar
pichillilorenzo committed
152 153
```

154
#### Future\<void\> InAppBrowser.open
pichillilorenzo's avatar
pichillilorenzo committed
155

156
Opens a URL in a new InAppBrowser instance or the system browser.
pichillilorenzo's avatar
pichillilorenzo committed
157 158

```dart
159
inAppBrowser.open({String url = "about:blank", Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}});
pichillilorenzo's avatar
pichillilorenzo committed
160 161 162 163
```

Opens an `url` in a new `InAppBrowser` instance or the system browser.

164
- `url`: The `url` to load. Call `encodeUriComponent()` on this if the `url` contains Unicode characters. The default value is `about:blank`.
pichillilorenzo's avatar
pichillilorenzo committed
165

166 167 168
- `headers`: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.

- `target`: The target in which to load the `url`, an optional parameter that defaults to `_self`.
pichillilorenzo's avatar
pichillilorenzo committed
169 170 171 172 173

  - `_self`: Opens in the `InAppBrowser`.
  - `_blank`: Opens in the `InAppBrowser`.
  - `_system`: Opens in the system's web browser.

174
- `options`: Options for the `InAppBrowser`.
pichillilorenzo's avatar
pichillilorenzo committed
175 176

  All platforms support:
177
  - __useShouldOverrideUrlLoading__: Set to `true` to be able to listen at the `shouldOverrideUrlLoading` event. The default value is `false`.
178
  - __useOnLoadResource__: Set to `true` to be able to listen at the `onLoadResource()` event. The default value is `false`.
179 180 181 182 183 184 185 186 187 188
  - __clearCache__: Set to `true` to have all the browser's cache cleared before the new window is opened. The default value is `false`.
  - __userAgent___: Set the custom WebView's user-agent.
  - __javaScriptEnabled__: Set to `true` to enable JavaScript. The default value is `true`.
  - __javaScriptCanOpenWindowsAutomatically__: Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`.
  - __hidden__: Set to `true` to create the browser and load the page, but not show it. The `onLoadStop` event fires when loading is complete. Omit or set to `false` (default) to have the browser open and load normally.
  - __toolbarTop__: Set to `false` to hide the toolbar at the top of the WebView. The default value is `true`.
  - __toolbarTopBackgroundColor__: Set the custom background color of the toolbat at the top.
  - __hideUrlBar__: Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`.
  - __mediaPlaybackRequiresUserGesture__: Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`.
  
pichillilorenzo's avatar
pichillilorenzo committed
189
  **Android** supports these additional options:
190 191 192 193 194 195 196 197 198 199 200 201
  
  - __hideTitleBar__: Set to `true` if you want the title should be displayed. The default value is `false`.
  - __closeOnCannotGoBack__: Set to `false` to not close the InAppBrowser when the user click on the back button and the WebView cannot go back to the history. The default value is `true`.
  - __clearSessionCache__: Set to `true` to have the session cookie cache cleared before the new window is opened.
  - __builtInZoomControls__: Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `false`.
  - __supportZoom__: Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`.
  - __databaseEnabled__: Set to `true` if you want the database storage API is enabled. The default value is `false`.
  - __domStorageEnabled__: Set to `true` if you want the DOM storage API is enabled. The default value is `false`.
  - __useWideViewPort__: Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. When the value of the setting is false, the layout width is always set to the width of the WebView control in device-independent (CSS) pixels. When the value is true and the page contains the viewport meta tag, the value of the width specified in the tag is used. If the page does not contain the tag or does not provide a width, then a wide viewport will be used. The default value is `true`.
  - __safeBrowsingEnabled__: Set to `true` if you want the Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. The default value is `true`.
  - __progressBar__: Set to `false` to hide the progress bar at the bottom of the toolbar at the top. The default value is `true`.

pichillilorenzo's avatar
pichillilorenzo committed
202 203
  **iOS** supports these additional options:
 
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  - __disallowOverScroll__: Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`.
  - __toolbarBottom__: Set to `false` to hide the toolbar at the bottom of the WebView. The default value is `true`.
  - __toolbarBottomBackgroundColor__: Set the custom background color of the toolbat at the bottom.
  - __toolbarBottomTranslucent__: Set to `true` to set the toolbar at the bottom translucent. The default value is `true`.
  - __closeButtonCaption__: Set the custom text for the close button.
  - __closeButtonColor__: Set the custom color for the close button.
  - __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles. 
  - __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.
  - __enableViewportScale__: Set to `true` to allow a viewport meta tag to either disable or restrict the range of user scaling. The default value is `false`.
  - __suppressesIncrementalRendering__: Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory.. The default value is `false`.
  - __allowsAirPlayForMediaPlayback__: Set to `true` to allow AirPlay. The default value is `true`.
  - __allowsBackForwardNavigationGestures__: Set to `true` to allow the horizontal swipe gestures trigger back-forward list navigations. The default value is `true`.
  - __allowsLinkPreview__: Set to `true` to allow that pressing on a link displays a preview of the destination for the link. The default value is `true`.
  - __ignoresViewportScaleLimits__: Set to `true` if you want that the WebView should always allow scaling of the webpage, regardless of the author's intent. The ignoresViewportScaleLimits property overrides the `user-scalable` HTML property in a webpage. The default value is `false`.
  - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`.
  - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`.
  - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
pichillilorenzo's avatar
pichillilorenzo committed
221 222 223
  
Example:
```dart
224 225
inAppBrowser.open('https://flutter.io/', options: {
  "useShouldOverrideUrlLoading": true,
226
  "useOnLoadResource": true,
227 228 229 230 231 232 233
  "clearCache": true,
  "disallowOverScroll": true,
  "domStorageEnabled": true,
  "supportZoom": false,
  "toolbarBottomTranslucent": false,
  "allowsLinkPreview": false
});
pichillilorenzo's avatar
pichillilorenzo committed
234 235
``` 

236
#### Events
pichillilorenzo's avatar
pichillilorenzo committed
237 238 239 240 241

Event fires when the `InAppBrowser` starts to load an `url`.
```dart
  @override
  void onLoadStart(String url) {
242
  
pichillilorenzo's avatar
pichillilorenzo committed
243 244 245 246 247 248 249
  }
```

Event fires when the `InAppBrowser` finishes loading an `url`.
```dart
  @override
  void onLoadStop(String url) {
250
  
pichillilorenzo's avatar
pichillilorenzo committed
251 252 253 254 255 256 257
  }
```

Event fires when the `InAppBrowser` encounters an error loading an `url`.
```dart
  @override
  void onLoadError(String url, String code, String message) {
258
  
pichillilorenzo's avatar
pichillilorenzo committed
259 260 261 262 263 264 265
  }
```

Event fires when the `InAppBrowser` window is closed.
```dart
  @override
  void onExit() {
266
  
pichillilorenzo's avatar
pichillilorenzo committed
267 268 269
  }
```

270 271 272 273 274 275 276 277
Event fires when the `InAppBrowser` webview receives a `ConsoleMessage`.
```dart
  @override
  void onConsoleMessage(ConsoleMessage consoleMessage) {

  }
```

278
Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
279 280

**NOTE**: In order to be able to listen this event, you need to set `useShouldOverrideUrlLoading` option to `true`.
281 282 283 284 285 286 287
```dart
  @override
  void shouldOverrideUrlLoading(String url) {

  }
```

288 289 290 291 292 293 294 295 296 297 298 299
Event fires when the `InAppBrowser` webview loads a resource.

**NOTE**: In order to be able to listen this event, you need to set `useOnLoadResource` option to `true`.

**NOTE only for iOS**: In some cases, the `response.data` of a `response` with `text/html` encoding could be empty.
```dart
  @override
  void onLoadResource(WebResourceResponse response, WebResourceRequest request) {

  }
```

300
#### Future\<void\> InAppBrowser.loadUrl
301 302 303 304 305 306 307

Loads the given `url` with optional `headers` specified as a map from name to value.

```dart
inAppBrowser.loadUrl(String url, {Map<String, String> headers = const {}});
```

308
#### Future\<void\> InAppBrowser.show
pichillilorenzo's avatar
pichillilorenzo committed
309 310 311 312 313 314 315

Displays an `InAppBrowser` window that was opened hidden. Calling this has no effect if the `InAppBrowser` was already visible.

```dart
inAppBrowser.show();
``` 

316
#### Future\<void\> InAppBrowser.hide
pichillilorenzo's avatar
pichillilorenzo committed
317 318 319 320 321 322 323

Hides the `InAppBrowser` window. Calling this has no effect if the `InAppBrowser` was already hidden.

```dart
inAppBrowser.hide();
``` 

324
#### Future\<void\> InAppBrowser.close
pichillilorenzo's avatar
pichillilorenzo committed
325

326
Closes the `InAppBrowser` window.
pichillilorenzo's avatar
pichillilorenzo committed
327 328 329 330 331

```dart
inAppBrowser.close();
``` 

332
#### Future\<void\> InAppBrowser.reload
pichillilorenzo's avatar
pichillilorenzo committed
333

334
Reloads the `InAppBrowser` window.
pichillilorenzo's avatar
pichillilorenzo committed
335 336

```dart
337
inAppBrowser.reload();
pichillilorenzo's avatar
pichillilorenzo committed
338 339
``` 

340
#### Future\<void\> InAppBrowser.goBack
341 342 343 344 345 346 347

Goes back in the history of the `InAppBrowser` window.

```dart
inAppBrowser.goBack();
``` 

348
#### Future\<void\> InAppBrowser.goForward
349 350 351 352 353 354 355

Goes forward in the history of the `InAppBrowser` window.

```dart
inAppBrowser.goForward();
``` 

356
#### Future\<bool\> InAppBrowser.isLoading
357 358 359 360 361 362 363

Check if the Web View of the `InAppBrowser` instance is in a loading state.

```dart
inAppBrowser.isLoading();
``` 

364
#### Future\<void\> InAppBrowser.stopLoading
365 366 367 368 369 370 371

Stops the Web View of the `InAppBrowser` instance from loading.

```dart
inAppBrowser.stopLoading();
``` 

372
#### Future\<bool\> InAppBrowser.isHidden
373 374 375 376 377 378 379

Check if the Web View of the `InAppBrowser` instance is hidden.

```dart
inAppBrowser.isHidden();
``` 

380
#### Future\<String\> InAppBrowser.injectScriptCode
381 382 383 384 385 386 387

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`)

```dart
inAppBrowser.injectScriptCode(String source);
``` 

388
#### Future\<void\> InAppBrowser.injectScriptFile
pichillilorenzo's avatar
pichillilorenzo committed
389 390 391 392

Injects a JavaScript file into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)

```dart
393
inAppBrowser.injectScriptFile(String urlFile);
pichillilorenzo's avatar
pichillilorenzo committed
394 395
``` 

396
#### Future\<void\> InAppBrowser.injectStyleCode
pichillilorenzo's avatar
pichillilorenzo committed
397 398 399 400

Injects CSS into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)

```dart
401
inAppBrowser.injectStyleCode(String source);
pichillilorenzo's avatar
pichillilorenzo committed
402 403
``` 

404
#### Future\<void\> InAppBrowser.injectStyleFile
pichillilorenzo's avatar
pichillilorenzo committed
405 406 407 408

Injects a CSS file into the `InAppBrowser` window. (Only available when the target is set to `_blank` or to `_self`)

```dart
409
inAppBrowser.injectStyleFile(String urlFile);
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
```

#### int InAppBrowser.addJavaScriptHandler

Adds/Appends a JavaScript message handler `callback` (`JavaScriptHandlerCallback`) that listen to post messages sent from JavaScript by the handler with name `handlerName`.
Returns the position `index` of the handler that can be used to remove it with the `removeJavaScriptHandler()` method.

The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)).
The iOS implementation uses [addScriptMessageHandler](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537172-addscriptmessagehandler?language=objc)

The JavaScript function that can be used to call the handler is `window.flutter_inappbrowser.callHandler(handlerName <String>, ...args);`, where `args` are [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
The `args` will be stringified automatically using `JSON.stringify(args)` method and then they will be decoded on the Dart side.

```dart
inAppBrowser.addJavaScriptHandler(String handlerName, JavaScriptHandlerCallback callback);
```

#### bool InAppBrowser.removeJavaScriptHandler

Removes a JavaScript message handler previously added with the `addJavaScriptHandler()` method in the `handlerName` list by its position `index`.
Returns `true` if the callback is removed, otherwise `false`.
```dart
inAppBrowser.removeJavaScriptHandler(String handlerName, int index);
```

pichillilorenzo's avatar
pichillilorenzo committed
435

436
### `ChromeSafariBrowser` class
437 438
[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.

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
Create a Class that extends the `ChromeSafariBrowser` Class in order to override the callbacks to manage the browser events. Example:
```dart
import 'package:flutter/material.dart';
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';

class MyInAppBrowser extends InAppBrowser {

  @override
  Future onLoadStart(String url) async {
    print("\n\nStarted $url\n\n");
  }

  @override
  Future onLoadStop(String url) async {
    print("\n\nStopped $url\n\n");
  }

  @override
  void onLoadError(String url, int code, String message) {
    print("\n\nCan't load $url.. Error: $message\n\n");
  }

  @override
  void onExit() {
    print("\n\nBrowser closed!\n\n");
  }
  
}

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());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Flutter InAppBrowser Plugin example app'),
        ),
        body: new Center(
          child: new RaisedButton(onPressed: () {
            chromeSafariBrowser.open("https://flutter.io/", options: {
                  "addShareButton": false,
                  "toolbarBackgroundColor": "#000000",
                  "dismissButtonStyle": 1,
                  "preferredBarTintColor": "#000000",
                },
              optionsFallback: {
                "toolbarTopBackgroundColor": "#000000",
                "closeButtonCaption": "Close"
              });
          },
          child: Text("Open ChromeSafariBrowser")
          ),
        ),
      ),
    );
  }
}

```

#### Future\<void\> ChromeSafariBrowser.open
Opens an `url` in a new `ChromeSafariBrowser` instance or the system browser.

- `url`: The `url` to load. Call `encodeUriComponent()` on this if the `url` contains Unicode characters.

- `options`: Options for the `ChromeSafariBrowser`.

- `headersFallback`: The additional header of the `InAppBrowser` instance fallback to be used in the HTTP request for this URL, specified as a map from name to value.

- `optionsFallback`: Options used by the `InAppBrowser` instance fallback.

**Android** supports these options:

- __addShareButton__: Set to `false` if you don't want the default share button. The default value is `true`.
- __showTitle__: Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
- __toolbarBackgroundColor__: Set the custom background color of the toolbar.
- __enableUrlBarHiding__: Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
- __instantAppsEnabled__: Set to `true` to enable Instant Apps. The default value is `false`.

**iOS** supports these options:

- __entersReaderIfAvailable__: Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
- __barCollapsingEnabled__: Set to `true` to enable bar collapsing. The default value is `false`.
- __dismissButtonStyle__: Set the custom style for the dismiss button. The default value is `0 //done`. See [SFSafariViewController.DismissButtonStyle](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller/dismissbuttonstyle) for all the available styles.
- __preferredBarTintColor__: Set the custom background color of the navigation bar and the toolbar.
- __preferredControlTintColor__: Set the custom color of the control buttons on the navigation bar and the toolbar.
- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles.
- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles.

Example:
```dart
chromeSafariBrowser.open("https://flutter.io/", options: {
  "addShareButton": false,
  "toolbarBackgroundColor": "#000000",
  "dismissButtonStyle": 1,
  "preferredBarTintColor": "#000000",
});
```

#### Events

Event fires when the `ChromeSafariBrowser` is opened.
```dart
  @override
  void onOpened() {
  
  }
```

Event fires when the `ChromeSafariBrowser` is loaded.
```dart
  @override
  void onLoaded() {
  
  }
```

Event fires when the `ChromeSafariBrowser` is closed.
```dart
  @override
  void onClosed() {
  
  }
```

pichillilorenzo's avatar
pichillilorenzo committed
602 603
## Screenshots:

604
#### InAppBrowser
pichillilorenzo's avatar
pichillilorenzo committed
605
iOS:
pichillilorenzo's avatar
pichillilorenzo committed
606

607
![ios](https://user-images.githubusercontent.com/5956938/45934084-2a935400-bf99-11e8-9d71-9e1758b5b8c6.gif)
pichillilorenzo's avatar
pichillilorenzo committed
608 609

Android:
pichillilorenzo's avatar
pichillilorenzo committed
610

611 612 613 614 615 616 617 618 619 620
![android](https://user-images.githubusercontent.com/5956938/45934080-26ffcd00-bf99-11e8-8136-d39a81bd83e7.gif)

#### ChromeSafariBrowser
iOS:

![ios](https://user-images.githubusercontent.com/5956938/46532148-0c362e00-c8a0-11e8-9a0e-343e049dcf35.gif)

Android:

![android](https://user-images.githubusercontent.com/5956938/46532149-0c362e00-c8a0-11e8-8134-9af18f38a746.gif)