Android Inject in webview external js, execute function, and raise an alert - javascript

I want to inject an external javascript in webview and execute one of its functions execute(). After completion an alert is raised and the string returns to the activity
this is how I do it but it doesn't seem to work (the js is already tested)
view.loadUrl("javascript:(function() { var script=document.createElement('script');script.type='text/javascript';script.src=" + jsFileURL + ";" + "document.getElementsByTagName('head').item(0).appendChild(script);window.HTMLOUT.showHTML(execute());})()");
this is how I implement HTMLOUT, while the alert is overrided in ChromeClient
browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT"); browser.setWebViewClient(new mWebViewClient()); browser.setWebChromeClient(new mChromeClient()); browser.loadUrl("file:///android_asset/Travian comx2b.htm");

Ok after many many attempts I found a workaround, but unfortunately not the "solution". I used this load view.loadUrl("javascript:" + src + " execute(); " + ""); while the source src comes from a text file script.js which includes my javascript (both functions and plain commands)
//get script
InputStream is;
String src= "";
try {
is = getAssets().open("travianbot.js");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
// Convert the buffer into a string.
src = new String(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a sample of the script.js (be careful on line endings ";")
function addItem(v, link, x, y, result) {
//function commands
}
function popup() {
alert(execute().split("#"));
}
function execute(){
//function commands
additem(...);
}
// plain commands
.......
One resolution for a remote script, which I haven't tested it, is to parse the remote script (e.g. as inputstream) and then included it as plain text.

I think u have to enclose the jsFileUrl in single quotes.
script.src='" + jsFileURL + "';"

please check out this http://lexandera.com/2009/01/adding-alert-support-to-a-webview/
Thanks

Related

How to inject whole javascript function into webview and call it from android

What i have done:
I have a js file and an html file in my assets folder, i am loading that html file in webview.
then i manually edited the html file and added this code to it
<script src="file:///android_asset/myjs.js" type="text/javascript"></script>
and loaded the webview again and in the onPageFinished of webview I injected a javascript function call like this
webviewMine.loadUrl("javascript:changeColor('" + currentLine + "');");
This is working fine. Then i removed the script tag from the html page and tried to load the js in the assets by injecting that code in the onPageFinished like this
webviewTTS.loadUrl("javascript:<script src=\"file:///android_asset/js/makeBold.js\" type=\"text/javascript\"></script>");
but when the js call is executed from the android side it says the function changeColor does not exists in the html page, means my js injection of script tag is not working.
Is there any standard way of injecting js function like this?
If there is none please correct me.
Use the below mentioned method to inject a js file from asset folder
public void injectScriptFile(WebView view, String scriptFile) {
InputStream input;
try {
input = getAssets().open(scriptFile);
byte[] buffer = new byte[input.available()];
input.read(buffer);
input.close();
// String-ify the script byte-array using BASE64 encoding !!!
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
view.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
// Tell the browser to BASE64-decode the string into your script !!!
"script.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(script)" +
"})()");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Adding a javascript file to an already-running Java FX webengine

I have a Java application that is running a Java FX webengine (the end goal of all of this is to dynamically draw a D3.js plot). I'd like to be able to add new javascript files to it while it's already running, and then ideally unload them again when the javascript tells it to.
This has the effect of making some functionality available to the user or not (drawing certain features) without having to load all of the code in at once. It also helps me avoid future headaches with a forest of brittle if/then statements inside my javascript.
Question 1: Is "unloading" files from a running webengine even possible? At least, possible without redrawing the whole thing. I'm pretty sure that calling loadContent() with my new filepaths will make them available the way that I want, but I haven't come across anything talking about how you can remove existing source code from your HTML block.
Question 2: Any recommendations on how to elegantly approach feeding the extra sources into the webView? My thought process right now is stuck on brute force, but I haven't been even been able to brute force my way to a solution that works, so maybe I'm barking up the wrong tree.
Question 3: Is this even a good idea? It's possible to do this solely in the Javascript, but I want the appearance and disappearance of options directly tied to a java-side feature that's later going to be executed from the class Bridge, the same place I'm trying to load new content from right now.
I asked a lot of questions, but any help is appreciated!
Right now I am setting up the webengine's content like so:
final ResourceExtractor RESOURCE_EXTRACTOR
= new ResourceExtractor(JavaScriptPlot.class);
// prepare the local URI for d3.js
final URI D3_JS_URI = RESOURCE_EXTRACTOR
.extractResourceAsPath("d3.min.js")
.toUri();
// prepare the local URI for numeric.js
final URI NUMERIC_JS_URI = RESOURCE_EXTRACTOR
.extractResourceAsPath("numeric.min.js")
.toUri();
// prepare the local URI for topsoil.js
final URI TOPSOIL_JS_URI = RESOURCE_EXTRACTOR
.extractResourceAsPath("topsoil.js")
.toUri();
// build the HTML template (comments show implicit elements/tags)
HTML_TEMPLATE = (""
+ "<!DOCTYPE html>\n"
// <html>
// <head>
+ "<style>\n"
+ "body {\n"
+ " margin: 0; padding: 0;\n"
+ "}\n"
+ "</style>\n"
// </head>
+ "<body>"
+ "<script src=\"" + D3_JS_URI + "\"></script>\n"
+ "<script src=\"" + NUMERIC_JS_URI + "\"></script>\n"
+ "<script src=\"" + TOPSOIL_JS_URI + "\"></script>\n"
+ "<script src=\"%s\"></script>\n" // JS file for plot
// </body>
// </html>
+ "").replaceAll("%20", "%%20");
The source path to replace %s is created here:
public class BasePlot extends JavaScriptPlot {
private static final ResourceExtractor RESOURCE_EXTRACTOR
= new ResourceExtractor(BasePlot.class);
private static final String RESOURCE_NAME = "BasePlot.js";
public BasePlot() {
super(
RESOURCE_EXTRACTOR.extractResourceAsPath(RESOURCE_NAME),
new BasePlotDefaultProperties());
}
}
And then later I take a file path already extracted as a resource, sourcePath, and insert it into the HTML block:
String buildContent() {
return String.format(HTML_TEMPLATE, sourcePath.toUri());
}
Then I build my web view using the return value of buildContent()
private void initializeWebView() {
runOnFxApplicationThread(() -> {
// initialize webView and associated variables
webView = new WebView();
webView.setContextMenuEnabled(false);
WebEngine webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener(
(observable, oldValue, newValue) -> {
if (newValue == SUCCEEDED) {
if (new IsBlankImage().test(screenCapture())) {
webEngine.loadContent(buildContent());
}
topsoil = (JSObject) webEngine.executeScript("topsoil");
topsoil.setMember("bridge", new Bridge());
}
});
// asynchronous
webEngine.loadContent(buildContent());
});
}
And the Javascript can fire off the method in the class below to trigger the change. Right now it's manually creating a hardcoded resource, but once I work out once going wrong I'll make this part more elegant/logically organized.
//loads appropriate JS files into webview based on BasePlot's isotope type
public class Bridge {
final URI ISOTOPE_URI = ISOTOPE_RESOURCE_EXTRACTOR
.extractResourceAsPath("Concordia.js")
.toUri();
String finalHtml = buildContent().concat("<script src=\""+ISOTOPE_URI.toString()+"\"></script>\n");
webView.getEngine().loadContent(finalHtml);
}
}
The loadContent() above is giving me an application thread error: "ReferenceError: Can't find variable: topsoil"

Printing multiple files through javascript

I need to print multiple files using javascript. Print single file works fine but as soon as I try and print multiple files, I get only one printed.
My javacript is as under
function LoadPrint() {
if (document.getElementById("pdf").src !== "") {
var frm = document.getElementById("pdf").contentWindow;
frm.focus();
frm.print();
}
return false;
}
and I call it from c# as below
foreach (var str in filenames)
ClientScript.RegisterStartupScript(this.GetType(), "Print", "LoadPdfFile('" + "/Templates/" + str + "');", true);
How can I tell RegisterStartupScript to wait until the file is printed?
If you have a component to generate a pdf, you'll have the functionality to create one pdf by merging many.
I suggest you write a method to create a new pdf with a pagebreak between each one and let the server handle it instead of the client

How to have functionality of Compiler in my jsp pages

I have a textarea through which user will write his code and when he press submit button then text should get compiled and result should be displayed.
Can anyone provide any API's available which I can use.?
More Details:
I have a form consisting of textarea where user can write code and submit.
On submit I want to compile this code through jsp page and return output message of compiler.
One more thing I do not Have file of submitted code, I have only string.
string code = request.getparameter("textareaCode");
So, is there any way to compile this code for any one languages ex. C, C++ or Java?
Is there any API's available which I can use to work it?
How to give system call through jsp pages so that I can compile the submitted code?
You can make use of run-time java compilation feature provided in JavaCompiler interface which accepts input/output stream.
Step 1. Convert contents submitted by text-area into input stream.
Step 2. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
Step 3. Call compiler.run method by providing inputstream(you have created in step 1) as one argument. You can capture the output of compilation thru output stream as another argument.
You can execute command line commands using Runtime.getRuntime().exec("command");
For example if you want to compile a java file then try the following :
import java.io.*;
public class JavaRunCommand {
public static void main(String args[]) {
String s = null;
try {
// Logic to save textarea code into java file.
// then compile a java file "javac fileName.java" command
// using the Runtime exec method
Process p = Runtime.getRuntime().exec("javac fileName.java");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}

Run script in wkhtmltopdf process

I use wkhtmltopdf to create pdf(s) from html(s)
I have next function :
private void CreateTempPdf(string htmlPath, string pdfPathTemp)
{
var processorInfo = new System.Diagnostics.ProcessStartInfo
{
Arguments =
"--margin-top 27 \"" + htmlPath + "\" \"" + pdfPathTemp +
"\" ",
FileName = PublisherConfigurationManager.Pdf2HtmlConverter,
UseShellExecute = true
};
using (var proc = new System.Diagnostics.Process())
{
proc.StartInfo = processorInfo;
proc.Start();
proc.WaitForExit();
}
}
in which i pass paths of html file and destination file.
I want to add some js script to run, before pdf will be generated.
I add my code : --run-script <js> into Arguments after pdfPathTemp but script isn't applied to pdf. I also add it before --margin but this case also doesn't help me.
How correctly add scripts into wkhtmltopdf process?
I would simply add the script directly into the HTML page. In this case I would load the HTML from the path into a string, inject the script, then write a tempfile for the process duration.
As for why --run-script does not work, I have no idea. Have you tried it directly in the command line with a very simple script and HTML to see if a minimal example works for you?
If that is not an option, you might have to play around with different files for differnt js arguments, if you require such things.

Categories

Resources