Repository navigation
Add a injectJavaScript method to the WebView component - #11358
worm-emoji wants to merge 24 commits into
Conversation
|
By analyzing the blame information on this pull request, we identified @jacobp100 and @spicyj to be potential reviewers. |
jacobp100
left a comment
There was a problem hiding this comment.
Good, clean implementation
|
@lukemiles This looks like it could be a useful addition. I'm having someone from my team review. |
|
@lukemiles Can you add some tests to this PR? |
|
@ericnakagawa On it! |
|
@ericnakagawa Test added. |
yungsters
left a comment
There was a problem hiding this comment.
Code was tested on iOS but not yet on Android - setting up my emulator later on.
Have you had a chance to test this on Android, yet?
| * because using eval() to return a response breaks | ||
| * this method on pages with a Content Security Policy | ||
| * that disallows eval(). If you need that functionality, | ||
| * look into postMessage/onMessage. |
There was a problem hiding this comment.
Nit: Can you fix the indentation here? (One too many spaces.)
| * because using eval() to return a response breaks | ||
| * this method on pages with a Content Security Policy | ||
| * that disallows eval(). If you need that functionality, | ||
| * look into postMessage/onMessage. |
| }, | ||
| { | ||
| title: 'Inject JavaScript', | ||
| render(): React.Element<any> { return <InjectJS/>; } |
|
iOS side lgtm |
|
Managed to get it working on Android and fixed all the nits. Let me know what else this needs before it can be merged! |
| <View> | ||
| <WebView | ||
| ref={webview => { this.webview = webview; }} | ||
| style={{ |
There was a problem hiding this comment.
quotes: Strings must use singlequote.
|
Just what I came here looking for! Thanks @lukemiles for this, looking forward to it landing in master |
|
Thanks @SRandazzo! @jacobp100 @yungsters @ericnakagawa What more has to be done here to get this merged into master? |
|
Someone at Facebook has to merge it. |
|
Made some stylistic changes thanks to suggestions @brentvatne made. Would love to know if there's anything else blocking this PR! |
|
@facebook-github-bot shipit |
|
@brentvatne has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
Summary: Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app. We noticed that the WebView had messaging support added (see react#9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and `eval()` it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born. Now, after I wrote this code, I realized that react#8798 exists and hadn't been merged because of a lack of tests. I commend what was done in react#8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I' Closes react#11358 Differential Revision: D4390425 fbshipit-source-id: 02813127f8cf60fd84229cb26eeea7f8922d03b3
Summary: Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app. We noticed that the WebView had messaging support added (see #9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and `eval()` it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born. Now, after I wrote this code, I realized that #8798 exists and hadn't been merged because of a lack of tests. I commend what was done in #8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I' Closes react/react-native#11358 Differential Revision: D4390425 fbshipit-source-id: 02813127f8cf60fd84229cb26eeea7f8922d03b3

Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app.
We noticed that the WebView had messaging support added (see #9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and
eval()it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born.Now, after I wrote this code, I realized that #8798 exists and hadn't been merged because of a lack of tests. I commend what was done in #8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I've done here (allows you to return the response). But, it uses
eval()internally which makes it subject to Content Security Policy.I'm not exactly sure what to do, but I think something should be merged. Perhaps I can add a way to try to return the results without using eval() but that seems tricky. I think the best way would be some sort of internal check when the WebView is loaded to see if CSP applies, and to not return a result on injected JavaScript (disable the use of eval() ) if that is the case. Or, you could make the argument that you don't need an evaluateJavascript function because you can accomplish it using the messaging features as it would work in all of the same places.
Looking for input - thanks.
Code was tested on iOS but not yet on Android - setting up my emulator later on.