diff --git a/README.md b/README.md index 152c5eca..56274dc9 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,8 @@ var WebViewAndroidExample = React.createClass({ }, evaluateJavascript: function(data) { // evaluates javascript directly on the webview instance - this.refs.webViewAndroidSample.evaluateJavascript(data); + this.refs.webViewAndroidSample.evaluateJavascript(data) + .then(res => console.log(res)); }, injectJavaScript: function(script) { // executes JavaScript immediately in web view diff --git a/android/build.gradle b/android/build.gradle index 3282ef95..92b58698 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -14,4 +14,5 @@ android { dependencies { compile 'com.facebook.react:react-native:+' + compile 'com.google.code.gson:gson:2.8.5' } diff --git a/android/src/main/java/com/burnweb/rnwebview/RNWebViewManager.java b/android/src/main/java/com/burnweb/rnwebview/RNWebViewManager.java index a992039e..0fc3bf3b 100644 --- a/android/src/main/java/com/burnweb/rnwebview/RNWebViewManager.java +++ b/android/src/main/java/com/burnweb/rnwebview/RNWebViewManager.java @@ -32,7 +32,6 @@ public class RNWebViewManager extends SimpleViewManager { public static final int POST_MESSAGE = 5; public static final int INJECT_JAVASCRIPT = 6; public static final int SHOULD_OVERRIDE_WITH_RESULT = 7; - public static final int EVALUATE_JAVASCRIPT = 8; private static final String HTML_MIME_TYPE = "text/html"; @@ -193,7 +192,6 @@ Map getCommandsMap() { "injectJavaScript", INJECT_JAVASCRIPT, "shouldOverrideWithResult", SHOULD_OVERRIDE_WITH_RESULT ); - map.put("evaluateJavascript", EVALUATE_JAVASCRIPT); return map; } @@ -238,11 +236,6 @@ public void receiveCommand(RNWebView view, int commandId, @Nullable ReadableArra case SHOULD_OVERRIDE_WITH_RESULT: view.shouldOverrideWithResult(view, args); break; - case EVALUATE_JAVASCRIPT: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - view.evaluateJavascript(args.getString(0), null); - } - break; } } diff --git a/android/src/main/java/com/burnweb/rnwebview/RNWebViewModule.java b/android/src/main/java/com/burnweb/rnwebview/RNWebViewModule.java index 4bf9d0b6..42d11296 100644 --- a/android/src/main/java/com/burnweb/rnwebview/RNWebViewModule.java +++ b/android/src/main/java/com/burnweb/rnwebview/RNWebViewModule.java @@ -12,6 +12,7 @@ import android.os.Build; import android.os.Bundle; import android.util.Log; +import android.view.View; import android.webkit.JsResult; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; @@ -19,6 +20,16 @@ import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactMethod; + +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.UIBlock; +import com.facebook.react.uimanager.NativeViewHierarchyManager; + +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import java.io.StringReader; public class RNWebViewModule extends ReactContextBaseJavaModule implements ActivityEventListener { @@ -171,4 +182,61 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode, public void onNewIntent(Intent intent) {} + public interface RNWebViewHandler { + void handle(RNWebView result); + } + + @ReactMethod + public void evaluateJavascript(final String data, final int viewId, final Promise promise) { + withRNWebView(viewId, promise, new RNWebViewHandler() { + @Override + public void handle(RNWebView view) { + view.evaluateJavascript(data, new ValueCallback() { + @Override + public void onReceiveValue(String value) { + JsonReader reader = new JsonReader(new StringReader(value)); + + reader.setLenient(true); + + try { + if(reader.peek() != JsonToken.NULL && reader.peek() == JsonToken.STRING) { + String msg = reader.nextString(); + promise.resolve(msg); + } else { + promise.resolve(value); + } + } catch (Exception e) { + Log.e(REACT_CLASS, "Unparsable evaluate javascript result"); + promise.reject(e.toString()); + } finally { + try { + reader.close(); + } catch (Exception e) { + // NOOP + promise.reject(e.toString()); + } + } + } + }); + } + }); + } + + private void withRNWebView(final int viewId, final Promise promise, final RNWebViewHandler handler) { + UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + @Override + public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { + View view = nativeViewHierarchyManager.resolveView(viewId); + if (view instanceof RNWebView) { + RNWebView myView = (RNWebView) view; + handler.handle(myView); + } + else { + promise.reject("RNWebView", "Unexpected view type"); + } + } + }); + } + } diff --git a/index.android.js b/index.android.js index 32ef6b81..f238b82c 100644 --- a/index.android.js +++ b/index.android.js @@ -84,13 +84,6 @@ var WebViewAndroid = createClass({ null ); }, - evaluateJavascript: function(data) { - RCTUIManager.dispatchViewManagerCommand( - this._getWebViewHandle(), - RCTUIManager.RNWebViewAndroid.Commands.evaluateJavascript, - [String(data)] - ); - }, postMessage: function(data) { RCTUIManager.dispatchViewManagerCommand( this._getWebViewHandle(), @@ -105,6 +98,9 @@ var WebViewAndroid = createClass({ [data] ); }, + evaluateJavascript: function(data) { + return NativeModules.RNWebViewAndroidModule.evaluateJavascript(data, this._getWebViewHandle()); + }, render: function() { return (