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

Add headers prop to Android WebViews #5494

Closed
wants to merge 4 commits into from

Conversation

mtostenson
Copy link

Related to issue #5418

This is a follow-up to this previous pull request.

Adds a new ReactProp 'urlWithHeaders' to Android WebViews that takes an object with a 'url' string and a 'headers' map.

[Update] Adds a new prop 'source' to Android WebViews

{
   html: string,
   url: string,
   headers: map<string, string>,
}

Update: resolves TODO 8495359

@facebook-github-bot
Copy link
Contributor

@mtostenson updated the pull request.

@@ -127,12 +133,23 @@ var WebView = React.createClass({
domStorageEnabled = this.props.domStorageEnabledAndroid;
}

var urlProp, urlWithHeaders;

Choose a reason for hiding this comment

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

space-after-keywords: Keyword "if" must be followed by whitespace.

@facebook-github-bot
Copy link
Contributor

@mtostenson updated the pull request.

@satya164
Copy link
Contributor

LGTM

cc @mkonicek @nicklockwood

@facebook-github-bot
Copy link
Contributor

@mtostenson updated the pull request.

@satya164
Copy link
Contributor

@vjeux @mkonicek The bot seems to be replying to PRs even when nothing changed :(

@@ -280,6 +283,19 @@ public void setHtml(WebView view, @Nullable String html) {
}
}

@ReactProp(name = "headers")
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think adding a third prop that calls loadUrl is a good idea, there's actually to TODO comment in setUrl to do something about setUrl and setHtml. It could be a good time to fix that.

We could do something like a source prop to the native component that takes an object like

{
  html: string,
  url: string,
  headers: Map<string, string>,
}

and then if html is defined, use it, else use url and if headers are defined, add them. That way changing between html, url and url with headers won't the make webview load the wrong thing because of the order props were set.

Edit: Just noticed something similar was already mentioned in the original PR :)

@satya164
Copy link
Contributor

A single object will be really great, as Nick suggested. But we also have to support the old way for a while before removing them. We can show console.warn for a release it two before completely removing it.

@mtostenson
Copy link
Author

That seems similar to the first solution I proposed. I would be in favor of a single source prop, but I agree @satya164 we will have to include warnings for both the url and html props that they will be deprecated.

This deprecates url and html props for Android WebView.
source prop takes an object { html: string, url: string, headers: map<string, string> }
@facebook-github-bot
Copy link
Contributor

@mtostenson updated the pull request.

console.warn('html is deprecated. Use source instead.');
htmlProp = this.props.html;
} else if(this.props.url) {
console.warn('url is deprecated. Use source instead.');

Choose a reason for hiding this comment

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

space-after-keywords: Keyword "if" must be followed by whitespace.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer a bit more informative warnings. When I see YellowBox with this warning, it'll not be obvious to me regarding where it's coming from and what to do.

Some thing like,

WebView: url prop is deprecated. Use the source prop instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since this pattern comes up a lot, perhaps we can come up with a standard way to mark props as deprecated that includes the component info? I think someone mentioned such a thing already exists in React.js?

Copy link
Contributor

Choose a reason for hiding this comment

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

@nicklockwood That'll be awesome. Though I'm not aware of any such functionality in React. Maybe we could do this with propTypes?

Copy link
Contributor

Choose a reason for hiding this comment

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

Something like,

function deprecatedPropType(checker, message) {
    return (props, propName, componentName) => {
        console.warn(`${componentName}: ${propName} prop is deprecated. ${mesage}`);
        return checker(props, propName, componentName);
    };
}

propTypes = {
    url: deprecatedPropType(React.PropTypes.string, "Use source prop instead.")
}

Copy link
Author

Choose a reason for hiding this comment

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

This is a good idea, do you have a recommendation for where this deprecatedPropType method should go so that any component can access it?

Copy link
Contributor

Choose a reason for hiding this comment

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

It should be a module in its own right, so it can be imported from anywhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

There doesn't seem to be anything in react to do this. Something like https://github.com/react-bootstrap/react-prop-types/blob/master/src/deprecated.js would be nice, it could eventually be integrated with the website too.

If you like I can submit a PR that implements that and change the places we deprecate props manually.

Copy link
Author

Choose a reason for hiding this comment

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

Sounds good to me, I'll leave the warnings as they are for the now.

@nicklockwood
Copy link
Contributor

I really like this solution :-)

urlProp = this.props.url;
} else {
sourceProp = this.props.source;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

In the interests of code cleanliness, you can probably just remove the native html and url props completely, and implement support for them on the JS side by using them to build the source object. Something like:

var source = this.props.source || {};
if (this.props.html) {
  console.warn('html is deprecated. Use source instead.');
  source.html = this.props.html;
} else if (this.props.url) {
  console.warn('url is deprecated. Use source instead.');
  source.url = this.props.url;
}

<RCTWebView
    ref={RCT_WEBVIEW_REF}
    key="webViewKey"
    style={webViewStyles}
    source={source} // no need for url/html any more
    ...
/>

Copy link
Author

Choose a reason for hiding this comment

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

Heh, that's a really good idea.

@janicduplessis
Copy link
Contributor

👍

@janicduplessis
Copy link
Contributor

It would be great to make the source prop work on iOS too but that could be in another PR.

Improve deprecated prop warnings.
@facebook-github-bot
Copy link
Contributor

@mtostenson updated the pull request.

@ncnlinh
Copy link

ncnlinh commented Jan 29, 2016

I hope this will be merged and released soon!

@nicklockwood
Copy link
Contributor

Sorry for the wait. I'll see what I can do to get this merged.

@facebook-github-bot shipit

@facebook-github-bot
Copy link
Contributor

Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/179867235705034/int_phab to review.

@nicklockwood
Copy link
Contributor

@mtostenson How would you feel about me changing the url prop to uri? It's just that this source object is quite similar to the one we use for images, and I see some potential for code reuse in the future if they follow the same structure as much as possible.

@mtostenson
Copy link
Author

@nicklockwood This prop results in a call to loadUrl so I think URL is preferable because it sticks with the naming convention of the native view.

@nicklockwood
Copy link
Contributor

@mtostenson we're already moving away from the native view conventions by using a source property, so I think consistency with React conventions is more important, don't you? It seems odd to me to have

<Image source={{uri: foo}}/>

But then

<WebView source={{url: foo}}/>

But if you're concerned that it will be confusing to use uri for WebViews, we could always check for url and display an error, so users are clear on what they've got wrong.

@mtostenson
Copy link
Author

@nicklockwood I see what you mean, I'm fine gonig with URI. Since it's all documented I don't think it's necessary to include the URL warning message, but it can't hurt.

@nicklockwood
Copy link
Contributor

@mtostenson great, I'll make that change then.

I'm also working on adding this to iOS so we can use it x-platform.

Thanks again for the PR, this is an awesome improvement.

@janicduplessis
Copy link
Contributor

@nicklockwood deprecatedPropType got merged in master if you want to make the change to use it before merging this.

@nicklockwood
Copy link
Contributor

@janicduplessis Yep, I'll do that.

@ghost ghost closed this in 80a2f5d Feb 1, 2016
@janicduplessis
Copy link
Contributor

It got merged :)

@mtostenson
Copy link
Author

thanks @janicduplessis

@nicklockwood
Copy link
Contributor

I have a follow up commit waiting that adds support for iOS as well. Just dealing with some Flow validation issues.

ghost pushed a commit that referenced this pull request Feb 2, 2016
Summary:
public
#5494 added a new `source` property to WebView on Android that provides a better API, as well as allowing for request headers to be set.

This diff ports that functionality over to iOS, so we can have a consistent API cross-platform.

I've also extended the API to include `method` (GET or POST) and `body` when setting the WebView content with a URI, and `baseUrl` when setting static HTML.

Reviewed By: javache

Differential Revision: D2884643

fb-gh-sync-id: 83f24494bdbb4e1408aa8f3b7428fee33888ae3a
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants