Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[webview_flutter] Opt-in feature that javaScript can automatically open window for iOS platform #8505

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class WebView extends StatefulWidget {
AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
this.allowsInlineMediaPlayback = false,
this.backgroundColor,
this.javaScriptCanOpenWindowsAutomatically = false,
});

static WebViewPlatform? _platform;
Expand Down Expand Up @@ -295,6 +296,12 @@ class WebView extends StatefulWidget {
/// default [backgroundColor] is `null`.
final Color? backgroundColor;

/// Whether JavaScript can open windows automatically.
///
/// This affects pop-up windows and window.open() in JavaScript.
/// The default value is false.
final bool javaScriptCanOpenWindowsAutomatically;

@override
State<StatefulWidget> createState() => _WebViewState();
}
Expand Down Expand Up @@ -381,6 +388,8 @@ WebSettings _webSettingsFromWidget(WebView widget) {
allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
userAgent: WebSetting<String?>.of(widget.userAgent),
zoomEnabled: widget.zoomEnabled,
javaScriptCanOpenWindowsAutomatically:
widget.javaScriptCanOpenWindowsAutomatically,
);
}

Expand All @@ -402,6 +411,8 @@ WebSettings _clearUnchangedWebSettings(
bool? debuggingEnabled;
WebSetting<String?> userAgent = const WebSetting<String?>.absent();
bool? zoomEnabled;
bool? javaScriptCanOpenWindowsAutomatically;

if (currentValue.javascriptMode != newValue.javascriptMode) {
javascriptMode = newValue.javascriptMode;
}
Expand All @@ -420,6 +431,11 @@ WebSettings _clearUnchangedWebSettings(
if (currentValue.zoomEnabled != newValue.zoomEnabled) {
zoomEnabled = newValue.zoomEnabled;
}
if (currentValue.javaScriptCanOpenWindowsAutomatically !=
newValue.javaScriptCanOpenWindowsAutomatically) {
javaScriptCanOpenWindowsAutomatically =
newValue.javaScriptCanOpenWindowsAutomatically;
}

return WebSettings(
javascriptMode: javascriptMode,
Expand All @@ -428,6 +444,8 @@ WebSettings _clearUnchangedWebSettings(
debuggingEnabled: debuggingEnabled,
userAgent: userAgent,
zoomEnabled: zoomEnabled,
javaScriptCanOpenWindowsAutomatically:
javaScriptCanOpenWindowsAutomatically,
);
}

Expand Down Expand Up @@ -779,6 +797,19 @@ class WebViewController {
Future<int> getScrollY() {
return _webViewPlatformController.getScrollY();
}

/// Sets whether JavaScript can open windows automatically.
///
/// The default value is false.
Future<void> setJavaScriptCanOpenWindowsAutomatically(bool enabled) async {
if (_settings.javaScriptCanOpenWindowsAutomatically == enabled) {
return;
}
final WebSettings newSettings = _settings.copyWith(
javaScriptCanOpenWindowsAutomatically: enabled,
);
await _updateSettings(newSettings);
}
}

/// Manages cookies pertaining to all [WebView]s.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ class WebViewController {
) {
return platform.setOnScrollPositionChange(onScrollPositionChange);
}

/// Sets whether JavaScript can open windows automatically.
///
/// The default value is false.
Future<void> setJavaScriptCanOpenWindowsAutomatically(bool enabled) {
return platform.setJavaScriptCanOpenWindowsAutomatically(enabled);
}
}

/// Permissions request when web content requests access to protected resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,11 @@ class AndroidWebViewController extends PlatformWebViewController {
_onJavaScriptPrompt = onJavaScriptTextInputDialog;
return _webChromeClient.setSynchronousReturnValueForOnJsPrompt(true);
}

@override
Future<void> setJavaScriptCanOpenWindowsAutomatically(bool enabled) async {
await _webView.settings.setJavaScriptCanOpenWindowsAutomatically(enabled);
}
}

/// Android implementation of [PlatformWebViewPermissionRequest].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class WebSettings {
this.allowsInlineMediaPlayback,
this.zoomEnabled,
required this.userAgent,
this.javaScriptCanOpenWindowsAutomatically,
});

/// The JavaScript execution mode to be used by the webview.
Expand Down Expand Up @@ -125,8 +126,13 @@ class WebSettings {
/// See also: [WebView.gestureNavigationEnabled]
final bool? gestureNavigationEnabled;

/// Whether JavaScript can open windows automatically.
///
/// This setting affects pop-up windows and window.open() in JavaScript.
final bool? javaScriptCanOpenWindowsAutomatically;

@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, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback, javaScriptCanOpenWindowsAutomatically: $javaScriptCanOpenWindowsAutomatically)';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,15 @@ abstract class PlatformWebViewController extends PlatformInterface {
'setOnJavaScriptTextInputDialog is not implemented on the current platform',
);
}

/// Sets whether JavaScript can open windows automatically.
///
/// The default value is false.
Future<void> setJavaScriptCanOpenWindowsAutomatically(bool enabled) {
throw UnimplementedError(
'setJavaScriptCanOpenWindowsAutomatically is not implemented.',
);
}
}

/// Describes the parameters necessary for registering a JavaScript channel.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@ - (void)testSetJavaScriptEnabled {
OCMVerify([mockPreferences setJavaScriptEnabled:YES]);
XCTAssertNil(error);
}

- (void)testSetJavaScriptCanOpenWindowsAutomatically {
FWFPreferencesHostApiImpl *hostAPI = [[FWFPreferencesHostApiImpl alloc]
initWithInstanceManager:self.instanceManager];
[self.instanceManager addDartCreatedInstance:self.mockPreferences
withIdentifier:0];

FlutterError *error;
[hostAPI setJavaScriptCanOpenWindowsAutomaticallyForPreferencesWithIdentifier:0
isEnabled:YES
error:&error];
OCMVerify([self.mockPreferences setJavaScriptCanOpenWindowsAutomatically:YES]);
XCTAssertNil(error);
}
@end
Loading
Loading