merged web support, dartfmt
This commit is contained in:
parent
091415dafe
commit
03e74820df
12
README.md
12
README.md
@ -45,6 +45,18 @@ Send a submission request to the [Submit App](https://inappwebview.dev/submit-ap
|
|||||||
|
|
||||||
Add `flutter_inappwebview` as a [dependency in your pubspec.yaml file](https://flutter.io/using-packages/).
|
Add `flutter_inappwebview` as a [dependency in your pubspec.yaml file](https://flutter.io/using-packages/).
|
||||||
|
|
||||||
|
### Installation - Web support
|
||||||
|
|
||||||
|
To make it work properly on the Web platformm, you need to add the `web_support.js` file inside the `<head>` of your `web/index.html` file:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<head>
|
||||||
|
<!-- ... -->
|
||||||
|
<script src="/packages/flutter_inappwebview/assets/web/web_support.js" defer></script>
|
||||||
|
<!-- ... -->
|
||||||
|
</head>
|
||||||
|
```
|
||||||
|
|
||||||
## Main Classes Overview
|
## Main Classes Overview
|
||||||
|
|
||||||
* [InAppWebView](https://inappwebview.dev/docs/in-app-webview/basic-usage/): Flutter Widget for adding an inline native WebView integrated into the flutter widget tree.
|
* [InAppWebView](https://inappwebview.dev/docs/in-app-webview/basic-usage/): Flutter Widget for adding an inline native WebView integrated into the flutter widget tree.
|
||||||
|
@ -5498,7 +5498,7 @@ setTimeout(function() {
|
|||||||
|
|
||||||
if (swAvailable && swInterceptAvailable) {
|
if (swAvailable && swInterceptAvailable) {
|
||||||
AndroidServiceWorkerController serviceWorkerController =
|
AndroidServiceWorkerController serviceWorkerController =
|
||||||
AndroidServiceWorkerController.instance();
|
AndroidServiceWorkerController.instance();
|
||||||
|
|
||||||
await serviceWorkerController.setServiceWorkerClient(null);
|
await serviceWorkerController.setServiceWorkerClient(null);
|
||||||
}
|
}
|
||||||
@ -5509,7 +5509,7 @@ setTimeout(function() {
|
|||||||
child: InAppWebView(
|
child: InAppWebView(
|
||||||
key: GlobalKey(),
|
key: GlobalKey(),
|
||||||
initialUrlRequest:
|
initialUrlRequest:
|
||||||
URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')),
|
URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')),
|
||||||
onLoadStop: (controller, url) {
|
onLoadStop: (controller, url) {
|
||||||
pageLoaded.complete(url!.toString());
|
pageLoaded.complete(url!.toString());
|
||||||
},
|
},
|
||||||
@ -5874,7 +5874,8 @@ setTimeout(function() {
|
|||||||
group('Android Custom Tabs', () {
|
group('Android Custom Tabs', () {
|
||||||
test('add custom action button', () async {
|
test('add custom action button', () async {
|
||||||
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
||||||
var actionButtonIcon = await rootBundle.load('test_assets/images/flutter-logo.png');
|
var actionButtonIcon =
|
||||||
|
await rootBundle.load('test_assets/images/flutter-logo.png');
|
||||||
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
||||||
id: 1,
|
id: 1,
|
||||||
description: 'Action Button description',
|
description: 'Action Button description',
|
||||||
@ -5892,7 +5893,8 @@ setTimeout(function() {
|
|||||||
await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev"));
|
await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev"));
|
||||||
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(
|
||||||
|
chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.browserClosed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
@ -19,8 +20,12 @@ class _HeadlessInAppWebViewExampleScreenState
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
var url = !kIsWeb
|
||||||
|
? Uri.parse("https://flutter.dev")
|
||||||
|
: Uri.parse("http://localhost:${Uri.base.port}/page.html");
|
||||||
|
|
||||||
headlessWebView = new HeadlessInAppWebView(
|
headlessWebView = new HeadlessInAppWebView(
|
||||||
initialUrlRequest: URLRequest(url: Uri.parse("https://flutter.dev")),
|
initialUrlRequest: URLRequest(url: url),
|
||||||
initialSettings: InAppWebViewSettings(),
|
initialSettings: InAppWebViewSettings(),
|
||||||
onWebViewCreated: (controller) {
|
onWebViewCreated: (controller) {
|
||||||
print('HeadlessInAppWebView created!');
|
print('HeadlessInAppWebView created!');
|
||||||
@ -78,6 +83,9 @@ class _HeadlessInAppWebViewExampleScreenState
|
|||||||
},
|
},
|
||||||
child: Text("Run HeadlessInAppWebView")),
|
child: Text("Run HeadlessInAppWebView")),
|
||||||
),
|
),
|
||||||
|
Container(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
Center(
|
Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -91,6 +99,9 @@ class _HeadlessInAppWebViewExampleScreenState
|
|||||||
},
|
},
|
||||||
child: Text("Send console.log message")),
|
child: Text("Send console.log message")),
|
||||||
),
|
),
|
||||||
|
Container(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
Center(
|
Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -13,17 +13,16 @@ class InAppWebViewExampleScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
|
|
||||||
final GlobalKey webViewKey = GlobalKey();
|
final GlobalKey webViewKey = GlobalKey();
|
||||||
|
|
||||||
InAppWebViewController? webViewController;
|
InAppWebViewController? webViewController;
|
||||||
InAppWebViewSettings settings = InAppWebViewSettings(
|
InAppWebViewSettings settings = InAppWebViewSettings(
|
||||||
useShouldOverrideUrlLoading: true,
|
useShouldOverrideUrlLoading: true,
|
||||||
mediaPlaybackRequiresUserGesture: false,
|
mediaPlaybackRequiresUserGesture: false,
|
||||||
useHybridComposition: true,
|
useHybridComposition: true,
|
||||||
allowsInlineMediaPlayback: true,
|
allowsInlineMediaPlayback: true,
|
||||||
iframeAllow: "camera; microphone",
|
iframeAllow: "camera; microphone",
|
||||||
iframeAllowFullscreen: true,
|
iframeAllowFullscreen: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
PullToRefreshController? pullToRefreshController;
|
PullToRefreshController? pullToRefreshController;
|
||||||
@ -57,25 +56,30 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||||||
print("onHideContextMenu");
|
print("onHideContextMenu");
|
||||||
},
|
},
|
||||||
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
|
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
|
||||||
|
var id = contextMenuItemClicked.id;
|
||||||
print("onContextMenuActionItemClicked: " +
|
print("onContextMenuActionItemClicked: " +
|
||||||
contextMenuItemClicked.id.toString() +
|
id.toString() +
|
||||||
" " +
|
" " +
|
||||||
contextMenuItemClicked.title);
|
contextMenuItemClicked.title);
|
||||||
});
|
});
|
||||||
|
|
||||||
pullToRefreshController = !kIsWeb ? PullToRefreshController(
|
pullToRefreshController = kIsWeb
|
||||||
settings: PullToRefreshSettings(
|
? null
|
||||||
color: Colors.blue,
|
: PullToRefreshController(
|
||||||
),
|
settings: PullToRefreshSettings(
|
||||||
onRefresh: () async {
|
color: Colors.blue,
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
),
|
||||||
webViewController?.reload();
|
onRefresh: () async {
|
||||||
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
webViewController?.loadUrl(
|
webViewController?.reload();
|
||||||
urlRequest: URLRequest(url: await webViewController?.getUrl()));
|
} else if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
}
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
},
|
webViewController?.loadUrl(
|
||||||
) : null;
|
urlRequest:
|
||||||
|
URLRequest(url: await webViewController?.getUrl()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -91,108 +95,105 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(prefixIcon: Icon(Icons.search)),
|
||||||
prefixIcon: Icon(Icons.search)
|
|
||||||
),
|
|
||||||
controller: urlController,
|
controller: urlController,
|
||||||
keyboardType: TextInputType.url,
|
keyboardType: TextInputType.url,
|
||||||
onSubmitted: (value) {
|
onSubmitted: (value) {
|
||||||
var url = Uri.parse(value);
|
var url = Uri.parse(value);
|
||||||
if (url.scheme.isEmpty) {
|
if (url.scheme.isEmpty) {
|
||||||
url = Uri.parse("https://www.google.com/search?q=" + value);
|
url = Uri.parse((!kIsWeb
|
||||||
|
? "https://www.google.com/search?q="
|
||||||
|
: "https://www.bing.com/search?q=") +
|
||||||
|
value);
|
||||||
}
|
}
|
||||||
webViewController?.loadUrl(
|
webViewController?.loadUrl(urlRequest: URLRequest(url: url));
|
||||||
urlRequest: URLRequest(url: url));
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
InAppWebView(
|
InAppWebView(
|
||||||
key: webViewKey,
|
key: webViewKey,
|
||||||
// contextMenu: contextMenu,
|
initialUrlRequest:
|
||||||
// initialUrlRequest:
|
URLRequest(url: Uri.parse("https://flutter.dev")),
|
||||||
// URLRequest(url: Uri.parse("https://www.pubnub.com/developers/demos/webrtc/launch/")),
|
// initialFile: "assets/index.html",
|
||||||
initialUrlRequest:
|
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
||||||
URLRequest(url: Uri.parse(Uri.base.toString().replaceFirst("/#/", "/") + 'page.html')),
|
initialSettings: settings,
|
||||||
// initialUrlRequest:
|
// contextMenu: contextMenu,
|
||||||
// URLRequest(url: Uri.parse('https://flutter.dev')),
|
pullToRefreshController: pullToRefreshController,
|
||||||
// initialFile: "assets/index.html",
|
onWebViewCreated: (controller) {
|
||||||
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
webViewController = controller;
|
||||||
initialSettings: settings,
|
},
|
||||||
pullToRefreshController: pullToRefreshController,
|
onLoadStart: (controller, url) async {
|
||||||
onWebViewCreated: (controller) async {
|
setState(() {
|
||||||
webViewController = controller;
|
this.url = url.toString();
|
||||||
},
|
urlController.text = this.url;
|
||||||
onLoadStart: (controller, url) async {
|
});
|
||||||
setState(() {
|
},
|
||||||
this.url = url.toString();
|
onPermissionRequest: (controller, request) async {
|
||||||
urlController.text = this.url;
|
return PermissionResponse(
|
||||||
});
|
resources: request.resources,
|
||||||
},
|
action: PermissionResponseAction.GRANT);
|
||||||
onPermissionRequest: (controller, request) async {
|
},
|
||||||
return PermissionResponse(
|
shouldOverrideUrlLoading:
|
||||||
resources: request.resources,
|
(controller, navigationAction) async {
|
||||||
action: PermissionResponseAction.GRANT);
|
var uri = navigationAction.request.url!;
|
||||||
},
|
|
||||||
shouldOverrideUrlLoading: (controller, navigationAction) async {
|
|
||||||
var uri = navigationAction.request.url!;
|
|
||||||
|
|
||||||
if (![
|
if (![
|
||||||
"http",
|
"http",
|
||||||
"https",
|
"https",
|
||||||
"file",
|
"file",
|
||||||
"chrome",
|
"chrome",
|
||||||
"data",
|
"data",
|
||||||
"javascript",
|
"javascript",
|
||||||
"about"
|
"about"
|
||||||
].contains(uri.scheme)) {
|
].contains(uri.scheme)) {
|
||||||
if (await canLaunch(url)) {
|
if (await canLaunch(url)) {
|
||||||
// Launch the App
|
// Launch the App
|
||||||
await launch(
|
await launch(
|
||||||
url,
|
url,
|
||||||
);
|
);
|
||||||
// and cancel the request
|
// and cancel the request
|
||||||
return NavigationActionPolicy.CANCEL;
|
return NavigationActionPolicy.CANCEL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NavigationActionPolicy.ALLOW;
|
return NavigationActionPolicy.ALLOW;
|
||||||
},
|
},
|
||||||
onLoadStop: (controller, url) async {
|
onLoadStop: (controller, url) async {
|
||||||
|
pullToRefreshController?.endRefreshing();
|
||||||
|
setState(() {
|
||||||
|
this.url = url.toString();
|
||||||
|
urlController.text = this.url;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onLoadError: (controller, url, code, message) {
|
||||||
|
pullToRefreshController?.endRefreshing();
|
||||||
|
},
|
||||||
|
onProgressChanged: (controller, progress) {
|
||||||
|
if (progress == 100) {
|
||||||
pullToRefreshController?.endRefreshing();
|
pullToRefreshController?.endRefreshing();
|
||||||
setState(() {
|
}
|
||||||
this.url = url.toString();
|
setState(() {
|
||||||
urlController.text = this.url;
|
this.progress = progress / 100;
|
||||||
});
|
urlController.text = this.url;
|
||||||
},
|
});
|
||||||
onLoadError: (controller, url, code, message) {
|
},
|
||||||
pullToRefreshController?.endRefreshing();
|
onUpdateVisitedHistory: (controller, url, androidIsReload) {
|
||||||
},
|
setState(() {
|
||||||
onProgressChanged: (controller, progress) {
|
this.url = url.toString();
|
||||||
if (progress == 100) {
|
urlController.text = this.url;
|
||||||
pullToRefreshController?.endRefreshing();
|
});
|
||||||
}
|
},
|
||||||
setState(() {
|
onConsoleMessage: (controller, consoleMessage) {
|
||||||
this.progress = progress / 100;
|
print(consoleMessage);
|
||||||
urlController.text = this.url;
|
},
|
||||||
});
|
),
|
||||||
},
|
progress < 1.0
|
||||||
onUpdateVisitedHistory: (controller, url, androidIsReload) {
|
? LinearProgressIndicator(value: progress)
|
||||||
setState(() {
|
: Container(),
|
||||||
this.url = url.toString();
|
],
|
||||||
urlController.text = this.url;
|
),
|
||||||
});
|
|
||||||
},
|
|
||||||
onConsoleMessage: (controller, consoleMessage) {
|
|
||||||
print(consoleMessage);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
!kIsWeb && progress < 1.0
|
|
||||||
? LinearProgressIndicator(value: progress)
|
|
||||||
: Container(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ButtonBar(
|
ButtonBar(
|
||||||
alignment: MainAxisAlignment.center,
|
alignment: MainAxisAlignment.center,
|
||||||
@ -215,12 +216,6 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||||||
webViewController?.reload();
|
webViewController?.reload();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
|
||||||
child: Icon(Icons.cancel),
|
|
||||||
onPressed: () {
|
|
||||||
webViewController?.stopLoading();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
])));
|
])));
|
||||||
|
@ -25,4 +25,4 @@ library flutter_inappwebview;
|
|||||||
import 'package:js/js.dart';
|
import 'package:js/js.dart';
|
||||||
|
|
||||||
export 'src/main.dart';
|
export 'src/main.dart';
|
||||||
export 'src/web/main.dart';
|
export 'src/web/main.dart';
|
||||||
|
@ -251,7 +251,8 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
|||||||
}
|
}
|
||||||
settings.screenOrientation = map["screenOrientation"];
|
settings.screenOrientation = map["screenOrientation"];
|
||||||
}
|
}
|
||||||
if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
settings.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
settings.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
||||||
settings.barCollapsingEnabled = map["barCollapsingEnabled"];
|
settings.barCollapsingEnabled = map["barCollapsingEnabled"];
|
||||||
settings.dismissButtonStyle =
|
settings.dismissButtonStyle =
|
||||||
|
@ -82,7 +82,8 @@ class CookieManager {
|
|||||||
bool? isSecure,
|
bool? isSecure,
|
||||||
bool? isHttpOnly,
|
bool? isHttpOnly,
|
||||||
HTTPCookieSameSitePolicy? sameSite,
|
HTTPCookieSameSitePolicy? sameSite,
|
||||||
@Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController,
|
@Deprecated("Use webViewController instead")
|
||||||
|
InAppWebViewController? iosBelow11WebViewController,
|
||||||
InAppWebViewController? webViewController}) async {
|
InAppWebViewController? webViewController}) async {
|
||||||
if (domain == null) domain = _getDomainName(url);
|
if (domain == null) domain = _getDomainName(url);
|
||||||
|
|
||||||
@ -200,7 +201,8 @@ class CookieManager {
|
|||||||
///- Web
|
///- Web
|
||||||
Future<List<Cookie>> getCookies(
|
Future<List<Cookie>> getCookies(
|
||||||
{required Uri url,
|
{required Uri url,
|
||||||
@Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController,
|
@Deprecated("Use webViewController instead")
|
||||||
|
InAppWebViewController? iosBelow11WebViewController,
|
||||||
InAppWebViewController? webViewController}) async {
|
InAppWebViewController? webViewController}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
|
|
||||||
@ -318,7 +320,8 @@ class CookieManager {
|
|||||||
Future<Cookie?> getCookie(
|
Future<Cookie?> getCookie(
|
||||||
{required Uri url,
|
{required Uri url,
|
||||||
required String name,
|
required String name,
|
||||||
@Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController,
|
@Deprecated("Use webViewController instead")
|
||||||
|
InAppWebViewController? iosBelow11WebViewController,
|
||||||
InAppWebViewController? webViewController}) async {
|
InAppWebViewController? webViewController}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
assert(name.isNotEmpty);
|
assert(name.isNotEmpty);
|
||||||
@ -388,7 +391,8 @@ class CookieManager {
|
|||||||
required String name,
|
required String name,
|
||||||
String domain = "",
|
String domain = "",
|
||||||
String path = "/",
|
String path = "/",
|
||||||
@Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController,
|
@Deprecated("Use webViewController instead")
|
||||||
|
InAppWebViewController? iosBelow11WebViewController,
|
||||||
InAppWebViewController? webViewController}) async {
|
InAppWebViewController? webViewController}) async {
|
||||||
if (domain.isEmpty) domain = _getDomainName(url);
|
if (domain.isEmpty) domain = _getDomainName(url);
|
||||||
|
|
||||||
@ -449,7 +453,8 @@ class CookieManager {
|
|||||||
{required Uri url,
|
{required Uri url,
|
||||||
String domain = "",
|
String domain = "",
|
||||||
String path = "/",
|
String path = "/",
|
||||||
@Deprecated("Use webViewController instead") InAppWebViewController? iosBelow11WebViewController,
|
@Deprecated("Use webViewController instead")
|
||||||
|
InAppWebViewController? iosBelow11WebViewController,
|
||||||
InAppWebViewController? webViewController}) async {
|
InAppWebViewController? webViewController}) async {
|
||||||
if (domain.isEmpty) domain = _getDomainName(url);
|
if (domain.isEmpty) domain = _getDomainName(url);
|
||||||
|
|
||||||
@ -537,13 +542,13 @@ class CookieManager {
|
|||||||
Future<String> _getCookieExpirationDate(int expiresDate) async {
|
Future<String> _getCookieExpirationDate(int expiresDate) async {
|
||||||
var platformUtil = PlatformUtil.instance();
|
var platformUtil = PlatformUtil.instance();
|
||||||
var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc();
|
var dateTime = DateTime.fromMillisecondsSinceEpoch(expiresDate).toUtc();
|
||||||
return !kIsWeb ?
|
return !kIsWeb
|
||||||
await platformUtil.formatDate(
|
? await platformUtil.formatDate(
|
||||||
date: dateTime,
|
date: dateTime,
|
||||||
format: 'EEE, dd MMM yyyy hh:mm:ss z',
|
format: 'EEE, dd MMM yyyy hh:mm:ss z',
|
||||||
locale: 'en_US',
|
locale: 'en_US',
|
||||||
timezone: 'GMT') :
|
timezone: 'GMT')
|
||||||
await platformUtil.getWebCookieExpirationDate(date: dateTime);
|
: await platformUtil.getWebCookieExpirationDate(date: dateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,8 @@ class InAppBrowserSettings
|
|||||||
settings.shouldCloseOnBackButtonPressed =
|
settings.shouldCloseOnBackButtonPressed =
|
||||||
map["shouldCloseOnBackButtonPressed"];
|
map["shouldCloseOnBackButtonPressed"];
|
||||||
}
|
}
|
||||||
if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
settings.toolbarTopTranslucent = map["toolbarTopTranslucent"];
|
settings.toolbarTopTranslucent = map["toolbarTopTranslucent"];
|
||||||
settings.toolbarTopTintColor =
|
settings.toolbarTopTintColor =
|
||||||
UtilColor.fromHex(map["toolbarTopTintColor"]);
|
UtilColor.fromHex(map["toolbarTopTintColor"]);
|
||||||
|
@ -75,7 +75,8 @@ class InAppWebViewController
|
|||||||
|
|
||||||
InAppWebViewController(dynamic id, WebView webview) {
|
InAppWebViewController(dynamic id, WebView webview) {
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._channel = MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id');
|
this._channel =
|
||||||
|
MethodChannel('com.pichillilorenzo/flutter_inappwebview_$id');
|
||||||
this._channel.setMethodCallHandler(handleMethod);
|
this._channel.setMethodCallHandler(handleMethod);
|
||||||
this._webview = webview;
|
this._webview = webview;
|
||||||
this._userScripts =
|
this._userScripts =
|
||||||
@ -1700,7 +1701,8 @@ class InAppWebViewController
|
|||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
args.putIfAbsent('contentWorld', () => contentWorld?.toMap());
|
args.putIfAbsent('contentWorld', () => contentWorld?.toMap());
|
||||||
var data = await _channel.invokeMethod('evaluateJavascript', args);
|
var data = await _channel.invokeMethod('evaluateJavascript', args);
|
||||||
if (data != null && (defaultTargetPlatform == TargetPlatform.android || kIsWeb)) {
|
if (data != null &&
|
||||||
|
(defaultTargetPlatform == TargetPlatform.android || kIsWeb)) {
|
||||||
try {
|
try {
|
||||||
// try to json decode the data coming from JavaScript
|
// try to json decode the data coming from JavaScript
|
||||||
// otherwise return it as it is.
|
// otherwise return it as it is.
|
||||||
|
@ -1053,132 +1053,133 @@ class InAppWebViewSettings
|
|||||||
///- Web
|
///- Web
|
||||||
String? iframeCsp;
|
String? iframeCsp;
|
||||||
|
|
||||||
InAppWebViewSettings(
|
InAppWebViewSettings({
|
||||||
{this.useShouldOverrideUrlLoading = false,
|
this.useShouldOverrideUrlLoading = false,
|
||||||
this.useOnLoadResource = false,
|
this.useOnLoadResource = false,
|
||||||
this.useOnDownloadStart = false,
|
this.useOnDownloadStart = false,
|
||||||
this.clearCache = false,
|
this.clearCache = false,
|
||||||
this.userAgent = "",
|
this.userAgent = "",
|
||||||
this.applicationNameForUserAgent = "",
|
this.applicationNameForUserAgent = "",
|
||||||
this.javaScriptEnabled = true,
|
this.javaScriptEnabled = true,
|
||||||
this.javaScriptCanOpenWindowsAutomatically = false,
|
this.javaScriptCanOpenWindowsAutomatically = false,
|
||||||
this.mediaPlaybackRequiresUserGesture = true,
|
this.mediaPlaybackRequiresUserGesture = true,
|
||||||
this.minimumFontSize,
|
this.minimumFontSize,
|
||||||
this.verticalScrollBarEnabled = true,
|
this.verticalScrollBarEnabled = true,
|
||||||
this.horizontalScrollBarEnabled = true,
|
this.horizontalScrollBarEnabled = true,
|
||||||
this.resourceCustomSchemes = const [],
|
this.resourceCustomSchemes = const [],
|
||||||
this.contentBlockers = const [],
|
this.contentBlockers = const [],
|
||||||
this.preferredContentMode = UserPreferredContentMode.RECOMMENDED,
|
this.preferredContentMode = UserPreferredContentMode.RECOMMENDED,
|
||||||
this.useShouldInterceptAjaxRequest = false,
|
this.useShouldInterceptAjaxRequest = false,
|
||||||
this.useShouldInterceptFetchRequest = false,
|
this.useShouldInterceptFetchRequest = false,
|
||||||
this.incognito = false,
|
this.incognito = false,
|
||||||
this.cacheEnabled = true,
|
this.cacheEnabled = true,
|
||||||
this.transparentBackground = false,
|
this.transparentBackground = false,
|
||||||
this.disableVerticalScroll = false,
|
this.disableVerticalScroll = false,
|
||||||
this.disableHorizontalScroll = false,
|
this.disableHorizontalScroll = false,
|
||||||
this.disableContextMenu = false,
|
this.disableContextMenu = false,
|
||||||
this.supportZoom = true,
|
this.supportZoom = true,
|
||||||
this.allowFileAccessFromFileURLs = false,
|
this.allowFileAccessFromFileURLs = false,
|
||||||
this.allowUniversalAccessFromFileURLs = false,
|
this.allowUniversalAccessFromFileURLs = false,
|
||||||
this.textZoom = 100,
|
this.textZoom = 100,
|
||||||
this.clearSessionCache = false,
|
this.clearSessionCache = false,
|
||||||
this.builtInZoomControls = true,
|
this.builtInZoomControls = true,
|
||||||
this.displayZoomControls = false,
|
this.displayZoomControls = false,
|
||||||
this.databaseEnabled = true,
|
this.databaseEnabled = true,
|
||||||
this.domStorageEnabled = true,
|
this.domStorageEnabled = true,
|
||||||
this.useWideViewPort = true,
|
this.useWideViewPort = true,
|
||||||
this.safeBrowsingEnabled = true,
|
this.safeBrowsingEnabled = true,
|
||||||
this.mixedContentMode,
|
this.mixedContentMode,
|
||||||
this.allowContentAccess = true,
|
this.allowContentAccess = true,
|
||||||
this.allowFileAccess = true,
|
this.allowFileAccess = true,
|
||||||
this.appCachePath,
|
this.appCachePath,
|
||||||
this.blockNetworkImage = false,
|
this.blockNetworkImage = false,
|
||||||
this.blockNetworkLoads = false,
|
this.blockNetworkLoads = false,
|
||||||
this.cacheMode = CacheMode.LOAD_DEFAULT,
|
this.cacheMode = CacheMode.LOAD_DEFAULT,
|
||||||
this.cursiveFontFamily = "cursive",
|
this.cursiveFontFamily = "cursive",
|
||||||
this.defaultFixedFontSize = 16,
|
this.defaultFixedFontSize = 16,
|
||||||
this.defaultFontSize = 16,
|
this.defaultFontSize = 16,
|
||||||
this.defaultTextEncodingName = "UTF-8",
|
this.defaultTextEncodingName = "UTF-8",
|
||||||
this.disabledActionModeMenuItems,
|
this.disabledActionModeMenuItems,
|
||||||
this.fantasyFontFamily = "fantasy",
|
this.fantasyFontFamily = "fantasy",
|
||||||
this.fixedFontFamily = "monospace",
|
this.fixedFontFamily = "monospace",
|
||||||
this.forceDark = ForceDark.FORCE_DARK_OFF,
|
this.forceDark = ForceDark.FORCE_DARK_OFF,
|
||||||
this.geolocationEnabled = true,
|
this.geolocationEnabled = true,
|
||||||
this.layoutAlgorithm,
|
this.layoutAlgorithm,
|
||||||
this.loadWithOverviewMode = true,
|
this.loadWithOverviewMode = true,
|
||||||
this.loadsImagesAutomatically = true,
|
this.loadsImagesAutomatically = true,
|
||||||
this.minimumLogicalFontSize = 8,
|
this.minimumLogicalFontSize = 8,
|
||||||
this.needInitialFocus = true,
|
this.needInitialFocus = true,
|
||||||
this.offscreenPreRaster = false,
|
this.offscreenPreRaster = false,
|
||||||
this.sansSerifFontFamily = "sans-serif",
|
this.sansSerifFontFamily = "sans-serif",
|
||||||
this.serifFontFamily = "sans-serif",
|
this.serifFontFamily = "sans-serif",
|
||||||
this.standardFontFamily = "sans-serif",
|
this.standardFontFamily = "sans-serif",
|
||||||
this.saveFormData = true,
|
this.saveFormData = true,
|
||||||
this.thirdPartyCookiesEnabled = true,
|
this.thirdPartyCookiesEnabled = true,
|
||||||
this.hardwareAcceleration = true,
|
this.hardwareAcceleration = true,
|
||||||
this.initialScale = 0,
|
this.initialScale = 0,
|
||||||
this.supportMultipleWindows = false,
|
this.supportMultipleWindows = false,
|
||||||
this.regexToCancelSubFramesLoading,
|
this.regexToCancelSubFramesLoading,
|
||||||
this.useHybridComposition = false,
|
this.useHybridComposition = false,
|
||||||
this.useShouldInterceptRequest = false,
|
this.useShouldInterceptRequest = false,
|
||||||
this.useOnRenderProcessGone = false,
|
this.useOnRenderProcessGone = false,
|
||||||
this.overScrollMode = OverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS,
|
this.overScrollMode = OverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS,
|
||||||
this.networkAvailable,
|
this.networkAvailable,
|
||||||
this.scrollBarStyle = ScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY,
|
this.scrollBarStyle = ScrollBarStyle.SCROLLBARS_INSIDE_OVERLAY,
|
||||||
this.verticalScrollbarPosition =
|
this.verticalScrollbarPosition =
|
||||||
VerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT,
|
VerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT,
|
||||||
this.scrollBarDefaultDelayBeforeFade,
|
this.scrollBarDefaultDelayBeforeFade,
|
||||||
this.scrollbarFadingEnabled = true,
|
this.scrollbarFadingEnabled = true,
|
||||||
this.scrollBarFadeDuration,
|
this.scrollBarFadeDuration,
|
||||||
this.rendererPriorityPolicy,
|
this.rendererPriorityPolicy,
|
||||||
this.disableDefaultErrorPage = false,
|
this.disableDefaultErrorPage = false,
|
||||||
this.verticalScrollbarThumbColor,
|
this.verticalScrollbarThumbColor,
|
||||||
this.verticalScrollbarTrackColor,
|
this.verticalScrollbarTrackColor,
|
||||||
this.horizontalScrollbarThumbColor,
|
this.horizontalScrollbarThumbColor,
|
||||||
this.horizontalScrollbarTrackColor,
|
this.horizontalScrollbarTrackColor,
|
||||||
this.disallowOverScroll = false,
|
this.disallowOverScroll = false,
|
||||||
this.enableViewportScale = false,
|
this.enableViewportScale = false,
|
||||||
this.suppressesIncrementalRendering = false,
|
this.suppressesIncrementalRendering = false,
|
||||||
this.allowsAirPlayForMediaPlayback = true,
|
this.allowsAirPlayForMediaPlayback = true,
|
||||||
this.allowsBackForwardNavigationGestures = true,
|
this.allowsBackForwardNavigationGestures = true,
|
||||||
this.allowsLinkPreview = true,
|
this.allowsLinkPreview = true,
|
||||||
this.ignoresViewportScaleLimits = false,
|
this.ignoresViewportScaleLimits = false,
|
||||||
this.allowsInlineMediaPlayback = false,
|
this.allowsInlineMediaPlayback = false,
|
||||||
this.allowsPictureInPictureMediaPlayback = true,
|
this.allowsPictureInPictureMediaPlayback = true,
|
||||||
this.isFraudulentWebsiteWarningEnabled = true,
|
this.isFraudulentWebsiteWarningEnabled = true,
|
||||||
this.selectionGranularity = SelectionGranularity.DYNAMIC,
|
this.selectionGranularity = SelectionGranularity.DYNAMIC,
|
||||||
this.dataDetectorTypes = const [DataDetectorTypes.NONE],
|
this.dataDetectorTypes = const [DataDetectorTypes.NONE],
|
||||||
this.sharedCookiesEnabled = false,
|
this.sharedCookiesEnabled = false,
|
||||||
this.automaticallyAdjustsScrollIndicatorInsets = false,
|
this.automaticallyAdjustsScrollIndicatorInsets = false,
|
||||||
this.accessibilityIgnoresInvertColors = false,
|
this.accessibilityIgnoresInvertColors = false,
|
||||||
this.decelerationRate = ScrollViewDecelerationRate.NORMAL,
|
this.decelerationRate = ScrollViewDecelerationRate.NORMAL,
|
||||||
this.alwaysBounceVertical = false,
|
this.alwaysBounceVertical = false,
|
||||||
this.alwaysBounceHorizontal = false,
|
this.alwaysBounceHorizontal = false,
|
||||||
this.scrollsToTop = true,
|
this.scrollsToTop = true,
|
||||||
this.isPagingEnabled = false,
|
this.isPagingEnabled = false,
|
||||||
this.maximumZoomScale = 1.0,
|
this.maximumZoomScale = 1.0,
|
||||||
this.minimumZoomScale = 1.0,
|
this.minimumZoomScale = 1.0,
|
||||||
this.contentInsetAdjustmentBehavior =
|
this.contentInsetAdjustmentBehavior =
|
||||||
ScrollViewContentInsetAdjustmentBehavior.NEVER,
|
ScrollViewContentInsetAdjustmentBehavior.NEVER,
|
||||||
this.isDirectionalLockEnabled = false,
|
this.isDirectionalLockEnabled = false,
|
||||||
this.mediaType,
|
this.mediaType,
|
||||||
this.pageZoom = 1.0,
|
this.pageZoom = 1.0,
|
||||||
this.limitsNavigationsToAppBoundDomains = false,
|
this.limitsNavigationsToAppBoundDomains = false,
|
||||||
this.useOnNavigationResponse = false,
|
this.useOnNavigationResponse = false,
|
||||||
this.applePayAPIEnabled = false,
|
this.applePayAPIEnabled = false,
|
||||||
this.allowingReadAccessTo,
|
this.allowingReadAccessTo,
|
||||||
this.disableLongPressContextMenuOnLinks = false,
|
this.disableLongPressContextMenuOnLinks = false,
|
||||||
this.disableInputAccessoryView = false,
|
this.disableInputAccessoryView = false,
|
||||||
this.underPageBackgroundColor,
|
this.underPageBackgroundColor,
|
||||||
this.isTextInteractionEnabled = true,
|
this.isTextInteractionEnabled = true,
|
||||||
this.isSiteSpecificQuirksModeEnabled = true,
|
this.isSiteSpecificQuirksModeEnabled = true,
|
||||||
this.upgradeKnownHostsToHTTPS = true,
|
this.upgradeKnownHostsToHTTPS = true,
|
||||||
this.iframeAllow,
|
this.iframeAllow,
|
||||||
this.iframeAllowFullscreen,
|
this.iframeAllowFullscreen,
|
||||||
this.iframeSandbox,
|
this.iframeSandbox,
|
||||||
this.iframeReferrerPolicy,
|
this.iframeReferrerPolicy,
|
||||||
this.iframeName,
|
this.iframeName,
|
||||||
this.iframeCsp,}) {
|
this.iframeCsp,
|
||||||
|
}) {
|
||||||
if (this.minimumFontSize == null)
|
if (this.minimumFontSize == null)
|
||||||
this.minimumFontSize =
|
this.minimumFontSize =
|
||||||
defaultTargetPlatform == TargetPlatform.android ? 8 : 0;
|
defaultTargetPlatform == TargetPlatform.android ? 8 : 0;
|
||||||
@ -1388,7 +1389,8 @@ class InAppWebViewSettings
|
|||||||
settings.iframeAllowFullscreen = map["iframeAllowFullscreen"];
|
settings.iframeAllowFullscreen = map["iframeAllowFullscreen"];
|
||||||
settings.iframeSandbox = (map["iframeSandbox"] as List<String?>?)
|
settings.iframeSandbox = (map["iframeSandbox"] as List<String?>?)
|
||||||
?.map((e) => Sandbox.fromValue(e)) as List<Sandbox>?;
|
?.map((e) => Sandbox.fromValue(e)) as List<Sandbox>?;
|
||||||
settings.iframeReferrerPolicy = ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]);
|
settings.iframeReferrerPolicy =
|
||||||
|
ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]);
|
||||||
settings.iframeName = map["iframeName"];
|
settings.iframeName = map["iframeName"];
|
||||||
settings.iframeCsp = map["iframeCsp"];
|
settings.iframeCsp = map["iframeCsp"];
|
||||||
}
|
}
|
||||||
@ -1460,7 +1462,8 @@ class InAppWebViewSettings
|
|||||||
settings.horizontalScrollbarTrackColor =
|
settings.horizontalScrollbarTrackColor =
|
||||||
UtilColor.fromHex(map["horizontalScrollbarTrackColor"]);
|
UtilColor.fromHex(map["horizontalScrollbarTrackColor"]);
|
||||||
}
|
}
|
||||||
if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
settings.disallowOverScroll = map["disallowOverScroll"];
|
settings.disallowOverScroll = map["disallowOverScroll"];
|
||||||
settings.enableViewportScale = map["enableViewportScale"];
|
settings.enableViewportScale = map["enableViewportScale"];
|
||||||
settings.suppressesIncrementalRendering =
|
settings.suppressesIncrementalRendering =
|
||||||
|
@ -27,6 +27,8 @@ abstract class WebView {
|
|||||||
///
|
///
|
||||||
///**NOTE for Web**: it will be dispatched at the same time of [onLoadStop] event
|
///**NOTE for Web**: it will be dispatched at the same time of [onLoadStop] event
|
||||||
///because there isn't any way to capture the real load start event from an iframe.
|
///because there isn't any way to capture the real load start event from an iframe.
|
||||||
|
///If `window.location.href` isn't accessible inside the iframe,
|
||||||
|
///the [url] parameter will have the current value of the `iframe.src` attribute.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)))
|
///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)))
|
||||||
@ -36,6 +38,9 @@ abstract class WebView {
|
|||||||
|
|
||||||
///Event fired when the [WebView] finishes loading an [url].
|
///Event fired when the [WebView] finishes loading an [url].
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: If `window.location.href` isn't accessible inside the iframe,
|
||||||
|
///the [url] parameter will have the current value of the `iframe.src` attribute.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)))
|
///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)))
|
||||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
||||||
|
@ -47,8 +47,7 @@ class PlatformUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///Get cookie expiration date used by Web platform.
|
///Get cookie expiration date used by Web platform.
|
||||||
Future<String> getWebCookieExpirationDate(
|
Future<String> getWebCookieExpirationDate({required DateTime date}) async {
|
||||||
{required DateTime date}) async {
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('date', () => date.millisecondsSinceEpoch);
|
args.putIfAbsent('date', () => date.millisecondsSinceEpoch);
|
||||||
return await _channel.invokeMethod('getWebCookieExpirationDate', args);
|
return await _channel.invokeMethod('getWebCookieExpirationDate', args);
|
||||||
|
@ -4795,14 +4795,15 @@ class PermissionResourceType {
|
|||||||
PermissionResourceType.DEVICE_ORIENTATION_AND_MOTION,
|
PermissionResourceType.DEVICE_ORIENTATION_AND_MOTION,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
static PermissionResourceType? fromValue(dynamic? value) {
|
static PermissionResourceType? fromValue(dynamic value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
try {
|
try {
|
||||||
Set<PermissionResourceType> valueList =
|
Set<PermissionResourceType> valueList =
|
||||||
<PermissionResourceType>[].toSet();
|
<PermissionResourceType>[].toSet();
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
valueList = PermissionResourceType._androidValues;
|
valueList = PermissionResourceType._androidValues;
|
||||||
} else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
} else if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
valueList = PermissionResourceType._appleValues;
|
valueList = PermissionResourceType._appleValues;
|
||||||
}
|
}
|
||||||
return valueList.firstWhere((element) => element.toValue() == value);
|
return valueList.firstWhere((element) => element.toValue() == value);
|
||||||
@ -7395,7 +7396,8 @@ class SslErrorType {
|
|||||||
Set<SslErrorType> valueList = <SslErrorType>[].toSet();
|
Set<SslErrorType> valueList = <SslErrorType>[].toSet();
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
valueList = SslErrorType._androidValues;
|
valueList = SslErrorType._androidValues;
|
||||||
} else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
} else if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
valueList = SslErrorType._appleValues;
|
valueList = SslErrorType._appleValues;
|
||||||
}
|
}
|
||||||
return valueList.firstWhere((element) => element.toValue() == value);
|
return valueList.firstWhere((element) => element.toValue() == value);
|
||||||
@ -7426,7 +7428,8 @@ class SslErrorType {
|
|||||||
default:
|
default:
|
||||||
return "SSL_NOTYETVALID";
|
return "SSL_NOTYETVALID";
|
||||||
}
|
}
|
||||||
} else if (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS) {
|
} else if (defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
switch (_value) {
|
switch (_value) {
|
||||||
case 3:
|
case 3:
|
||||||
return "DENY";
|
return "DENY";
|
||||||
@ -10768,8 +10771,7 @@ class Sandbox {
|
|||||||
return _NONE;
|
return _NONE;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return Sandbox.values
|
return Sandbox.values.firstWhere((element) => element.toValue() == value);
|
||||||
.firstWhere((element) => element.toValue() == value);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -10778,7 +10780,8 @@ class Sandbox {
|
|||||||
String? toValue() => _value;
|
String? toValue() => _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => _value == null ? "allow-all" : (_value == "" ? "allow-none" : "");
|
String toString() =>
|
||||||
|
_value == null ? "allow-all" : (_value == "" ? "allow-none" : "");
|
||||||
|
|
||||||
static const _ALL = const Sandbox._internal(null);
|
static const _ALL = const Sandbox._internal(null);
|
||||||
static const _NONE = const Sandbox._internal("");
|
static const _NONE = const Sandbox._internal("");
|
||||||
@ -10799,10 +10802,12 @@ class Sandbox {
|
|||||||
static const ALLOW_MODALS = const Sandbox._internal("allow-modals");
|
static const ALLOW_MODALS = const Sandbox._internal("allow-modals");
|
||||||
|
|
||||||
///Lets the resource lock the screen orientation.
|
///Lets the resource lock the screen orientation.
|
||||||
static const ALLOW_ORIENTATION_LOCK = const Sandbox._internal("allow-orientation-lock");
|
static const ALLOW_ORIENTATION_LOCK =
|
||||||
|
const Sandbox._internal("allow-orientation-lock");
|
||||||
|
|
||||||
///Lets the resource use the Pointer Lock API.
|
///Lets the resource use the Pointer Lock API.
|
||||||
static const ALLOW_POINTER_LOCK = const Sandbox._internal("allow-pointer-lock");
|
static const ALLOW_POINTER_LOCK =
|
||||||
|
const Sandbox._internal("allow-pointer-lock");
|
||||||
|
|
||||||
///Allows popups (such as `window.open()`, `target="_blank"`, or `showModalDialog()`).
|
///Allows popups (such as `window.open()`, `target="_blank"`, or `showModalDialog()`).
|
||||||
///If this keyword is not used, the popup will silently fail to open.
|
///If this keyword is not used, the popup will silently fail to open.
|
||||||
@ -10810,10 +10815,12 @@ class Sandbox {
|
|||||||
|
|
||||||
///Lets the sandboxed document open new windows without those windows inheriting the sandboxing.
|
///Lets the sandboxed document open new windows without those windows inheriting the sandboxing.
|
||||||
///For example, this can safely sandbox an advertisement without forcing the same restrictions upon the page the ad links to.
|
///For example, this can safely sandbox an advertisement without forcing the same restrictions upon the page the ad links to.
|
||||||
static const ALLOW_POPUPS_TO_ESCAPE_SANDBOX = const Sandbox._internal("allow-popups-to-escape-sandbox");
|
static const ALLOW_POPUPS_TO_ESCAPE_SANDBOX =
|
||||||
|
const Sandbox._internal("allow-popups-to-escape-sandbox");
|
||||||
|
|
||||||
///Lets the resource start a presentation session.
|
///Lets the resource start a presentation session.
|
||||||
static const ALLOW_PRESENTATION = const Sandbox._internal("allow-presentation");
|
static const ALLOW_PRESENTATION =
|
||||||
|
const Sandbox._internal("allow-presentation");
|
||||||
|
|
||||||
///If this token is not used, the resource is treated as being from a special origin that always fails the
|
///If this token is not used, the resource is treated as being from a special origin that always fails the
|
||||||
///same-origin policy (potentially preventing access to data storage/cookies and some JavaScript APIs).
|
///same-origin policy (potentially preventing access to data storage/cookies and some JavaScript APIs).
|
||||||
@ -10823,13 +10830,15 @@ class Sandbox {
|
|||||||
static const ALLOW_SCRIPTS = const Sandbox._internal("allow-scripts");
|
static const ALLOW_SCRIPTS = const Sandbox._internal("allow-scripts");
|
||||||
|
|
||||||
///Lets the resource navigate the top-level browsing context (the one named `_top`).
|
///Lets the resource navigate the top-level browsing context (the one named `_top`).
|
||||||
static const ALLOW_TOP_NAVIGATION = const Sandbox._internal("allow-top-navigation");
|
static const ALLOW_TOP_NAVIGATION =
|
||||||
|
const Sandbox._internal("allow-top-navigation");
|
||||||
|
|
||||||
///Lets the resource navigate the top-level browsing context, but only if initiated by a user gesture.
|
///Lets the resource navigate the top-level browsing context, but only if initiated by a user gesture.
|
||||||
static const ALLOW_TOP_NAVIGATION_BY_USER_ACTIVATION = const Sandbox._internal("allow-top-navigation-by-user-activation");
|
static const ALLOW_TOP_NAVIGATION_BY_USER_ACTIVATION =
|
||||||
|
const Sandbox._internal("allow-top-navigation-by-user-activation");
|
||||||
|
|
||||||
bool operator ==(value) => value == _value;
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => _value.hashCode;
|
int get hashCode => _value.hashCode;
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,12 @@ class HeadlessInAppWebViewWebElement {
|
|||||||
InAppWebViewWebElement? webView;
|
InAppWebViewWebElement? webView;
|
||||||
late MethodChannel? _channel;
|
late MethodChannel? _channel;
|
||||||
|
|
||||||
HeadlessInAppWebViewWebElement({required this.id, required BinaryMessenger messenger,
|
HeadlessInAppWebViewWebElement(
|
||||||
required this.webView}) {
|
{required this.id,
|
||||||
|
required BinaryMessenger messenger,
|
||||||
|
required this.webView}) {
|
||||||
this._messenger = messenger;
|
this._messenger = messenger;
|
||||||
|
|
||||||
_channel = MethodChannel(
|
_channel = MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_headless_inappwebview_${this.id}',
|
'com.pichillilorenzo/flutter_headless_inappwebview_${this.id}',
|
||||||
const StandardMethodCodec(),
|
const StandardMethodCodec(),
|
||||||
@ -38,7 +40,8 @@ class HeadlessInAppWebViewWebElement {
|
|||||||
default:
|
default:
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'Unimplemented',
|
code: 'Unimplemented',
|
||||||
details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
details:
|
||||||
|
'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,7 +57,8 @@ class HeadlessInAppWebViewWebElement {
|
|||||||
|
|
||||||
Size getSize() {
|
Size getSize() {
|
||||||
var width = webView?.iframe.getBoundingClientRect().width.toDouble() ?? 0.0;
|
var width = webView?.iframe.getBoundingClientRect().width.toDouble() ?? 0.0;
|
||||||
var height = webView?.iframe.getBoundingClientRect().height.toDouble() ?? 0.0;
|
var height =
|
||||||
|
webView?.iframe.getBoundingClientRect().height.toDouble() ?? 0.0;
|
||||||
return Size(width, height);
|
return Size(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,4 +68,4 @@ class HeadlessInAppWebViewWebElement {
|
|||||||
webView?.dispose();
|
webView?.dispose();
|
||||||
webView = null;
|
webView = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,16 @@ class HeadlessInAppWebViewManager {
|
|||||||
const StandardMethodCodec(),
|
const StandardMethodCodec(),
|
||||||
_messenger,
|
_messenger,
|
||||||
);
|
);
|
||||||
HeadlessInAppWebViewManager._sharedChannel.setMethodCallHandler(handleMethod);
|
HeadlessInAppWebViewManager._sharedChannel
|
||||||
|
.setMethodCallHandler(handleMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> handleMethod(MethodCall call) async {
|
Future<dynamic> handleMethod(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "run":
|
case "run":
|
||||||
String id = call.arguments["id"];
|
String id = call.arguments["id"];
|
||||||
Map<String, dynamic> params = call.arguments["params"].cast<String, dynamic>();
|
Map<String, dynamic> params =
|
||||||
|
call.arguments["params"].cast<String, dynamic>();
|
||||||
run(id, params);
|
run(id, params);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -39,24 +41,24 @@ class HeadlessInAppWebViewManager {
|
|||||||
void run(String id, Map<String, dynamic> params) {
|
void run(String id, Map<String, dynamic> params) {
|
||||||
var webView = InAppWebViewWebElement(viewId: id, messenger: _messenger);
|
var webView = InAppWebViewWebElement(viewId: id, messenger: _messenger);
|
||||||
var headlessWebView = HeadlessInAppWebViewWebElement(
|
var headlessWebView = HeadlessInAppWebViewWebElement(
|
||||||
id: id,
|
id: id, messenger: _messenger, webView: webView);
|
||||||
messenger: _messenger,
|
|
||||||
webView: webView
|
|
||||||
);
|
|
||||||
WebPlatformManager.webViews.putIfAbsent(id, () => webView);
|
WebPlatformManager.webViews.putIfAbsent(id, () => webView);
|
||||||
webView.iframe.style.display = 'none';
|
webView.iframe.style.display = 'none';
|
||||||
Map<String, dynamic> initialSettings = params["initialSettings"].cast<String, dynamic>();
|
Map<String, dynamic> initialSettings =
|
||||||
|
params["initialSettings"].cast<String, dynamic>();
|
||||||
if (initialSettings.isEmpty) {
|
if (initialSettings.isEmpty) {
|
||||||
webView.initialSettings = InAppWebViewSettings();
|
webView.initialSettings = InAppWebViewSettings();
|
||||||
} else {
|
} else {
|
||||||
webView.initialSettings = InAppWebViewSettings.fromMap(initialSettings);
|
webView.initialSettings = InAppWebViewSettings.fromMap(initialSettings);
|
||||||
}
|
}
|
||||||
webView.initialUrlRequest = URLRequest.fromMap(params["initialUrlRequest"]?.cast<String, dynamic>());
|
webView.initialUrlRequest = URLRequest.fromMap(
|
||||||
|
params["initialUrlRequest"]?.cast<String, dynamic>());
|
||||||
webView.initialFile = params["initialFile"];
|
webView.initialFile = params["initialFile"];
|
||||||
webView.initialData = InAppWebViewInitialData.fromMap(params["initialData"]?.cast<String, dynamic>());
|
webView.initialData = InAppWebViewInitialData.fromMap(
|
||||||
|
params["initialData"]?.cast<String, dynamic>());
|
||||||
document.body?.append(webView.iframe);
|
document.body?.append(webView.iframe);
|
||||||
webView.prepare();
|
webView.prepare();
|
||||||
headlessWebView.onWebViewCreated();
|
headlessWebView.onWebViewCreated();
|
||||||
webView.makeInitialLoad();
|
webView.makeInitialLoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@ class InAppWebViewWebElement {
|
|||||||
late js.JsObject bridgeJsObject;
|
late js.JsObject bridgeJsObject;
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
|
|
||||||
InAppWebViewWebElement({required dynamic viewId, required BinaryMessenger messenger}) {
|
InAppWebViewWebElement(
|
||||||
|
{required dynamic viewId, required BinaryMessenger messenger}) {
|
||||||
this._viewId = viewId;
|
this._viewId = viewId;
|
||||||
this._messenger = messenger;
|
this._messenger = messenger;
|
||||||
iframe = IFrameElement()
|
iframe = IFrameElement()
|
||||||
@ -38,8 +39,10 @@ class InAppWebViewWebElement {
|
|||||||
|
|
||||||
this._channel?.setMethodCallHandler(handleMethodCall);
|
this._channel?.setMethodCallHandler(handleMethodCall);
|
||||||
|
|
||||||
bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
bridgeJsObject = js.JsObject.fromBrowserObject(
|
||||||
bridgeJsObject['webViews'][_viewId] = bridgeJsObject.callMethod("createFlutterInAppWebView", [_viewId, iframe.id]);
|
js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
||||||
|
bridgeJsObject['webViews'][_viewId] = bridgeJsObject
|
||||||
|
.callMethod("createFlutterInAppWebView", [_viewId, iframe.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles method calls over the MethodChannel of this plugin.
|
/// Handles method calls over the MethodChannel of this plugin.
|
||||||
@ -48,7 +51,8 @@ class InAppWebViewWebElement {
|
|||||||
case "getIFrameId":
|
case "getIFrameId":
|
||||||
return iframe.id;
|
return iframe.id;
|
||||||
case "loadUrl":
|
case "loadUrl":
|
||||||
URLRequest urlRequest = URLRequest.fromMap(call.arguments["urlRequest"].cast<String, dynamic>())!;
|
URLRequest urlRequest = URLRequest.fromMap(
|
||||||
|
call.arguments["urlRequest"].cast<String, dynamic>())!;
|
||||||
await loadUrl(urlRequest: urlRequest);
|
await loadUrl(urlRequest: urlRequest);
|
||||||
break;
|
break;
|
||||||
case "loadData":
|
case "loadData":
|
||||||
@ -84,7 +88,8 @@ class InAppWebViewWebElement {
|
|||||||
case "getSettings":
|
case "getSettings":
|
||||||
return await settings.toMap();
|
return await settings.toMap();
|
||||||
case "setSettings":
|
case "setSettings":
|
||||||
InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap(call.arguments["settings"].cast<String, dynamic>());
|
InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap(
|
||||||
|
call.arguments["settings"].cast<String, dynamic>());
|
||||||
setSettings(newSettings);
|
setSettings(newSettings);
|
||||||
break;
|
break;
|
||||||
case "dispose":
|
case "dispose":
|
||||||
@ -93,7 +98,8 @@ class InAppWebViewWebElement {
|
|||||||
default:
|
default:
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'Unimplemented',
|
code: 'Unimplemented',
|
||||||
details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
details:
|
||||||
|
'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,13 +114,17 @@ class InAppWebViewWebElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
iframe.allow = settings.iframeAllow ?? iframe.allow;
|
iframe.allow = settings.iframeAllow ?? iframe.allow;
|
||||||
iframe.allowFullscreen = settings.iframeAllowFullscreen ?? iframe.allowFullscreen;
|
iframe.allowFullscreen =
|
||||||
iframe.referrerPolicy = settings.iframeReferrerPolicy?.toValue() ?? iframe.referrerPolicy;
|
settings.iframeAllowFullscreen ?? iframe.allowFullscreen;
|
||||||
|
iframe.referrerPolicy =
|
||||||
|
settings.iframeReferrerPolicy?.toValue() ?? iframe.referrerPolicy;
|
||||||
iframe.name = settings.iframeName ?? iframe.name;
|
iframe.name = settings.iframeName ?? iframe.name;
|
||||||
iframe.csp = settings.iframeCsp ?? iframe.csp;
|
iframe.csp = settings.iframeCsp ?? iframe.csp;
|
||||||
|
|
||||||
if (settings.iframeSandbox != null && settings.iframeSandbox != Sandbox.ALLOW_ALL) {
|
if (settings.iframeSandbox != null &&
|
||||||
iframe.setAttribute("sandbox", settings.iframeSandbox!.map((e) => e.toValue()).join(" "));
|
settings.iframeSandbox != Sandbox.ALLOW_ALL) {
|
||||||
|
iframe.setAttribute(
|
||||||
|
"sandbox", settings.iframeSandbox!.map((e) => e.toValue()).join(" "));
|
||||||
} else if (settings.iframeSandbox == Sandbox.ALLOW_ALL) {
|
} else if (settings.iframeSandbox == Sandbox.ALLOW_ALL) {
|
||||||
iframe.removeAttribute("sandbox");
|
iframe.removeAttribute("sandbox");
|
||||||
} else if (sandbox != Sandbox.values) {
|
} else if (sandbox != Sandbox.values) {
|
||||||
@ -143,23 +153,26 @@ class InAppWebViewWebElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<HttpRequest> _makeRequest(URLRequest urlRequest, {bool? withCredentials, String? responseType, String? mimeType, void onProgress(ProgressEvent e)?}) {
|
Future<HttpRequest> _makeRequest(URLRequest urlRequest,
|
||||||
return HttpRequest.request(
|
{bool? withCredentials,
|
||||||
urlRequest.url?.toString() ?? 'about:blank',
|
String? responseType,
|
||||||
|
String? mimeType,
|
||||||
|
void onProgress(ProgressEvent e)?}) {
|
||||||
|
return HttpRequest.request(urlRequest.url?.toString() ?? 'about:blank',
|
||||||
method: urlRequest.method,
|
method: urlRequest.method,
|
||||||
requestHeaders: urlRequest.headers,
|
requestHeaders: urlRequest.headers,
|
||||||
sendData: urlRequest.body,
|
sendData: urlRequest.body,
|
||||||
withCredentials: withCredentials,
|
withCredentials: withCredentials,
|
||||||
responseType: responseType,
|
responseType: responseType,
|
||||||
mimeType: mimeType,
|
mimeType: mimeType,
|
||||||
onProgress: onProgress
|
onProgress: onProgress);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _convertHttpResponseToData(HttpRequest httpRequest) {
|
String _convertHttpResponseToData(HttpRequest httpRequest) {
|
||||||
final String contentType =
|
final String contentType =
|
||||||
httpRequest.getResponseHeader('content-type') ?? 'text/html';
|
httpRequest.getResponseHeader('content-type') ?? 'text/html';
|
||||||
return 'data:$contentType,' + Uri.encodeFull(httpRequest.responseText ?? '');
|
return 'data:$contentType,' +
|
||||||
|
Uri.encodeFull(httpRequest.responseText ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadUrl({required URLRequest urlRequest}) async {
|
Future<void> loadUrl({required URLRequest urlRequest}) async {
|
||||||
@ -171,7 +184,8 @@ class InAppWebViewWebElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadData({required String data, String mimeType = "text/html"}) async {
|
Future<void> loadData(
|
||||||
|
{required String data, String mimeType = "text/html"}) async {
|
||||||
iframe.src = 'data:$mimeType,' + Uri.encodeFull(data);
|
iframe.src = 'data:$mimeType,' + Uri.encodeFull(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +261,8 @@ class InAppWebViewWebElement {
|
|||||||
if (settings.iframeSandbox != newSettings.iframeSandbox) {
|
if (settings.iframeSandbox != newSettings.iframeSandbox) {
|
||||||
var sandbox = newSettings.iframeSandbox;
|
var sandbox = newSettings.iframeSandbox;
|
||||||
if (sandbox != null && sandbox != Sandbox.ALLOW_ALL) {
|
if (sandbox != null && sandbox != Sandbox.ALLOW_ALL) {
|
||||||
iframe.setAttribute("sandbox", sandbox.map((e) => e.toValue()).join(" "));
|
iframe.setAttribute(
|
||||||
|
"sandbox", sandbox.map((e) => e.toValue()).join(" "));
|
||||||
} else if (sandbox == Sandbox.ALLOW_ALL) {
|
} else if (sandbox == Sandbox.ALLOW_ALL) {
|
||||||
iframe.removeAttribute("sandbox");
|
iframe.removeAttribute("sandbox");
|
||||||
}
|
}
|
||||||
@ -263,33 +278,24 @@ class InAppWebViewWebElement {
|
|||||||
void onLoadStart(String url) async {
|
void onLoadStart(String url) async {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
|
|
||||||
var obj = {
|
var obj = {"url": url};
|
||||||
"url": url
|
|
||||||
};
|
|
||||||
await _channel?.invokeMethod("onLoadStart", obj);
|
await _channel?.invokeMethod("onLoadStart", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLoadStop(String url) async {
|
void onLoadStop(String url) async {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
var obj = {
|
var obj = {"url": url};
|
||||||
"url": url
|
|
||||||
};
|
|
||||||
await _channel?.invokeMethod("onLoadStop", obj);
|
await _channel?.invokeMethod("onLoadStop", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdateVisitedHistory(String url) async {
|
void onUpdateVisitedHistory(String url) async {
|
||||||
var obj = {
|
var obj = {"url": url};
|
||||||
"url": url
|
|
||||||
};
|
|
||||||
await _channel?.invokeMethod("onUpdateVisitedHistory", obj);
|
await _channel?.invokeMethod("onUpdateVisitedHistory", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onScrollChanged(int x, int y) async {
|
void onScrollChanged(int x, int y) async {
|
||||||
var obj = {
|
var obj = {"x": x, "y": y};
|
||||||
"x": x,
|
|
||||||
"y": y
|
|
||||||
};
|
|
||||||
await _channel?.invokeMethod("onScrollChanged", obj);
|
await _channel?.invokeMethod("onScrollChanged", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,14 +316,12 @@ class InAppWebViewWebElement {
|
|||||||
default:
|
default:
|
||||||
messageLevel = 1;
|
messageLevel = 1;
|
||||||
}
|
}
|
||||||
var obj = {
|
var obj = {"messageLevel": messageLevel, "message": message};
|
||||||
"messageLevel": messageLevel,
|
|
||||||
"message": message
|
|
||||||
};
|
|
||||||
await _channel?.invokeMethod("onConsoleMessage", obj);
|
await _channel?.invokeMethod("onConsoleMessage", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> onCreateWindow(int windowId, String url, String? target, String? windowFeatures) async {
|
Future<bool?> onCreateWindow(
|
||||||
|
int windowId, String url, String? target, String? windowFeatures) async {
|
||||||
Map<String, dynamic> windowFeaturesMap = {};
|
Map<String, dynamic> windowFeaturesMap = {};
|
||||||
List<String> features = windowFeatures?.split(",") ?? [];
|
List<String> features = windowFeatures?.split(",") ?? [];
|
||||||
for (var feature in features) {
|
for (var feature in features) {
|
||||||
@ -336,10 +340,7 @@ class InAppWebViewWebElement {
|
|||||||
var obj = {
|
var obj = {
|
||||||
"windowId": windowId,
|
"windowId": windowId,
|
||||||
"isForMainFrame": true,
|
"isForMainFrame": true,
|
||||||
"request": {
|
"request": {"url": url, "method": "GET"},
|
||||||
"url": url,
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
"windowFeatures": windowFeaturesMap
|
"windowFeatures": windowFeaturesMap
|
||||||
};
|
};
|
||||||
return await _channel?.invokeMethod("onCreateWindow", obj);
|
return await _channel?.invokeMethod("onCreateWindow", obj);
|
||||||
@ -354,9 +355,7 @@ class InAppWebViewWebElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onPrint(String? url) async {
|
void onPrint(String? url) async {
|
||||||
var obj = {
|
var obj = {"url": url};
|
||||||
"url": url
|
|
||||||
};
|
|
||||||
|
|
||||||
await _channel?.invokeMethod("onPrint", obj);
|
await _channel?.invokeMethod("onPrint", obj);
|
||||||
}
|
}
|
||||||
@ -370,18 +369,13 @@ class InAppWebViewWebElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onTitleChanged(String? title) async {
|
void onTitleChanged(String? title) async {
|
||||||
var obj = {
|
var obj = {"title": title};
|
||||||
"title": title
|
|
||||||
};
|
|
||||||
|
|
||||||
await _channel?.invokeMethod("onTitleChanged", obj);
|
await _channel?.invokeMethod("onTitleChanged", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onZoomScaleChanged(double oldScale, double newScale) async {
|
void onZoomScaleChanged(double oldScale, double newScale) async {
|
||||||
var obj = {
|
var obj = {"oldScale": oldScale, "newScale": newScale};
|
||||||
"oldScale": oldScale,
|
|
||||||
"newScale": newScale
|
|
||||||
};
|
|
||||||
|
|
||||||
await _channel?.invokeMethod("onZoomScaleChanged", obj);
|
await _channel?.invokeMethod("onZoomScaleChanged", obj);
|
||||||
}
|
}
|
||||||
@ -393,10 +387,11 @@ class InAppWebViewWebElement {
|
|||||||
if (WebPlatformManager.webViews.containsKey(_viewId)) {
|
if (WebPlatformManager.webViews.containsKey(_viewId)) {
|
||||||
WebPlatformManager.webViews.remove(_viewId);
|
WebPlatformManager.webViews.remove(_viewId);
|
||||||
}
|
}
|
||||||
bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
bridgeJsObject = js.JsObject.fromBrowserObject(
|
||||||
|
js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
||||||
var webViews = bridgeJsObject['webViews'] as js.JsObject;
|
var webViews = bridgeJsObject['webViews'] as js.JsObject;
|
||||||
if (webViews.hasProperty(_viewId)) {
|
if (webViews.hasProperty(_viewId)) {
|
||||||
webViews.deleteProperty(_viewId);
|
webViews.deleteProperty(_viewId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export 'web_platform.dart';
|
export 'web_platform.dart';
|
||||||
|
@ -11,7 +11,7 @@ class PlatformUtil {
|
|||||||
|
|
||||||
PlatformUtil({required BinaryMessenger messenger}) {
|
PlatformUtil({required BinaryMessenger messenger}) {
|
||||||
this._messenger = messenger;
|
this._messenger = messenger;
|
||||||
|
|
||||||
_channel = MethodChannel(
|
_channel = MethodChannel(
|
||||||
'com.pichillilorenzo/flutter_inappwebview_platformutil',
|
'com.pichillilorenzo/flutter_inappwebview_platformutil',
|
||||||
const StandardMethodCodec(),
|
const StandardMethodCodec(),
|
||||||
@ -29,13 +29,15 @@ class PlatformUtil {
|
|||||||
default:
|
default:
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'Unimplemented',
|
code: 'Unimplemented',
|
||||||
details: 'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
details:
|
||||||
|
'flutter_inappwebview for web doesn\'t implement \'${call.method}\'',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getWebCookieExpirationDate(int timestamp) {
|
String getWebCookieExpirationDate(int timestamp) {
|
||||||
var bridgeJsObject = js.JsObject.fromBrowserObject(js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
var bridgeJsObject = js.JsObject.fromBrowserObject(
|
||||||
|
js.context[WebPlatformManager.BRIDGE_JS_OBJECT_NAME]);
|
||||||
return bridgeJsObject.callMethod("getCookieExpirationDate", [timestamp]);
|
return bridgeJsObject.callMethod("getCookieExpirationDate", [timestamp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,4 +45,4 @@ class PlatformUtil {
|
|||||||
_channel?.setMethodCallHandler(null);
|
_channel?.setMethodCallHandler(null);
|
||||||
_channel = null;
|
_channel = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart';
|
export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart';
|
||||||
|
@ -26,4 +26,4 @@ class webOnlyAssetManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signature of callbacks that have no arguments and return no data.
|
/// Signature of callbacks that have no arguments and return no data.
|
||||||
typedef VoidCallback = void Function();
|
typedef VoidCallback = void Function();
|
||||||
|
@ -1 +1 @@
|
|||||||
export 'dart:ui';
|
export 'dart:ui';
|
||||||
|
@ -12,16 +12,15 @@ import 'package:js/js.dart';
|
|||||||
///
|
///
|
||||||
/// This is used as the default implementation for [WebView] on web.
|
/// This is used as the default implementation for [WebView] on web.
|
||||||
class FlutterInAppWebViewWebPlatform {
|
class FlutterInAppWebViewWebPlatform {
|
||||||
|
|
||||||
/// Constructs a new instance of [FlutterInAppWebViewWebPlatform].
|
/// Constructs a new instance of [FlutterInAppWebViewWebPlatform].
|
||||||
FlutterInAppWebViewWebPlatform(Registrar registrar) {
|
FlutterInAppWebViewWebPlatform(Registrar registrar) {
|
||||||
ui.platformViewRegistry.registerViewFactory(
|
ui.platformViewRegistry.registerViewFactory(
|
||||||
'com.pichillilorenzo/flutter_inappwebview',
|
'com.pichillilorenzo/flutter_inappwebview', (int viewId) {
|
||||||
(int viewId) {
|
var webView =
|
||||||
var webView = InAppWebViewWebElement(viewId: viewId, messenger: registrar);
|
InAppWebViewWebElement(viewId: viewId, messenger: registrar);
|
||||||
WebPlatformManager.webViews.putIfAbsent(viewId, () => webView);
|
WebPlatformManager.webViews.putIfAbsent(viewId, () => webView);
|
||||||
return webView.iframe;
|
return webView.iframe;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void registerWith(Registrar registrar) {
|
static void registerWith(Registrar registrar) {
|
||||||
@ -34,15 +33,19 @@ class FlutterInAppWebViewWebPlatform {
|
|||||||
|
|
||||||
/// Allows assigning a function to be callable from `window.flutter_inappwebview.nativeCommunication()`
|
/// Allows assigning a function to be callable from `window.flutter_inappwebview.nativeCommunication()`
|
||||||
@JS('flutter_inappwebview.nativeCommunication')
|
@JS('flutter_inappwebview.nativeCommunication')
|
||||||
external set _nativeCommunication(Future<dynamic> Function(String method, dynamic viewId, [List? args]) f);
|
external set _nativeCommunication(
|
||||||
|
Future<dynamic> Function(String method, dynamic viewId, [List? args]) f);
|
||||||
|
|
||||||
/// Allows calling the assigned function from Dart as well.
|
/// Allows calling the assigned function from Dart as well.
|
||||||
@JS()
|
@JS()
|
||||||
external Future<dynamic> nativeCommunication(String method, dynamic viewId, [List? args]);
|
external Future<dynamic> nativeCommunication(String method, dynamic viewId,
|
||||||
|
[List? args]);
|
||||||
|
|
||||||
Future<dynamic> _dartNativeCommunication(String method, dynamic viewId, [List? args]) async {
|
Future<dynamic> _dartNativeCommunication(String method, dynamic viewId,
|
||||||
|
[List? args]) async {
|
||||||
if (WebPlatformManager.webViews.containsKey(viewId)) {
|
if (WebPlatformManager.webViews.containsKey(viewId)) {
|
||||||
var webViewHtmlElement = WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
|
var webViewHtmlElement =
|
||||||
|
WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case 'onLoadStart':
|
case 'onLoadStart':
|
||||||
var url = args![0] as String;
|
var url = args![0] as String;
|
||||||
@ -71,7 +74,8 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId, [List? a
|
|||||||
var url = args[1] as String? ?? 'about:blank';
|
var url = args[1] as String? ?? 'about:blank';
|
||||||
var target = args[2] as String?;
|
var target = args[2] as String?;
|
||||||
var windowFeatures = args[3] as String?;
|
var windowFeatures = args[3] as String?;
|
||||||
return await webViewHtmlElement.onCreateWindow(windowId, url, target, windowFeatures);
|
return await webViewHtmlElement.onCreateWindow(
|
||||||
|
windowId, url, target, windowFeatures);
|
||||||
case 'onWindowFocus':
|
case 'onWindowFocus':
|
||||||
webViewHtmlElement.onWindowFocus();
|
webViewHtmlElement.onWindowFocus();
|
||||||
break;
|
break;
|
||||||
@ -79,7 +83,7 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId, [List? a
|
|||||||
webViewHtmlElement.onWindowBlur();
|
webViewHtmlElement.onWindowBlur();
|
||||||
break;
|
break;
|
||||||
case 'onPrint':
|
case 'onPrint':
|
||||||
var url = args![0] as String?;
|
var url = args![0] as String?;
|
||||||
webViewHtmlElement.onPrint(url);
|
webViewHtmlElement.onPrint(url);
|
||||||
break;
|
break;
|
||||||
case 'onEnterFullscreen':
|
case 'onEnterFullscreen':
|
||||||
@ -99,4 +103,4 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId, [List? a
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
abstract class WebPlatformManager {
|
abstract class WebPlatformManager {
|
||||||
static final String BRIDGE_JS_OBJECT_NAME = "flutter_inappwebview";
|
static final String BRIDGE_JS_OBJECT_NAME = "flutter_inappwebview";
|
||||||
static final Map<dynamic, dynamic> webViews = {};
|
static final Map<dynamic, dynamic> webViews = {};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user