Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Expose the allowsLinkPreview property in WKWebView for iOS #5110

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
3612a84
added allowsLinkPreview to platform interface
b099l3 Mar 26, 2022
d13276f
Bump platform interface version to 1.8.2
b099l3 Mar 26, 2022
bb17b4d
added allowsLinkPreview to wkwebview
b099l3 Mar 26, 2022
e659cd5
bumped wkwebview to 2.7.2
b099l3 Mar 26, 2022
6b0ad2e
updated flutter android to use platform interface with allowsLinkPreview
b099l3 Mar 26, 2022
06ba8dd
updated flutter web to use platform interface with allowsLinkPreview
b099l3 Mar 26, 2022
4a78973
updated webview_flutter to use platform interface, wkwebview and andr…
b099l3 Mar 26, 2022
eec288f
bumped webview_flutter to 3.0.2
b099l3 Mar 26, 2022
78bec61
format changes
b099l3 Mar 26, 2022
ed14ad2
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Jul 31, 2022
baaf7d5
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 2, 2022
82be993
removed allowsLinkPreview setting in "Custom platform implementation …
b099l3 Sep 2, 2022
09ae8b6
Added tests for allowsLinkPreview
b099l3 Sep 2, 2022
9eadd8e
Changed docs comment to say not supported on all platforms
b099l3 Sep 2, 2022
023d1ff
added allowsLinkPreview to the new style and ran pigeon/gen commands
b099l3 Sep 5, 2022
6f7ef30
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 5, 2022
87382bc
formatter changes
b099l3 Sep 5, 2022
f21cac9
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 6, 2022
ebc1dec
some how the formatter doesnt like this
b099l3 Sep 6, 2022
9950af8
removed changes to android package that wont be needed
b099l3 Sep 6, 2022
920a253
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 6, 2022
b08bab3
changed to suggest docs comment - Whether pressing a link displays ...
b099l3 Sep 6, 2022
7d2f9ef
reverted changes on integration_test package
b099l3 Sep 6, 2022
9bfacc8
reverts on webview_flutter_web
b099l3 Sep 6, 2022
a413f89
changed to deps override
b099l3 Sep 6, 2022
e34c9c2
removed iOS specific default reason
b099l3 Sep 6, 2022
a69a34a
removed Dart integration test
b099l3 Sep 6, 2022
77fbc60
removed allowsLinkPreview on method channel
b099l3 Sep 6, 2022
a0ae928
updated versions of all packages that have changes
b099l3 Sep 6, 2022
8201ae4
revert of spacing from my formatter
b099l3 Sep 7, 2022
bb2d434
revert of spacing from my formatter
b099l3 Sep 7, 2022
1c5d385
revert of spacing from my formatter
b099l3 Sep 7, 2022
b8675f9
matching naming for native method
b099l3 Sep 7, 2022
8862792
Added native test for testSetAllowsLinkPreview in FWFWebViewHostApiTests
b099l3 Sep 7, 2022
f2ec62b
added dependancy overrides in examples
b099l3 Sep 7, 2022
b642bbe
reverted changes to pigeon 3.1.5
b099l3 Sep 7, 2022
1aaf428
wrong prop testing and dupe code removal
b099l3 Sep 10, 2022
f86918b
removed enableLinkPreview from webview controller
b099l3 Sep 10, 2022
d414528
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 10, 2022
9548784
removed allowsLinkPreview from websettings and method channel
b099l3 Sep 14, 2022
12f6da2
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 14, 2022
0b39035
added allowsLinkPreview back to WebSettings
b099l3 Sep 16, 2022
b0e2496
Merge branch 'main' into iain_smith/webview-wkwebview-link-preview
b099l3 Sep 16, 2022
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
3 changes: 2 additions & 1 deletion packages/webview_flutter/webview_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 3.0.5

* Adds support for the `allowsLinkPreview` property on iOS.
* Updates minimum Flutter version to 2.10.
* Fixes avoid_redundant_argument_values lint warnings and minor typos.
* Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/104231).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ dependencies:
# the parent directory to use the current plugin's version.
path: ../

# FOR TESTING ONLY. DO NOT MERGE.
dependency_overrides:
webview_flutter_android:
path: ../../webview_flutter_android
webview_flutter_platform_interface:
path: ../../webview_flutter_platform_interface
webview_flutter_wkwebview:
path: ../../webview_flutter_wkwebview

dev_dependencies:
espresso: ^0.1.0+2
flutter_driver:
Expand Down
16 changes: 16 additions & 0 deletions packages/webview_flutter/webview_flutter/lib/src/webview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class WebView extends StatefulWidget {
this.onWebResourceError,
this.debuggingEnabled = false,
this.gestureNavigationEnabled = false,
this.allowsLinkPreview = true,
this.userAgent,
this.zoomEnabled = true,
this.initialMediaPlaybackPolicy =
Expand Down Expand Up @@ -260,6 +261,13 @@ class WebView extends StatefulWidget {
/// By default `gestureNavigationEnabled` is false.
final bool gestureNavigationEnabled;

/// Whether pressing a link displays a preview of the destination for the link.
///
/// Not supported on all platforms.
///
/// By default `allowsLinkPreview` is true.
final bool allowsLinkPreview;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this type be nullable, so on Platforms that doesn't support this feature, the value is null.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not a fan of nullable bools in most cases; they are annoying to use, and in practice you generally have to pick a default to treat null as eventually anyway.

(We shouldn't say this is iOS only by the way; we should instead say it's not supported on all platforms.)

Copy link
Author

Choose a reason for hiding this comment

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

Based on the comments, assuming I should keep it as a bool and not a nullable bool. If this is wrong, let me know, and I'll change it.

Changed doc comment to 'Not supported on all platforms.'


/// The value used for the HTTP User-Agent: request header.
///
/// When null the platform's webview default is used for the User-Agent header.
Expand Down Expand Up @@ -380,6 +388,7 @@ WebSettings _webSettingsFromWidget(WebView widget) {
hasProgressTracking: widget.onProgress != null,
debuggingEnabled: widget.debuggingEnabled,
gestureNavigationEnabled: widget.gestureNavigationEnabled,
allowsLinkPreview: widget.allowsLinkPreview,
allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
userAgent: WebSetting<String?>.of(widget.userAgent),
zoomEnabled: widget.zoomEnabled,
Expand All @@ -399,13 +408,16 @@ WebSettings _clearUnchangedWebSettings(
assert(newValue.debuggingEnabled != null);
assert(newValue.userAgent != null);
assert(newValue.zoomEnabled != null);
assert(newValue.allowsLinkPreview != null);

JavascriptMode? javascriptMode;
bool? hasNavigationDelegate;
bool? hasProgressTracking;
bool? debuggingEnabled;
WebSetting<String?> userAgent = const WebSetting<String?>.absent();
bool? zoomEnabled;
bool? allowsLinkPreview;

if (currentValue.javascriptMode != newValue.javascriptMode) {
javascriptMode = newValue.javascriptMode;
}
Expand All @@ -424,6 +436,9 @@ WebSettings _clearUnchangedWebSettings(
if (currentValue.zoomEnabled != newValue.zoomEnabled) {
zoomEnabled = newValue.zoomEnabled;
}
if (currentValue.allowsLinkPreview != newValue.allowsLinkPreview) {
allowsLinkPreview = newValue.allowsLinkPreview;
}

return WebSettings(
javascriptMode: javascriptMode,
Expand All @@ -432,6 +447,7 @@ WebSettings _clearUnchangedWebSettings(
debuggingEnabled: debuggingEnabled,
userAgent: userAgent,
zoomEnabled: zoomEnabled,
allowsLinkPreview: allowsLinkPreview,
);
}

Expand Down
11 changes: 10 additions & 1 deletion packages/webview_flutter/webview_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter
description: A Flutter plugin that provides a WebView widget on Android and iOS.
repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.0.4
version: 3.0.5

environment:
sdk: ">=2.14.0 <3.0.0"
Expand All @@ -23,6 +23,15 @@ dependencies:
webview_flutter_platform_interface: ^1.9.3
webview_flutter_wkwebview: ^2.7.0

# FOR TESTING ONLY. DO NOT MERGE.
dependency_overrides:
webview_flutter_android:
path: ../webview_flutter_android
webview_flutter_platform_interface:
path: ../webview_flutter_platform_interface
webview_flutter_wkwebview:
path: ../webview_flutter_wkwebview

dev_dependencies:
build_runner: ^2.1.5
flutter_driver:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,58 @@ void main() {
});
});

group('allowsLinkPreview', () {
testWidgets('defaults to true', (WidgetTester tester) async {
await tester.pumpWidget(const WebView());

final CreationParams params = captureBuildArgs(
mockWebViewPlatform,
creationParams: true,
).single as CreationParams;

expect(params.webSettings!.allowsLinkPreview, true);
});

testWidgets('can be disabled', (WidgetTester tester) async {
await tester.pumpWidget(const WebView(
allowsLinkPreview: false,
));

final CreationParams params = captureBuildArgs(
mockWebViewPlatform,
creationParams: true,
).single as CreationParams;

expect(params.webSettings!.allowsLinkPreview, false);
});

testWidgets('can be changed', (WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

This test is failing because the allowsLinkPreview values needs to be updated at https://github.com/flutter/plugins/blob/main/packages/webview_flutter/webview_flutter/lib/src/webview.dart#L390.

Copy link
Author

Choose a reason for hiding this comment

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

I have removed allowsLinkPreview from WebSettings, I think that is correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, you still want allowsLinkPreview in WebSettings so that updates can be made to it. I would also re-add the test that were removed for it. You just need to add the updates to allowsLinkPreview in the method mentioned above. e.g.

WebSettings _clearUnchangedWebSettings(
    WebSettings currentValue, WebSettings newValue) {
  assert(currentValue.javascriptMode != null);
  /* other values */
  assert(newValue.allowsLinkPreview != null);

  JavascriptMode? javascriptMode;
  /* other values */
  bool? allowsLinkPreview;
  if (currentValue.javascriptMode != newValue.javascriptMode) {
    javascriptMode = newValue.javascriptMode;
  }
  /* other values */
  if (currentValue.allowsLinkPreview != newValue.allowsLinkPreview) {
    allowsLinkPreview = newValue.allowsLinkPreview;
  }

  return WebSettings(
    javascriptMode: javascriptMode,
    /* other values */
    allowsLinkPreview: allowsLinkPreview,
  );
}

Copy link
Author

Choose a reason for hiding this comment

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

Sorry for the misunderstanding; that's my bad. I have added it back in and made the changes

final GlobalKey key = GlobalKey();
await tester.pumpWidget(WebView(key: key));

await tester.pumpWidget(WebView(
key: key,
allowsLinkPreview: false,
));

final WebSettings enabledSettings =
verify(mockWebViewPlatformController.updateSettings(captureAny))
.captured
.last as WebSettings;
expect(enabledSettings.allowsLinkPreview, false);

await tester.pumpWidget(WebView(
key: key,
));

final WebSettings disabledSettings =
verify(mockWebViewPlatformController.updateSettings(captureAny))
.captured
.last as WebSettings;
expect(disabledSettings.allowsLinkPreview, true);
});
});

group('Custom platform implementation', () {
setUp(() {
WebView.platform = MyWebViewPlatform();
Expand Down Expand Up @@ -1143,6 +1195,7 @@ void main() {
debuggingEnabled: false,
userAgent: const WebSetting<String?>.of(null),
gestureNavigationEnabled: true,
allowsLinkPreview: true,
zoomEnabled: true,
),
)));
Expand Down Expand Up @@ -1325,6 +1378,7 @@ class MatchesWebSettings extends Matcher {
_webSettings!.debuggingEnabled == webSettings.debuggingEnabled &&
_webSettings!.gestureNavigationEnabled ==
webSettings.gestureNavigationEnabled &&
_webSettings!.allowsLinkPreview == webSettings.allowsLinkPreview &&
_webSettings!.userAgent == webSettings.userAgent &&
_webSettings!.zoomEnabled == webSettings.zoomEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.9.4

* Adds support for the `allowsLinkPreview` property on iOS.

## 1.9.3

* Updates minimum Flutter version to 2.10.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class WebSettings {
this.hasProgressTracking,
this.debuggingEnabled,
this.gestureNavigationEnabled,
this.allowsLinkPreview,
this.allowsInlineMediaPlayback,
this.zoomEnabled,
required this.userAgent,
Expand Down Expand Up @@ -125,8 +126,13 @@ class WebSettings {
/// See also: [WebView.gestureNavigationEnabled]
final bool? gestureNavigationEnabled;

/// Determines whether pressing a link displays a preview of the destination for the link in iOS.
///
/// See also: [WebView.allowsLinkPreview]
final bool? allowsLinkPreview;

@override
String toString() {
return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, hasProgressTracking: $hasProgressTracking, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback)';
return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, hasProgressTracking: $hasProgressTracking, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, allowsLinkPreview: $allowsLinkPreview, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback)';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutte
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview_flutter%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 1.9.3
version: 1.9.4

environment:
sdk: ">=2.12.0 <3.0.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 2.9.4

* Adds support for the `allowsLinkPreview` property on iOS.
* Fixes avoid_redundant_argument_values lint warnings and minor typos.
* Fixes typo in an internal method name, from `setCookieForInsances` to `setCookieForInstances`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,22 @@ - (void)testSetAllowsBackForwardNavigationGestures {
XCTAssertNil(error);
}

- (void)testSetAllowsLinkPreview {
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 setAllowsLinkPreviewForWebViewWithIdentifier:@0 isAllowed:@NO error:&error];
OCMVerify([mockWebView setAllowsLinkPreview:NO]);
XCTAssertNil(error);
}

- (void)testEvaluateJavaScript {
FWFWebView *mockWebView = OCMClassMock([FWFWebView class]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class WebView extends StatefulWidget {
this.onWebResourceError,
this.debuggingEnabled = false,
this.gestureNavigationEnabled = false,
this.allowsLinkPreview = true,
this.userAgent,
this.zoomEnabled = true,
this.initialMediaPlaybackPolicy =
Expand Down Expand Up @@ -206,6 +207,13 @@ class WebView extends StatefulWidget {
/// By default `gestureNavigationEnabled` is false.
final bool gestureNavigationEnabled;

/// Whether pressing a link displays a preview of the destination for the link.
///
/// Not supported on all platforms.
///
/// By default `allowsLinkPreview` is true, to match the default on iOS.
final bool allowsLinkPreview;

/// The value used for the HTTP User-Agent: request header.
///
/// When null the platform's webview default is used for the User-Agent header.
Expand Down Expand Up @@ -622,6 +630,7 @@ WebSettings _webSettingsFromWidget(WebView widget) {
hasProgressTracking: widget.onProgress != null,
debuggingEnabled: widget.debuggingEnabled,
gestureNavigationEnabled: widget.gestureNavigationEnabled,
allowsLinkPreview: widget.allowsLinkPreview,
allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
userAgent: WebSetting<String?>.of(widget.userAgent),
zoomEnabled: widget.zoomEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ dependencies:
# the parent directory to use the current plugin's version.
path: ../

# FOR TESTING ONLY. DO NOT MERGE.
dependency_overrides:
webview_flutter_platform_interface:
path: ../../webview_flutter_platform_interface

dev_dependencies:
espresso: ^0.1.0+2
flutter_driver:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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.
// Autogenerated from Pigeon (v3.1.5), do not edit directly.
// Autogenerated from Pigeon (v3.2.6), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import <Foundation/Foundation.h>
@protocol FlutterBinaryMessenger;
Expand Down Expand Up @@ -506,6 +506,9 @@ NSObject<FlutterMessageCodec> *FWFWKWebViewHostApiGetCodec(void);
- (void)setAllowsBackForwardForWebViewWithIdentifier:(NSNumber *)identifier
isAllowed:(NSNumber *)allow
error:(FlutterError *_Nullable *_Nonnull)error;
- (void)setAllowsLinkPreviewForWebViewWithIdentifier:(NSNumber *)identifier
isAllowed:(NSNumber *)allow
error:(FlutterError *_Nullable *_Nonnull)error;
- (void)setUserAgentForWebViewWithIdentifier:(NSNumber *)identifier
userAgent:(nullable NSString *)userAgent
error:(FlutterError *_Nullable *_Nonnull)error;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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.
// Autogenerated from Pigeon (v3.1.5), do not edit directly.
// Autogenerated from Pigeon (v3.2.6), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import "FWFGeneratedWebKitApis.h"
#import <Flutter/Flutter.h>
Expand Down Expand Up @@ -2502,6 +2502,31 @@ void FWFWKWebViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
[channel setMessageHandler:nil];
}
}
{
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setAllowsLinkPreview"
binaryMessenger:binaryMessenger
codec:FWFWKWebViewHostApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector
(setAllowsLinkPreviewForWebViewWithIdentifier:isAllowed:error:)],
@"FWFWKWebViewHostApi api (%@) doesn't respond to "
@"@selector(setAllowsLinkPreviewForWebViewWithIdentifier:isAllowed:error:)",
api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
NSNumber *arg_allow = GetNullableObjectAtIndex(args, 1);
FlutterError *error;
[api setAllowsLinkPreviewForWebViewWithIdentifier:arg_identifier
isAllowed:arg_allow
error:&error];
callback(wrapResult(nil, error));
}];
} else {
[channel setMessageHandler:nil];
}
}
{
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ - (void)reloadWebViewWithIdentifier:(nonnull NSNumber *)identifier
[[self webViewForIdentifier:identifier] setAllowsBackForwardNavigationGestures:allow.boolValue];
}

- (void)
setAllowsLinkPreviewForWebViewWithIdentifier:(nonnull NSNumber *)identifier
isAllowed:(nonnull NSNumber *)allow
error:(FlutterError *_Nullable __autoreleasing *_Nonnull)
error {
[[self webViewForIdentifier:identifier] setAllowsLinkPreview:allow.boolValue];
}

- (void)
setNavigationDelegateForWebViewWithIdentifier:(nonnull NSNumber *)identifier
delegateIdentifier:(nullable NSNumber *)navigationDelegateIdentifier
Expand All @@ -287,4 +295,5 @@ - (void)setUIDelegateForWebViewWithIdentifier:(nonnull NSNumber *)identifier
error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
return [[self webViewForIdentifier:identifier] title];
}

@end
Loading