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

[android] Add rebind method #22

Closed
wants to merge 11 commits into from

Conversation

matthova
Copy link

@matthova matthova commented Dec 9, 2022

The goal is to add an imperative method for immediately swapping the webview to a different parent. This is helpful for race conditions where it's necessary to prevent the webview's document visibility to stay 'visible'.

There are some changes in this PR to enable this functionality:

  1. adds a rebind method to re-attach the internal webview to the parent
  2. instead of attaching the webview on setWebViewKey, we attach the webview when the window is attached
  3. the view layout is not correct when it's rebound to a different view. we remeasure the view when the hierarchy changes

We'll do the iOS pr right after. The changes are just split out for ease of review. Apologies for the changes on the native side, I think there are some existing formatting issues

@nealmanaktola nealmanaktola changed the title Add rebind method [android] Add rebind method Dec 15, 2022
@nealmanaktola
Copy link

@donaldchen this is ready for review now

// Since we are moving views outside of React, the layout request might be dropped
// on a normal add/remove view
// By calling .layout directly on the parent, it'll force the layout change
// See this issue for more context: https://github.com/facebook/react-native/issues/17968

Choose a reason for hiding this comment

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

facebook/react-native#17968 (comment)

Unbelievable that this bug is still open.

Wow, same. Anyway, nice work on identifying this issue, and I'm glad calling layout directly fixes this!

MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY)
);
parent.layout(0, 0, parent.getMeasuredWidth(), parent.getMeasuredHeight());

Choose a reason for hiding this comment

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

nit: It may be slightly more readable to name the l / t / r / b parameters inline with code comments sort of like this.

parent.layout(
  0 /* left */ ,
  0 /* top */,
  parent.getMeasuredWidth() /* right */,
  parent.getMeasuredHeight() /* bottom */
);

// The chrome client was originally setup on instance creation but might be pointing to the wrong webview
// so it's reset here.
// Not entirely sure why there is a single instance of the webchrome client for all webviews?
setupWebChromeClient((ThemedReactContext) existingWebView.getContext(), existingWebView);

Choose a reason for hiding this comment

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

I'm seeing this deleted but not added back anywhere. Do we still need to call setupWebChromeClient anywhere?

Choose a reason for hiding this comment

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

Would it have to get called again in onAttachedToWindow when the webViewKey is non-null?

view.attachWebView(webView);
// Remove the default webview on instance creation
// The actual webview will be attached
WebView activeWebview = RNCWebViewMapManager.INSTANCE.getInternalWebViewMap().get(webViewKey);

Choose a reason for hiding this comment

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

nit: Can we name this something like activeInternalWebView? Looking at https://github.com/discord/react-native-webview/pull/22/files#diff-e9700631fc9fa5600d2e1ee70eb2d28aa2a1fbc695b85f99981972d3904ca485R819 , it seems that sometimes we're using the name activeWebView for the internal WebView, and sometimes we use it for the RNCWebView. That makes it a little harder for me to follow the logic sometimes

Choose a reason for hiding this comment

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

Alternatively, we could keep this one named activeWebView, and we can rename the other one to activeRncWebView

// Attach the webview to this view
view.attachWebView(internalWebView);
// Update the map accordingly
RNCWebViewMapManager.INSTANCE.getRncWebViewMap().put(webViewKey, view);

Choose a reason for hiding this comment

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

Do we also need to update RNCWebViewMapManager.viewIdMap here?

webViewKey="TEST"
source={{ uri: "https://google.ca" }}
style={{flex: 1}}

Choose a reason for hiding this comment

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

nit: we can probably delete this whitespace

<View style={{ width: 300, height: 200, borderWidth: 2, borderColor: 'red' }}>
<WebView
ref={this.googleRef}
webViewKey="TEST"

Choose a reason for hiding this comment

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

nit: Should we put "TEST" in a const, since it's used in four places in this file?

<Button
title="Bind to google"
onPress={() => {
console.log('google ref', this.googleRef);

Choose a reason for hiding this comment

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

nit: Is this console log still necessary?

<Button
title="Bind to yelp"
onPress={() => {
this.yelpRef.current.rebind('TEST');

Choose a reason for hiding this comment

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

For my understanding, with this Rebind example, is the expectation that between the Google and Yelp web pages, only one of them will show at a time, and then clicking the buttons will determine which web page appears (by determining which RNCWebView the internal WebView gets attached to)?

Copy link

Hello 👋, this PR has been opened for more than 2 months with no activity on it. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically

@github-actions github-actions bot added the Stale label Jan 15, 2024
@github-actions github-actions bot closed this Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants