Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.6.0

* Adds support to enable debugging of web contents on the latest versions of WebKit. See
`WebKitWebViewController.setInspectable`.

## 3.5.0

* Adds support to limit navigation to pages within the app’s domain. See
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,4 +464,20 @@ - (void)testContentInsetsSumAlwaysZeroAfterSetFrame {
XCTAssertTrue(feq(webView.scrollView.contentInset.bottom, -insetToAdjust.bottom));
XCTAssertTrue(CGRectEqualToRect(webView.frame, CGRectMake(0, 0, 300, 100)));
}

- (void)testSetInspectable API_AVAILABLE(ios(16.4), macos(13.3), tvos(16.4)) {
FWFWebView *mockWebView = OCMClassMock([FWFWebView class]);

FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init];
[instanceManager addDartCreatedInstance:mockWebView withIdentifier:0];

FWFWebViewHostApiImpl *hostAPI = [[FWFWebViewHostApiImpl alloc]
initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger))
instanceManager:instanceManager];

FlutterError *error;
[hostAPI setInspectableForWebViewWithIdentifier:@0 inspectable:@YES error:&error];
OCMVerify([mockWebView setInspectable:YES]);
XCTAssertNil(error);
}
@end
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,9 @@ NSObject<FlutterMessageCodec> *FWFWKWebViewHostApiGetCodec(void);
javaScriptString:(NSString *)javaScriptString
completion:(void (^)(id _Nullable,
FlutterError *_Nullable))completion;
- (void)setInspectableForWebViewWithIdentifier:(NSNumber *)identifier
inspectable:(NSNumber *)inspectable
error:(FlutterError *_Nullable *_Nonnull)error;
@end

extern void FWFWKWebViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,31 @@ void FWFWKWebViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
[channel setMessageHandler:nil];
}
}
{
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setInspectable"
binaryMessenger:binaryMessenger
codec:FWFWKWebViewHostApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(setInspectableForWebViewWithIdentifier:
inspectable:error:)],
@"FWFWKWebViewHostApi api (%@) doesn't respond to "
@"@selector(setInspectableForWebViewWithIdentifier:inspectable:error:)",
api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
NSNumber *arg_inspectable = GetNullableObjectAtIndex(args, 1);
FlutterError *error;
[api setInspectableForWebViewWithIdentifier:arg_identifier
inspectable:arg_inspectable
error:&error];
callback(wrapResult(nil, error));
}];
} else {
[channel setMessageHandler:nil];
}
}
}
NSObject<FlutterMessageCodec> *FWFWKUIDelegateHostApiGetCodec(void) {
static FlutterStandardMessageCodec *sSharedObject = nil;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ - (void)evaluateJavaScriptForWebViewWithIdentifier:(nonnull NSNumber *)identifie
}];
}

- (void)setInspectableForWebViewWithIdentifier:(NSNumber *)identifier
inspectable:(NSNumber *)inspectable
error:(FlutterError *_Nullable *_Nonnull)error {
if (@available(macOS 13.3, iOS 16.4, tvOS 16.4, *)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWFUnsupportedVersionError has been added.

[[self webViewForIdentifier:identifier] setInspectable:inspectable.boolValue];
} else {
*error = [FlutterError errorWithCode:@"FWFUnsupportedVersionError"
message:@"setInspectable is only supported on versions 16.4+."
details:nil];
}
}

- (void)goBackForWebViewWithIdentifier:(nonnull NSNumber *)identifier
error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
[[self webViewForIdentifier:identifier] goBack];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ class ObjectOrIdentifier {

class _WKWebsiteDataStoreHostApiCodec extends StandardMessageCodec {
const _WKWebsiteDataStoreHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKWebsiteDataTypeEnumData) {
Expand Down Expand Up @@ -961,6 +962,7 @@ class UIScrollViewHostApi {

class _WKWebViewConfigurationHostApiCodec extends StandardMessageCodec {
const _WKWebViewConfigurationHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKAudiovisualMediaTypeEnumData) {
Expand Down Expand Up @@ -1150,6 +1152,7 @@ abstract class WKWebViewConfigurationFlutterApi {

class _WKUserContentControllerHostApiCodec extends StandardMessageCodec {
const _WKUserContentControllerHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKUserScriptData) {
Expand Down Expand Up @@ -1435,6 +1438,7 @@ class WKScriptMessageHandlerHostApi {

class _WKScriptMessageHandlerFlutterApiCodec extends StandardMessageCodec {
const _WKScriptMessageHandlerFlutterApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKScriptMessageData) {
Expand Down Expand Up @@ -1537,6 +1541,7 @@ class WKNavigationDelegateHostApi {

class _WKNavigationDelegateFlutterApiCodec extends StandardMessageCodec {
const _WKNavigationDelegateFlutterApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSErrorData) {
Expand Down Expand Up @@ -1768,6 +1773,7 @@ abstract class WKNavigationDelegateFlutterApi {

class _NSObjectHostApiCodec extends StandardMessageCodec {
const _NSObjectHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSKeyValueObservingOptionsEnumData) {
Expand Down Expand Up @@ -1881,6 +1887,7 @@ class NSObjectHostApi {

class _NSObjectFlutterApiCodec extends StandardMessageCodec {
const _NSObjectFlutterApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSKeyValueChangeKeyEnumData) {
Expand Down Expand Up @@ -1982,6 +1989,7 @@ abstract class NSObjectFlutterApi {

class _WKWebViewHostApiCodec extends StandardMessageCodec {
const _WKWebViewHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSErrorData) {
Expand Down Expand Up @@ -2527,6 +2535,28 @@ class WKWebViewHostApi {
return replyList[0];
}
}

Future<void> setInspectable(int arg_identifier, bool arg_inspectable) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.WKWebViewHostApi.setInspectable', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel
.send(<Object?>[arg_identifier, arg_inspectable]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
}

/// Mirror of WKUIDelegate.
Expand Down Expand Up @@ -2567,6 +2597,7 @@ class WKUIDelegateHostApi {

class _WKUIDelegateFlutterApiCodec extends StandardMessageCodec {
const _WKUIDelegateFlutterApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSUrlRequestData) {
Expand Down Expand Up @@ -2703,6 +2734,7 @@ abstract class WKUIDelegateFlutterApi {

class _WKHttpCookieStoreHostApiCodec extends StandardMessageCodec {
const _WKHttpCookieStoreHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSHttpCookieData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,24 @@ class WKWebView extends UIView {
);
}

/// Enables debugging of web contents (HTML / CSS / JavaScript) in the
/// underlying WebView.
///
/// This flag can be enabled in order to facilitate debugging of web layouts
/// and JavaScript code running inside WebViews. Please refer to [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview?language=objc).
/// documentation for the debugging guide.
///
/// Starting from macOS version 13.3, iOS version 16.4, and tvOS version 16.4,
/// the default value is set to false.
///
/// Defaults to true in previous versions.
Future<void> setInspectable(bool inspectable) {
return _webViewApi.setInspectableForInstances(
this,
inspectable,
);
}

@override
WKWebView copy() {
return WKWebView.detached(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,17 @@ class WKWebViewHostApiImpl extends WKWebViewHostApi {
}
}

/// Calls [setInspectable] with the ids of the provided object instances.
Future<void> setInspectableForInstances(
WKWebView instance,
bool inspectable,
) async {
return setInspectable(
instanceManager.getIdentifier(instance)!,
inspectable,
);
}

/// Calls [setNavigationDelegate] with the ids of the provided object instances.
Future<void> setNavigationDelegateForInstances(
WKWebView instance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,18 @@ class WebKitWebViewController extends PlatformWebViewController {
) async {
_onPermissionRequestCallback = onPermissionRequest;
}

/// Whether to enable tools for debugging the current WKWebView content.
///
/// It needs to be activated in each WKWebView where you want to enable it.
///
/// Starting from macOS version 13.3, iOS version 16.4, and tvOS version 16.4,
/// the default value is set to false.
///
/// Defaults to true in previous versions.
Future<void> setInspectable(bool inspectable) {
return _webView.setInspectable(inspectable);
}
}

/// An implementation of [JavaScriptChannelParams] with the WebKit api.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,9 @@ abstract class WKWebViewHostApi {
@ObjCSelector('evaluateJavaScriptForWebViewWithIdentifier:javaScriptString:')
@async
Object? evaluateJavaScript(int identifier, String javaScriptString);

@ObjCSelector('setInspectableForWebViewWithIdentifier:inspectable:')
void setInspectable(int identifier, bool inspectable);
}

/// Mirror of WKUIDelegate.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.5.0
version: 3.6.0

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,15 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView {
returnValue: _i5.Future<Object?>.value(),
) as _i5.Future<Object?>);
@override
_i5.Future<void> setInspectable(bool? inspectable) => (super.noSuchMethod(
Invocation.method(
#setInspectable,
[inspectable],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i4.WKWebView copy() => (super.noSuchMethod(
Invocation.method(
#copy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
// ignore_for_file: avoid_relative_lib_imports
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;

import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:webview_flutter_wkwebview/src/common/web_kit.g.dart';

class _TestWKWebsiteDataStoreHostApiCodec extends StandardMessageCodec {
const _TestWKWebsiteDataStoreHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKWebsiteDataTypeEnumData) {
Expand Down Expand Up @@ -333,6 +334,7 @@ abstract class TestUIScrollViewHostApi {

class _TestWKWebViewConfigurationHostApiCodec extends StandardMessageCodec {
const _TestWKWebViewConfigurationHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKAudiovisualMediaTypeEnumData) {
Expand Down Expand Up @@ -511,6 +513,7 @@ abstract class TestWKWebViewConfigurationHostApi {

class _TestWKUserContentControllerHostApiCodec extends StandardMessageCodec {
const _TestWKUserContentControllerHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is WKUserScriptData) {
Expand Down Expand Up @@ -867,6 +870,7 @@ abstract class TestWKNavigationDelegateHostApi {

class _TestNSObjectHostApiCodec extends StandardMessageCodec {
const _TestNSObjectHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSKeyValueObservingOptionsEnumData) {
Expand Down Expand Up @@ -995,6 +999,7 @@ abstract class TestNSObjectHostApi {

class _TestWKWebViewHostApiCodec extends StandardMessageCodec {
const _TestWKWebViewHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSErrorData) {
Expand Down Expand Up @@ -1145,6 +1150,8 @@ abstract class TestWKWebViewHostApi {

Future<Object?> evaluateJavaScript(int identifier, String javaScriptString);

void setInspectable(int identifier, bool inspectable);

static void setup(TestWKWebViewHostApi? api,
{BinaryMessenger? binaryMessenger}) {
{
Expand Down Expand Up @@ -1575,6 +1582,31 @@ abstract class TestWKWebViewHostApi {
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.WKWebViewHostApi.setInspectable', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.WKWebViewHostApi.setInspectable was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_identifier = (args[0] as int?);
assert(arg_identifier != null,
'Argument for dev.flutter.pigeon.WKWebViewHostApi.setInspectable was null, expected non-null int.');
final bool? arg_inspectable = (args[1] as bool?);
assert(arg_inspectable != null,
'Argument for dev.flutter.pigeon.WKWebViewHostApi.setInspectable was null, expected non-null bool.');
api.setInspectable(arg_identifier!, arg_inspectable!);
return <Object?>[];
});
}
}
}
}

Expand Down Expand Up @@ -1617,6 +1649,7 @@ abstract class TestWKUIDelegateHostApi {

class _TestWKHttpCookieStoreHostApiCodec extends StandardMessageCodec {
const _TestWKHttpCookieStoreHostApiCodec();

@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is NSHttpCookieData) {
Expand Down
Loading