Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion Examples/UIExplorer/js/WebViewExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,35 @@ class MessagingTest extends React.Component {
}
}

class InjectJS extends React.Component {
webview = null;
injectJS = () => {
const script = 'document.write("Injected JS ")'; // eslint-disable-line quotes
if (this.webview) {
this.webview.injectJavaScript(script);
}
}
render() {
return (
<View>
<WebView
ref={webview => { this.webview = webview; }}
style={{

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

quotes: Strings must use singlequote.

backgroundColor: BGWASH,
height: 300,
}}
source={{uri: 'https://www.facebook.com'}}
scalesPageToFit={true}
/>
<View style={styles.buttons}>
<Button text="Inject JS" enabled onPress={this.injectJS} />
</View>
</View>
);
}
}


var styles = StyleSheet.create({
container: {
flex: 1,
Expand Down Expand Up @@ -442,5 +471,9 @@ exports.examples = [
{
title: 'Mesaging Test',
render(): ReactElement<any> { return <MessagingTest />; }
}
},
{
title: 'Inject JavaScript',
render(): React.Element<any> { return <InjectJS />; }
},
];
14 changes: 14 additions & 0 deletions Libraries/Components/WebView/WebView.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,20 @@ class WebView extends React.Component {
);
};

/**
* Injects a javascript string into the referenced WebView. Deliberately does not
* return a response 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.
*/
injectJavaScript = (data) => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.RCTWebView.Commands.injectJavaScript,
[data]
);
};

/**
* We return an event with a bunch of fields including:
* url, title, loading, canGoBack, canGoForward
Expand Down
14 changes: 14 additions & 0 deletions Libraries/Components/WebView/WebView.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,20 @@ class WebView extends React.Component {
);
};

/**
* Injects a javascript string into the referenced WebView. Deliberately does not
* return a response 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.
*/
injectJavaScript = (data) => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
UIManager.RCTWebView.Commands.injectJavaScript,
[data]
);
};

/**
* We return an event with a bunch of fields including:
* url, title, loading, canGoBack, canGoForward
Expand Down
1 change: 1 addition & 0 deletions React/Views/RCTWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
- (void)reload;
- (void)stopLoading;
- (void)postMessage:(NSString *)message;
- (void)injectJavaScript:(NSString *)script;

@end
5 changes: 5 additions & 0 deletions React/Views/RCTWebView.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ - (void)postMessage:(NSString *)message
[_webView stringByEvaluatingJavaScriptFromString:source];
}

- (void)injectJavaScript:(NSString *)script
{
[_webView stringByEvaluatingJavaScriptFromString:script];
}

- (void)setSource:(NSDictionary *)source
{
if (![_source isEqualToDictionary:source]) {
Expand Down
12 changes: 12 additions & 0 deletions React/Views/RCTWebViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ - (UIView *)view
}];
}

RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTWebView *> *viewRegistry) {
RCTWebView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTWebView class]]) {
RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
} else {
[view injectJavaScript:script];
}
}];
}

#pragma mark - Exported synchronous methods

- (BOOL)webView:(__unused RCTWebView *)webView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
public static final int COMMAND_RELOAD = 3;
public static final int COMMAND_STOP_LOADING = 4;
public static final int COMMAND_POST_MESSAGE = 5;
public static final int COMMAND_INJECT_JAVASCRIPT = 6;

// Use `webView.loadUrl("about:blank")` to reliably reset the view
// state and release page resources (including any running JavaScript).
Expand Down Expand Up @@ -477,7 +478,9 @@ protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
"goForward", COMMAND_GO_FORWARD,
"reload", COMMAND_RELOAD,
"stopLoading", COMMAND_STOP_LOADING,
"postMessage", COMMAND_POST_MESSAGE);
"postMessage", COMMAND_POST_MESSAGE,
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
);
}

@Override
Expand All @@ -504,6 +507,9 @@ public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray
throw new RuntimeException(e);
}
break;
case COMMAND_INJECT_JAVASCRIPT:
root.loadUrl("javascript:" + args.getString(0));
break;
}
}

Expand Down