Skip to content

Commit

Permalink
Merge pull request #2558 from ayeung/timob-5824-2_1_X
Browse files Browse the repository at this point in the history
TIMOB-5824-2_1_X: Android: WebView.evalJS Causes Form Input Fields to Lost/Not Retain Focus
  • Loading branch information
Opie Cyrus committed Jul 13, 2012
2 parents a84ec92 + 2ff40ea commit b474713
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -311,26 +311,18 @@ public void release()

@Override
public void onStart(Activity activity) {
// TODO Auto-generated method stub

}

@Override
public void onResume(Activity activity) {
// TODO Auto-generated method stub

}

@Override
public void onPause(Activity activity) {
// TODO Auto-generated method stub

}

@Override
public void onStop(Activity activity) {
// TODO Auto-generated method stub

}

@Override
Expand All @@ -340,6 +332,11 @@ public void onDestroy(Activity activity) {
return;
}

// We allow JS polling to continue until we exit the app. If we want to stop the polling when the app is
// backgrounded, we would need to move this to onStop(), and add the appropriate logic in onResume() to restart
// the polling.
webView.destroyWebViewBinding();

WebView nativeWebView = webView.getWebView();
if (nativeWebView == null) {
return;
Expand All @@ -348,6 +345,5 @@ public void onDestroy(Activity activity) {
nativeWebView.stopLoading();
super.releaseViews();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ public void setUrl(String url)
getWebView().getSettings().setLoadWithOverviewMode(true);
}
getWebView().loadUrl(finalUrl);

}

public void changeProxyUrl(String url)
Expand Down Expand Up @@ -465,6 +464,11 @@ public void setBasicAuthentication(String username, String password)
client.setBasicAuthentication(username, password);
}

public void destroyWebViewBinding()
{
client.getBinding().destroy();
}

public void setPluginState(int pluginState)
{
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR_MR1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2011 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
Expand All @@ -11,7 +11,9 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Stack;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollEventCallback;
Expand All @@ -35,9 +37,22 @@ public class TiWebViewBinding
// - minify binding.js to create binding.min.js
protected final static String SCRIPT_INJECTION_ID = "__ti_injection";
protected final static String INJECTION_CODE;

// This is based on polling.min.js. If you have to change anything...
// - change polling.js
// - minify polling.js to create polling.min.js
protected static String POLLING_CODE = "";
static {
StringBuilder jsonCode = readResourceFile("json2.js");
StringBuilder tiCode = readResourceFile("binding.min.js");
StringBuilder pollingCode = readResourceFile("polling.min.js");

if (pollingCode == null) {
Log.w(LCAT, "Unable to read polling code");
} else {
POLLING_CODE = pollingCode.toString();
}

StringBuilder allCode = new StringBuilder();
allCode.append("\n<script id=\"" + SCRIPT_INJECTION_ID + "\">\n");
if (jsonCode == null) {
Expand All @@ -59,13 +74,15 @@ public class TiWebViewBinding
allCode = null;
}

private WebView webView;
private Stack<String> codeSnippets;
private boolean destroyed;

private KrollLogging apiBinding;
private AppBinding appBinding;

public TiWebViewBinding(WebView webView)
{
this.webView = webView;
codeSnippets = new Stack<String>();

apiBinding = KrollLogging.getDefault();
appBinding = new AppBinding();
Expand All @@ -84,6 +101,10 @@ public void destroy()
// remove any event listener that have already been added to the Ti.APP through
// this web view instance
appBinding.clearEventListeners();

returnSemaphore.release();
codeSnippets.clear();
destroyed = true;
}

private static StringBuilder readResourceFile(String fileName)
Expand Down Expand Up @@ -111,25 +132,27 @@ private static StringBuilder readResourceFile(String fileName)
return code;
}

private void evalJS(String code)
{
webView.loadUrl("javascript:" + code);
}

private Semaphore returnSemaphore = new Semaphore(0);
private String returnValue;

public String getJSValue(String expression)
synchronized public String getJSValue(String expression)
{
String code = "javascript:_TiReturn.setValue((function(){try{return " + expression
+ "+\"\";}catch(ti_eval_err){return '';}})());";
Log.d(LCAT, "getJSValue:" + code);
webView.loadUrl(code);
try {
returnSemaphore.acquire();
return returnValue;
} catch (InterruptedException e) {
Log.e(LCAT, "Interrupted", e);
// Don't try to evaluate js code again if the binding has already been destroyed
if (!destroyed) {
String code = "_TiReturn.setValue((function(){try{return " + expression
+ "+\"\";}catch(ti_eval_err){return '';}})());";
Log.d(LCAT, "getJSValue:" + code);
synchronized (codeSnippets) {
codeSnippets.push(code);
}
try {
if (!returnSemaphore.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
Log.w(LCAT, "Timeout waiting to evaluate JS");
}
return returnValue;
} catch (InterruptedException e) {
Log.e(LCAT, "Interrupted", e);
}
}
return null;
}
Expand Down Expand Up @@ -168,7 +191,9 @@ public void call(Object data)
}

String code = "Ti.executeListener(" + id + dataString + ");";
evalJS(code);
synchronized (codeSnippets) {
codeSnippets.push(code);
}
}
}

Expand Down Expand Up @@ -217,5 +242,18 @@ public void clearEventListeners()
removeEventListener(event, appListeners.get(event));
}
}

public String getJSCode()
{
if (destroyed) {
return null;
}

String code;
synchronized (codeSnippets) {
code = codeSnippets.empty() ? "" : codeSnippets.pop();
}
return code;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public void onPageFinished(WebView view, String url)
KrollDict data = new KrollDict();
data.put("url", url);
webView.getProxy().fireEvent("load", data);
WebView nativeWebView = webView.getWebView();

if (nativeWebView != null) {
webView.getWebView().loadUrl("javascript:" + TiWebViewBinding.POLLING_CODE);
}
}

public TiWebViewBinding getBinding()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ var Ti = {
}
}
};

var Titanium = Ti;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function checkForJSCode() {
var code = TiApp.getJSCode();
if ( code != undefined) {
eval(code);
} else {
clearInterval(refreshIntervalId);
}
}

var refreshIntervalId = setInterval(checkForJSCode, 250);

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b474713

Please sign in to comment.