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

Conversation

@amirh
Copy link
Contributor

@amirh amirh commented May 22, 2019

As a temporary step we passed these objects as maps that were sent across the method channel. This PR replaces the maps with proper Dart objects.

@amirh amirh requested a review from cyanglaz May 22, 2019 19:28
@amirh
Copy link
Contributor Author

amirh commented May 22, 2019

@nkoroste

Copy link
Contributor

@cyanglaz cyanglaz left a comment

Choose a reason for hiding this comment

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

I like this approach, I was planning to do a similar update to the image_picker as well.
Left some comments.

this.debuggingEnabled,
});

final JavascriptMode javascriptMode;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: dart doc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

final JavascriptMode javascriptMode;

/// Whether a [NavigationDelegate] should be used for this webview.
final bool hasNavigationDelegate;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit(personal opinion): useNavigationDelegate might be a better name in this case.

// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final Map<String, dynamic> updatesMap = _webSettingsToMap(settings);
if (updatesMap.isEmpty) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Another option could be assert(!updatesMap.isEmpty)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's actually legit to send a settings with all null fields to this method.

We could potentially move the short-circuting logic to webview_flutter.dart, but that requires some ugliness or maintaining an operator== for WebSettings which I'm hesitant to do from a forward-compatibility point of view(I can see us adding a list field to WebSettings, at which point naive looking webSettings==webSettings2 might actually be expensive.

JavascriptMode javascriptMode;
bool hasNavigationDelegate;
bool debuggingEnabled;
if (currentValue.javascriptMode != newValue.javascriptMode) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if the newValue.javascriptMode is null and the currentValue.javascriptMode is non-null, we are setting the old value to null. Same as below. It seems to violate the comment here:

/// Updates the webview settings.
///
/// Any non null field in `settings` will be set as the new setting value.
/// All null fields in `settings` are ignored.

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The fields in currentValue should never be null (the initial value built by _WebSettingFromWidget can never have null values).

I made it clear in the method comment and added assertions.

Copy link
Contributor

@cyanglaz cyanglaz May 22, 2019

Choose a reason for hiding this comment

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

I was thinking when the fields in newValue is null, the current implementation will set the corresponding fields in the currentValue to null. But the dart doc in the updateSetting in the WebViewSettings class mentioned that the null fields should be ignored.

Copy link
Contributor

@cyanglaz cyanglaz May 22, 2019

Choose a reason for hiding this comment

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

After offline discussion with @amirh; we confirmed that the fields in both currentValue and newValue could never be null because they are both created by _webSettingsFromWidget which takes the setting from the WebView widget, which should never be null. Can possibly add assertions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added more assertions here

Choose a reason for hiding this comment

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

Sorry I'm a bit confused about this entire method, what it's purpose? It looks to me that the return type will almost always be a copy of newValue unless the fields of each equal, in which case it will return a new WebSettings object with some null fields - is that really what you want?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the platform side, at least for the platforms we've been dealing with so far, all these "settings" are updated by imperative calls, e.g on Android we call setJavaScriptEnabled to update the "javascriptMode".
We do not want to call setJavaScriptEnabled every time the widget is rebuilt, so we're keeping track of the previous javascriptMode value we had the last time the widget was built, and only when we see that the value has changed we call setJavaScriptEnabled.

The WebSettings class groups these kind of settings. We track the previous WebSettings value, and when the widget is rebuilt this method(_webSettingsUpdate) computes a WebSettings instance that only includes the values that have changed and has to be updated on the platform side. This value is then passed to WebViewPlatform.updateSettings which ignores the null fields and updates the platform webview with the new values for all non-null fields in WebSettings.

Choose a reason for hiding this comment

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

I see, so you're nullfying all the unchanged fields on purpose because WebViewPlatform.updateSettings expects it that way. I guess the method name confused me, it's more like nullfyUnchangedValues which is a horrible name I agree. Anyway, thanks for the detailed explanation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to _clearUnchangedWebSettings

/// Whether to enable the platform's webview content debugging tools.
///
/// See also: [WebView.debuggingEnabled].
final bool debuggingEnabled;

Choose a reason for hiding this comment

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

nit: isDebuggingEnabled

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it makes sense to keep it consistent with the WebView parameter name, if we want to change both it will be a breaking change at this point.

Note that as far as I know the Flutter style guide doesn't prefer an "is" prefix for flags.


/// The initial set of JavaScript channels that are configured for this webview.
///
/// For each value in this list the platform's webview should make sure that a corresponding

Choose a reason for hiding this comment

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

nit: "in this set"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}


static Map<String, dynamic> creationParamsToMap(CreationParams creationParams) {

Choose a reason for hiding this comment

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

add dart doc or should it be private?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

JavascriptMode javascriptMode;
bool hasNavigationDelegate;
bool debuggingEnabled;
if (currentValue.javascriptMode != newValue.javascriptMode) {

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

@amirh amirh left a comment

Choose a reason for hiding this comment

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

Thanks! PTAL

JavascriptMode javascriptMode;
bool hasNavigationDelegate;
bool debuggingEnabled;
if (currentValue.javascriptMode != newValue.javascriptMode) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The fields in currentValue should never be null (the initial value built by _WebSettingFromWidget can never have null values).

I made it clear in the method comment and added assertions.

// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final Map<String, dynamic> updatesMap = _webSettingsToMap(settings);
if (updatesMap.isEmpty) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's actually legit to send a settings with all null fields to this method.

We could potentially move the short-circuting logic to webview_flutter.dart, but that requires some ugliness or maintaining an operator== for WebSettings which I'm hesitant to do from a forward-compatibility point of view(I can see us adding a list field to WebSettings, at which point naive looking webSettings==webSettings2 might actually be expensive.

}


static Map<String, dynamic> creationParamsToMap(CreationParams creationParams) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


/// The initial set of JavaScript channels that are configured for this webview.
///
/// For each value in this list the platform's webview should make sure that a corresponding
Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

/// Whether to enable the platform's webview content debugging tools.
///
/// See also: [WebView.debuggingEnabled].
final bool debuggingEnabled;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it makes sense to keep it consistent with the WebView parameter name, if we want to change both it will be a breaking change at this point.

Note that as far as I know the Flutter style guide doesn't prefer an "is" prefix for flags.

this.debuggingEnabled,
});

final JavascriptMode javascriptMode;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@cyanglaz cyanglaz left a comment

Choose a reason for hiding this comment

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

download

@amirh
Copy link
Contributor Author

amirh commented May 22, 2019

Thanks.
Waiting for @nkoroste's approval before merging.

JavascriptMode javascriptMode;
bool hasNavigationDelegate;
bool debuggingEnabled;
if (currentValue.javascriptMode != newValue.javascriptMode) {

Choose a reason for hiding this comment

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

I see, so you're nullfying all the unchanged fields on purpose because WebViewPlatform.updateSettings expects it that way. I guess the method name confused me, it's more like nullfyUnchangedValues which is a horrible name I agree. Anyway, thanks for the detailed explanation.

amirh added 5 commits May 28, 2019 15:37
As a temporary step we passed these objects as maps that were sent
across the method channel. This PR replaces the maps with proper Dart objects.
@amirh amirh force-pushed the multi_platform_webview_2 branch from 9cecb36 to b05a5c6 Compare May 28, 2019 22:38
@amirh amirh merged commit 4d69253 into flutter:master May 29, 2019
amirh added a commit that referenced this pull request May 30, 2019
…ce (#1645)

This is a followup for #1618 and #1624, and moves all of the plugins.flutter.io/webview method channel calls behind the platform channel, which allows a third party package to provide a new platform implementation for all of these methods.

See the description for #1618 for more details.

The last remaining part is the plugins.flutter.io/cookie_manager channel which I'm leaving for a followup PR.
amirh added a commit that referenced this pull request May 31, 2019
This is a followup for #1618, #1624, and #1645, and moves the plugins.flutter.io/cookie_manager method channel behind the platform interface which allows a third party package to provide a new platform implementation the cooke manager.

See the description for #1618 for more details.

Following this PR all platform specific code can be replaced by an external package.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants