blob: 7cd29da3e71630cb667cd6b981618e0a4062a753 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import '../common/instance_manager.dart';
import '../common/web_kit.g.dart';
import '../foundation/foundation.dart';
import 'web_kit.dart';
export '../common/web_kit.g.dart' show WKNavigationType;
Iterable<WKWebsiteDataTypeEnumData> _toWKWebsiteDataTypeEnumData(
Iterable<WKWebsiteDataType> types) {
return types.map<WKWebsiteDataTypeEnumData>((WKWebsiteDataType type) {
late final WKWebsiteDataTypeEnum value;
switch (type) {
case WKWebsiteDataType.cookies:
value = WKWebsiteDataTypeEnum.cookies;
break;
case WKWebsiteDataType.memoryCache:
value = WKWebsiteDataTypeEnum.memoryCache;
break;
case WKWebsiteDataType.diskCache:
value = WKWebsiteDataTypeEnum.diskCache;
break;
case WKWebsiteDataType.offlineWebApplicationCache:
value = WKWebsiteDataTypeEnum.offlineWebApplicationCache;
break;
case WKWebsiteDataType.localStorage:
value = WKWebsiteDataTypeEnum.localStorage;
break;
case WKWebsiteDataType.sessionStorage:
value = WKWebsiteDataTypeEnum.sessionStorage;
break;
case WKWebsiteDataType.webSQLDatabases:
value = WKWebsiteDataTypeEnum.webSQLDatabases;
break;
case WKWebsiteDataType.indexedDBDatabases:
value = WKWebsiteDataTypeEnum.indexedDBDatabases;
break;
}
return WKWebsiteDataTypeEnumData(value: value);
});
}
extension _NSHttpCookieConverter on NSHttpCookie {
NSHttpCookieData toNSHttpCookieData() {
final Iterable<NSHttpCookiePropertyKey> keys = properties.keys;
return NSHttpCookieData(
propertyKeys: keys.map<NSHttpCookiePropertyKeyEnumData>(
(NSHttpCookiePropertyKey key) {
return key.toNSHttpCookiePropertyKeyEnumData();
},
).toList(),
propertyValues: keys
.map<Object>((NSHttpCookiePropertyKey key) => properties[key]!)
.toList(),
);
}
}
extension _WKNavigationActionPolicyConverter on WKNavigationActionPolicy {
WKNavigationActionPolicyEnumData toWKNavigationActionPolicyEnumData() {
return WKNavigationActionPolicyEnumData(
value: WKNavigationActionPolicyEnum.values.firstWhere(
(WKNavigationActionPolicyEnum element) => element.name == name,
),
);
}
}
extension _NSHttpCookiePropertyKeyConverter on NSHttpCookiePropertyKey {
NSHttpCookiePropertyKeyEnumData toNSHttpCookiePropertyKeyEnumData() {
late final NSHttpCookiePropertyKeyEnum value;
switch (this) {
case NSHttpCookiePropertyKey.comment:
value = NSHttpCookiePropertyKeyEnum.comment;
break;
case NSHttpCookiePropertyKey.commentUrl:
value = NSHttpCookiePropertyKeyEnum.commentUrl;
break;
case NSHttpCookiePropertyKey.discard:
value = NSHttpCookiePropertyKeyEnum.discard;
break;
case NSHttpCookiePropertyKey.domain:
value = NSHttpCookiePropertyKeyEnum.domain;
break;
case NSHttpCookiePropertyKey.expires:
value = NSHttpCookiePropertyKeyEnum.expires;
break;
case NSHttpCookiePropertyKey.maximumAge:
value = NSHttpCookiePropertyKeyEnum.maximumAge;
break;
case NSHttpCookiePropertyKey.name:
value = NSHttpCookiePropertyKeyEnum.name;
break;
case NSHttpCookiePropertyKey.originUrl:
value = NSHttpCookiePropertyKeyEnum.originUrl;
break;
case NSHttpCookiePropertyKey.path:
value = NSHttpCookiePropertyKeyEnum.path;
break;
case NSHttpCookiePropertyKey.port:
value = NSHttpCookiePropertyKeyEnum.port;
break;
case NSHttpCookiePropertyKey.sameSitePolicy:
value = NSHttpCookiePropertyKeyEnum.sameSitePolicy;
break;
case NSHttpCookiePropertyKey.secure:
value = NSHttpCookiePropertyKeyEnum.secure;
break;
case NSHttpCookiePropertyKey.value:
value = NSHttpCookiePropertyKeyEnum.value;
break;
case NSHttpCookiePropertyKey.version:
value = NSHttpCookiePropertyKeyEnum.version;
break;
}
return NSHttpCookiePropertyKeyEnumData(value: value);
}
}
extension _WKUserScriptInjectionTimeConverter on WKUserScriptInjectionTime {
WKUserScriptInjectionTimeEnumData toWKUserScriptInjectionTimeEnumData() {
late final WKUserScriptInjectionTimeEnum value;
switch (this) {
case WKUserScriptInjectionTime.atDocumentStart:
value = WKUserScriptInjectionTimeEnum.atDocumentStart;
break;
case WKUserScriptInjectionTime.atDocumentEnd:
value = WKUserScriptInjectionTimeEnum.atDocumentEnd;
break;
}
return WKUserScriptInjectionTimeEnumData(value: value);
}
}
Iterable<WKAudiovisualMediaTypeEnumData> _toWKAudiovisualMediaTypeEnumData(
Iterable<WKAudiovisualMediaType> types,
) {
return types
.map<WKAudiovisualMediaTypeEnumData>((WKAudiovisualMediaType type) {
late final WKAudiovisualMediaTypeEnum value;
switch (type) {
case WKAudiovisualMediaType.none:
value = WKAudiovisualMediaTypeEnum.none;
break;
case WKAudiovisualMediaType.audio:
value = WKAudiovisualMediaTypeEnum.audio;
break;
case WKAudiovisualMediaType.video:
value = WKAudiovisualMediaTypeEnum.video;
break;
case WKAudiovisualMediaType.all:
value = WKAudiovisualMediaTypeEnum.all;
break;
}
return WKAudiovisualMediaTypeEnumData(value: value);
});
}
extension _NavigationActionDataConverter on WKNavigationActionData {
WKNavigationAction toNavigationAction() {
return WKNavigationAction(
request: request.toNSUrlRequest(),
targetFrame: targetFrame.toWKFrameInfo(),
navigationType: navigationType,
);
}
}
extension _WKFrameInfoDataConverter on WKFrameInfoData {
WKFrameInfo toWKFrameInfo() {
return WKFrameInfo(isMainFrame: isMainFrame);
}
}
extension _NSUrlRequestDataConverter on NSUrlRequestData {
NSUrlRequest toNSUrlRequest() {
return NSUrlRequest(
url: url,
httpBody: httpBody,
httpMethod: httpMethod,
allHttpHeaderFields: allHttpHeaderFields.cast(),
);
}
}
extension _WKNSErrorDataConverter on NSErrorData {
NSError toNSError() {
return NSError(
domain: domain,
code: code,
localizedDescription: localizedDescription,
);
}
}
extension _WKScriptMessageDataConverter on WKScriptMessageData {
WKScriptMessage toWKScriptMessage() {
return WKScriptMessage(name: name, body: body);
}
}
extension _WKUserScriptConverter on WKUserScript {
WKUserScriptData toWKUserScriptData() {
return WKUserScriptData(
source: source,
injectionTime: injectionTime.toWKUserScriptInjectionTimeEnumData(),
isMainFrameOnly: isMainFrameOnly,
);
}
}
extension _NSUrlRequestConverter on NSUrlRequest {
NSUrlRequestData toNSUrlRequestData() {
return NSUrlRequestData(
url: url,
httpMethod: httpMethod,
httpBody: httpBody,
allHttpHeaderFields: allHttpHeaderFields,
);
}
}
/// Handles initialization of Flutter APIs for WebKit.
class WebKitFlutterApis {
/// Constructs a [WebKitFlutterApis].
@visibleForTesting
WebKitFlutterApis({
BinaryMessenger? binaryMessenger,
InstanceManager? instanceManager,
}) : _binaryMessenger = binaryMessenger,
navigationDelegate = WKNavigationDelegateFlutterApiImpl(
instanceManager: instanceManager,
),
scriptMessageHandler = WKScriptMessageHandlerFlutterApiImpl(
instanceManager: instanceManager,
),
uiDelegate = WKUIDelegateFlutterApiImpl(
instanceManager: instanceManager,
),
webViewConfiguration = WKWebViewConfigurationFlutterApiImpl(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
);
static WebKitFlutterApis _instance = WebKitFlutterApis();
/// Sets the global instance containing the Flutter Apis for the WebKit library.
@visibleForTesting
static set instance(WebKitFlutterApis instance) {
_instance = instance;
}
/// Global instance containing the Flutter Apis for the WebKit library.
static WebKitFlutterApis get instance {
return _instance;
}
final BinaryMessenger? _binaryMessenger;
bool _hasBeenSetUp = false;
/// Flutter Api for [WKNavigationDelegate].
@visibleForTesting
final WKNavigationDelegateFlutterApiImpl navigationDelegate;
/// Flutter Api for [WKScriptMessageHandler].
@visibleForTesting
final WKScriptMessageHandlerFlutterApiImpl scriptMessageHandler;
/// Flutter Api for [WKUIDelegate].
@visibleForTesting
final WKUIDelegateFlutterApiImpl uiDelegate;
/// Flutter Api for [WKWebViewConfiguration].
@visibleForTesting
final WKWebViewConfigurationFlutterApiImpl webViewConfiguration;
/// Ensures all the Flutter APIs have been set up to receive calls from native code.
void ensureSetUp() {
if (!_hasBeenSetUp) {
WKNavigationDelegateFlutterApi.setup(
navigationDelegate,
binaryMessenger: _binaryMessenger,
);
WKScriptMessageHandlerFlutterApi.setup(
scriptMessageHandler,
binaryMessenger: _binaryMessenger,
);
WKUIDelegateFlutterApi.setup(
uiDelegate,
binaryMessenger: _binaryMessenger,
);
WKWebViewConfigurationFlutterApi.setup(
webViewConfiguration,
binaryMessenger: _binaryMessenger,
);
_hasBeenSetUp = true;
}
}
}
/// Host api implementation for [WKWebSiteDataStore].
class WKWebsiteDataStoreHostApiImpl extends WKWebsiteDataStoreHostApi {
/// Constructs a [WebsiteDataStoreHostApiImpl].
WKWebsiteDataStoreHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [createFromWebViewConfiguration] with the ids of the provided object instances.
Future<void> createFromWebViewConfigurationForInstances(
WKWebsiteDataStore instance,
WKWebViewConfiguration configuration,
) {
return createFromWebViewConfiguration(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(configuration)!,
);
}
/// Calls [createDefaultDataStore] with the ids of the provided object instances.
Future<void> createDefaultDataStoreForInstances(
WKWebsiteDataStore instance,
) {
return createDefaultDataStore(
instanceManager.addDartCreatedInstance(instance),
);
}
/// Calls [removeDataOfTypes] with the ids of the provided object instances.
Future<bool> removeDataOfTypesForInstances(
WKWebsiteDataStore instance,
Set<WKWebsiteDataType> dataTypes, {
required double secondsModifiedSinceEpoch,
}) {
return removeDataOfTypes(
instanceManager.getIdentifier(instance)!,
_toWKWebsiteDataTypeEnumData(dataTypes).toList(),
secondsModifiedSinceEpoch,
);
}
}
/// Host api implementation for [WKScriptMessageHandler].
class WKScriptMessageHandlerHostApiImpl extends WKScriptMessageHandlerHostApi {
/// Constructs a [WKScriptMessageHandlerHostApiImpl].
WKScriptMessageHandlerHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [create] with the ids of the provided object instances.
Future<void> createForInstances(WKScriptMessageHandler instance) {
return create(instanceManager.addDartCreatedInstance(instance));
}
}
/// Flutter api implementation for [WKScriptMessageHandler].
class WKScriptMessageHandlerFlutterApiImpl
extends WKScriptMessageHandlerFlutterApi {
/// Constructs a [WKScriptMessageHandlerFlutterApiImpl].
WKScriptMessageHandlerFlutterApiImpl({InstanceManager? instanceManager})
: instanceManager = instanceManager ?? NSObject.globalInstanceManager;
/// Maintains instances stored to communicate with native language objects.
final InstanceManager instanceManager;
WKScriptMessageHandler _getHandler(int identifier) {
return instanceManager.getInstanceWithWeakReference(identifier)!;
}
@override
void didReceiveScriptMessage(
int identifier,
int userContentControllerIdentifier,
WKScriptMessageData message,
) {
_getHandler(identifier).didReceiveScriptMessage(
instanceManager.getInstanceWithWeakReference(
userContentControllerIdentifier,
)! as WKUserContentController,
message.toWKScriptMessage(),
);
}
}
/// Host api implementation for [WKPreferences].
class WKPreferencesHostApiImpl extends WKPreferencesHostApi {
/// Constructs a [WKPreferencesHostApiImpl].
WKPreferencesHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [createFromWebViewConfiguration] with the ids of the provided object instances.
Future<void> createFromWebViewConfigurationForInstances(
WKPreferences instance,
WKWebViewConfiguration configuration,
) {
return createFromWebViewConfiguration(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(configuration)!,
);
}
/// Calls [setJavaScriptEnabled] with the ids of the provided object instances.
Future<void> setJavaScriptEnabledForInstances(
WKPreferences instance,
bool enabled,
) {
return setJavaScriptEnabled(
instanceManager.getIdentifier(instance)!,
enabled,
);
}
}
/// Host api implementation for [WKHttpCookieStore].
class WKHttpCookieStoreHostApiImpl extends WKHttpCookieStoreHostApi {
/// Constructs a [WKHttpCookieStoreHostApiImpl].
WKHttpCookieStoreHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [createFromWebsiteDataStore] with the ids of the provided object instances.
Future<void> createFromWebsiteDataStoreForInstances(
WKHttpCookieStore instance,
WKWebsiteDataStore dataStore,
) {
return createFromWebsiteDataStore(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(dataStore)!,
);
}
/// Calls [setCookie] with the ids of the provided object instances.
Future<void> setCookieForInstances(
WKHttpCookieStore instance,
NSHttpCookie cookie,
) {
return setCookie(
instanceManager.getIdentifier(instance)!,
cookie.toNSHttpCookieData(),
);
}
}
/// Host api implementation for [WKUserContentController].
class WKUserContentControllerHostApiImpl
extends WKUserContentControllerHostApi {
/// Constructs a [WKUserContentControllerHostApiImpl].
WKUserContentControllerHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [createFromWebViewConfiguration] with the ids of the provided object instances.
Future<void> createFromWebViewConfigurationForInstances(
WKUserContentController instance,
WKWebViewConfiguration configuration,
) {
return createFromWebViewConfiguration(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(configuration)!,
);
}
/// Calls [addScriptMessageHandler] with the ids of the provided object instances.
Future<void> addScriptMessageHandlerForInstances(
WKUserContentController instance,
WKScriptMessageHandler handler,
String name,
) {
return addScriptMessageHandler(
instanceManager.getIdentifier(instance)!,
instanceManager.getIdentifier(handler)!,
name,
);
}
/// Calls [removeScriptMessageHandler] with the ids of the provided object instances.
Future<void> removeScriptMessageHandlerForInstances(
WKUserContentController instance,
String name,
) {
return removeScriptMessageHandler(
instanceManager.getIdentifier(instance)!,
name,
);
}
/// Calls [removeAllScriptMessageHandlers] with the ids of the provided object instances.
Future<void> removeAllScriptMessageHandlersForInstances(
WKUserContentController instance,
) {
return removeAllScriptMessageHandlers(
instanceManager.getIdentifier(instance)!,
);
}
/// Calls [addUserScript] with the ids of the provided object instances.
Future<void> addUserScriptForInstances(
WKUserContentController instance,
WKUserScript userScript,
) {
return addUserScript(
instanceManager.getIdentifier(instance)!,
userScript.toWKUserScriptData(),
);
}
/// Calls [removeAllUserScripts] with the ids of the provided object instances.
Future<void> removeAllUserScriptsForInstances(
WKUserContentController instance,
) {
return removeAllUserScripts(instanceManager.getIdentifier(instance)!);
}
}
/// Host api implementation for [WKWebViewConfiguration].
class WKWebViewConfigurationHostApiImpl extends WKWebViewConfigurationHostApi {
/// Constructs a [WKWebViewConfigurationHostApiImpl].
WKWebViewConfigurationHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [create] with the ids of the provided object instances.
Future<void> createForInstances(WKWebViewConfiguration instance) {
return create(instanceManager.addDartCreatedInstance(instance));
}
/// Calls [createFromWebView] with the ids of the provided object instances.
Future<void> createFromWebViewForInstances(
WKWebViewConfiguration instance,
WKWebView webView,
) {
return createFromWebView(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(webView)!,
);
}
/// Calls [setAllowsInlineMediaPlayback] with the ids of the provided object instances.
Future<void> setAllowsInlineMediaPlaybackForInstances(
WKWebViewConfiguration instance,
bool allow,
) {
return setAllowsInlineMediaPlayback(
instanceManager.getIdentifier(instance)!,
allow,
);
}
/// Calls [setMediaTypesRequiringUserActionForPlayback] with the ids of the provided object instances.
Future<void> setMediaTypesRequiringUserActionForPlaybackForInstances(
WKWebViewConfiguration instance,
Set<WKAudiovisualMediaType> types,
) {
return setMediaTypesRequiringUserActionForPlayback(
instanceManager.getIdentifier(instance)!,
_toWKAudiovisualMediaTypeEnumData(types).toList(),
);
}
}
/// Flutter api implementation for [WKWebViewConfiguration].
@immutable
class WKWebViewConfigurationFlutterApiImpl
extends WKWebViewConfigurationFlutterApi {
/// Constructs a [WKWebViewConfigurationFlutterApiImpl].
WKWebViewConfigurationFlutterApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager;
/// Receives binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with native language objects.
final InstanceManager instanceManager;
@override
void create(int identifier) {
instanceManager.addHostCreatedInstance(
WKWebViewConfiguration.detached(
binaryMessenger: binaryMessenger,
instanceManager: instanceManager,
),
identifier,
);
}
}
/// Host api implementation for [WKUIDelegate].
class WKUIDelegateHostApiImpl extends WKUIDelegateHostApi {
/// Constructs a [WKUIDelegateHostApiImpl].
WKUIDelegateHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [create] with the ids of the provided object instances.
Future<void> createForInstances(WKUIDelegate instance) async {
return create(instanceManager.addDartCreatedInstance(instance));
}
}
/// Flutter api implementation for [WKUIDelegate].
class WKUIDelegateFlutterApiImpl extends WKUIDelegateFlutterApi {
/// Constructs a [WKUIDelegateFlutterApiImpl].
WKUIDelegateFlutterApiImpl({InstanceManager? instanceManager})
: instanceManager = instanceManager ?? NSObject.globalInstanceManager;
/// Maintains instances stored to communicate with native language objects.
final InstanceManager instanceManager;
WKUIDelegate _getDelegate(int identifier) {
return instanceManager.getInstanceWithWeakReference(identifier)!;
}
@override
void onCreateWebView(
int identifier,
int webViewIdentifier,
int configurationIdentifier,
WKNavigationActionData navigationAction,
) {
final void Function(WKWebView, WKWebViewConfiguration, WKNavigationAction)?
function = _getDelegate(identifier).onCreateWebView;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
instanceManager.getInstanceWithWeakReference(configurationIdentifier)!
as WKWebViewConfiguration,
navigationAction.toNavigationAction(),
);
}
}
/// Host api implementation for [WKNavigationDelegate].
class WKNavigationDelegateHostApiImpl extends WKNavigationDelegateHostApi {
/// Constructs a [WKNavigationDelegateHostApiImpl].
WKNavigationDelegateHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [create] with the ids of the provided object instances.
Future<void> createForInstances(WKNavigationDelegate instance) async {
return create(instanceManager.addDartCreatedInstance(instance));
}
}
/// Flutter api implementation for [WKNavigationDelegate].
class WKNavigationDelegateFlutterApiImpl
extends WKNavigationDelegateFlutterApi {
/// Constructs a [WKNavigationDelegateFlutterApiImpl].
WKNavigationDelegateFlutterApiImpl({InstanceManager? instanceManager})
: instanceManager = instanceManager ?? NSObject.globalInstanceManager;
/// Maintains instances stored to communicate with native language objects.
final InstanceManager instanceManager;
WKNavigationDelegate _getDelegate(int identifier) {
return instanceManager.getInstanceWithWeakReference(identifier)!;
}
@override
void didFinishNavigation(
int identifier,
int webViewIdentifier,
String? url,
) {
final void Function(WKWebView, String?)? function =
_getDelegate(identifier).didFinishNavigation;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
url,
);
}
@override
Future<WKNavigationActionPolicyEnumData> decidePolicyForNavigationAction(
int identifier,
int webViewIdentifier,
WKNavigationActionData navigationAction,
) async {
final Future<WKNavigationActionPolicy> Function(
WKWebView,
WKNavigationAction navigationAction,
)? function = _getDelegate(identifier).decidePolicyForNavigationAction;
if (function == null) {
return WKNavigationActionPolicyEnumData(
value: WKNavigationActionPolicyEnum.allow,
);
}
final WKNavigationActionPolicy policy = await function(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
navigationAction.toNavigationAction(),
);
return policy.toWKNavigationActionPolicyEnumData();
}
@override
void didFailNavigation(
int identifier,
int webViewIdentifier,
NSErrorData error,
) {
final void Function(WKWebView, NSError)? function =
_getDelegate(identifier).didFailNavigation;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
error.toNSError(),
);
}
@override
void didFailProvisionalNavigation(
int identifier,
int webViewIdentifier,
NSErrorData error,
) {
final void Function(WKWebView, NSError)? function =
_getDelegate(identifier).didFailProvisionalNavigation;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
error.toNSError(),
);
}
@override
void didStartProvisionalNavigation(
int identifier,
int webViewIdentifier,
String? url,
) {
final void Function(WKWebView, String?)? function =
_getDelegate(identifier).didStartProvisionalNavigation;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
url,
);
}
@override
void webViewWebContentProcessDidTerminate(
int identifier,
int webViewIdentifier,
) {
final void Function(WKWebView)? function =
_getDelegate(identifier).webViewWebContentProcessDidTerminate;
function?.call(
instanceManager.getInstanceWithWeakReference(webViewIdentifier)!
as WKWebView,
);
}
}
/// Host api implementation for [WKWebView].
class WKWebViewHostApiImpl extends WKWebViewHostApi {
/// Constructs a [WKWebViewHostApiImpl].
WKWebViewHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;
/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
/// Calls [create] with the ids of the provided object instances.
Future<void> createForInstances(
WKWebView instance,
WKWebViewConfiguration configuration,
) {
return create(
instanceManager.addDartCreatedInstance(instance),
instanceManager.getIdentifier(configuration)!,
);
}
/// Calls [loadRequest] with the ids of the provided object instances.
Future<void> loadRequestForInstances(
WKWebView webView,
NSUrlRequest request,
) {
return loadRequest(
instanceManager.getIdentifier(webView)!,
request.toNSUrlRequestData(),
);
}
/// Calls [loadHtmlString] with the ids of the provided object instances.
Future<void> loadHtmlStringForInstances(
WKWebView instance,
String string,
String? baseUrl,
) {
return loadHtmlString(
instanceManager.getIdentifier(instance)!,
string,
baseUrl,
);
}
/// Calls [loadFileUrl] with the ids of the provided object instances.
Future<void> loadFileUrlForInstances(
WKWebView instance,
String url,
String readAccessUrl,
) {
return loadFileUrl(
instanceManager.getIdentifier(instance)!,
url,
readAccessUrl,
);
}
/// Calls [loadFlutterAsset] with the ids of the provided object instances.
Future<void> loadFlutterAssetForInstances(WKWebView instance, String key) {
return loadFlutterAsset(
instanceManager.getIdentifier(instance)!,
key,
);
}
/// Calls [canGoBack] with the ids of the provided object instances.
Future<bool> canGoBackForInstances(WKWebView instance) {
return canGoBack(instanceManager.getIdentifier(instance)!);
}
/// Calls [canGoForward] with the ids of the provided object instances.
Future<bool> canGoForwardForInstances(WKWebView instance) {
return canGoForward(instanceManager.getIdentifier(instance)!);
}
/// Calls [goBack] with the ids of the provided object instances.
Future<void> goBackForInstances(WKWebView instance) {
return goBack(instanceManager.getIdentifier(instance)!);
}
/// Calls [goForward] with the ids of the provided object instances.
Future<void> goForwardForInstances(WKWebView instance) {
return goForward(instanceManager.getIdentifier(instance)!);
}
/// Calls [reload] with the ids of the provided object instances.
Future<void> reloadForInstances(WKWebView instance) {
return reload(instanceManager.getIdentifier(instance)!);
}
/// Calls [getUrl] with the ids of the provided object instances.
Future<String?> getUrlForInstances(WKWebView instance) {
return getUrl(instanceManager.getIdentifier(instance)!);
}
/// Calls [getTitle] with the ids of the provided object instances.
Future<String?> getTitleForInstances(WKWebView instance) {
return getTitle(instanceManager.getIdentifier(instance)!);
}
/// Calls [getEstimatedProgress] with the ids of the provided object instances.
Future<double> getEstimatedProgressForInstances(WKWebView instance) {
return getEstimatedProgress(instanceManager.getIdentifier(instance)!);
}
/// Calls [setAllowsBackForwardNavigationGestures] with the ids of the provided object instances.
Future<void> setAllowsBackForwardNavigationGesturesForInstances(
WKWebView instance,
bool allow,
) {
return setAllowsBackForwardNavigationGestures(
instanceManager.getIdentifier(instance)!,
allow,
);
}
/// Calls [setCustomUserAgent] with the ids of the provided object instances.
Future<void> setCustomUserAgentForInstances(
WKWebView instance,
String? userAgent,
) {
return setCustomUserAgent(
instanceManager.getIdentifier(instance)!,
userAgent,
);
}
/// Calls [evaluateJavaScript] with the ids of the provided object instances.
Future<Object?> evaluateJavaScriptForInstances(
WKWebView instance,
String javaScriptString,
) async {
try {
final Object? result = await evaluateJavaScript(
instanceManager.getIdentifier(instance)!,
javaScriptString,
);
return result;
} on PlatformException catch (exception) {
if (exception.details is! NSErrorData) {
rethrow;
}
throw PlatformException(
code: exception.code,
message: exception.message,
stacktrace: exception.stacktrace,
details: (exception.details as NSErrorData).toNSError(),
);
}
}
/// Calls [setNavigationDelegate] with the ids of the provided object instances.
Future<void> setNavigationDelegateForInstances(
WKWebView instance,
WKNavigationDelegate? delegate,
) {
return setNavigationDelegate(
instanceManager.getIdentifier(instance)!,
delegate != null ? instanceManager.getIdentifier(delegate)! : null,
);
}
/// Calls [setUIDelegate] with the ids of the provided object instances.
Future<void> setUIDelegateForInstances(
WKWebView instance,
WKUIDelegate? delegate,
) {
return setUIDelegate(
instanceManager.getIdentifier(instance)!,
delegate != null ? instanceManager.getIdentifier(delegate)! : null,
);
}
}