Parse JavaScript code in C# - c#

I have the following JavaScript code as a string literal:
var $Page = new function()
{
var _url= 'http://www.some.url.com';
this.Download = function()
{
window.location = _url;
}
}
Is there a way I could get the value of the _url variable from my C# code? An open source library perhaps? I did this using a Regular Expression, but I was hoping for a more elegant way.

You should take a look at the open-source Javascript .NET (http://javascriptdotnet.codeplex.com/) on Codeplex.
This sample of code should help you:
Javascript context = new JavascriptContext();
context.Run("var _url= 'http://www.some.url.com';") // You put your javascript in the function run
String url = (String)context.GetParameter("_url"); // You get your url from javascript
That's it.

There is an open-source JavaScript interpreter in C# at http://jint.codeplex.com, if you need more than just getting the value.
This is now moved to GITHUB

You could execute the javascript function using the DLR and/or MyJScript.

You could use a javascript parser, but parsing javascript for just that one value is probably way overkill.

Related

Using Javascript for Google Maps API from WPF

I am creating an application that interfaces with Google's Maps API v3. My current approach is using a WebBrowser control by WebBrowser.Navigate("Map.html"). This is working correctly at the moment; however, I am also aware of WebBrowser.InvokeScript(). I have seen this used to execute a javascript function, but I would like to have something like the following structure:
APICalls.js - Contains different functions that can be called, or even separated out into a file for each function if necessary.
MapInterface.cs
WebBrowser.InvokeScript("APICalls.js", args) - Or control the javascript variables directly.
I have seen the InvokeScript method used, but none of the examples gave any detail to the source of the function, so I'm not sure if it was calling it from an html file or js file. Is it possible to have a structure like this, or a similarly organized structure, rather than creating an html file with javascript in each one and using Navigate()?
Additionally, are there any easier ways to use Google Maps with WPF. I checked around, but all of the resources I found were at least 2-3 years old, which I believe is older than the newest version of the maps API.
I can't suggest a better way of using Google Maps API with WPF (although I'm sure it exists), but I can try to answer the rest of the question.
First, make sure to enable FEATURE_BROWSER_EMULATION for your WebBrowser app, so Google Maps API recognizes is it as modern HTML5-capable browser.
Then, navigate to your "Map.html" page and let it finish loading. Here's how it can be done using async/await (the code is for the WinForms version of WebBrowser control, but the concept remains the same).
You can have your APICalls.js as a separate local file, but you'd need to create and populate a <script> element for it from C#. You do it once for the session.
Example:
var scriptText = File.ReadAllText("APICalls.js");
dynamic htmlDocument = webBrowser.Document;
var script = htmlDocument.createElement("script");
script.type = "text/javascript";
script.appendChild(htmlDocument.createTextNode(scriptText));
htmlDocument.body.appendChild(script);
Then you can call functions from this script in a few different ways.
For example, your JavaScript entry point function in APICalls.js may look like this:
(function() {
window.callMeFromCsharp = function(arg1, arg2) {
window.alert(arg1 + ", " +arg2);
}
})();
Which you could call from C# like this:
webBrowser.InvokeScript("callMeFromCsharp", "Hello", "World!");
[UPDATE] If you're looking for a bit more modular or object-oriented approach, you can utilize the dynamic feature of C#. Example:
JavaScript:
(function() {
window.apiObject = function() {
return {
property: "I'm a property",
Method1: function(arg) { alert("I'm method 1, " + arg); },
Method2: function() { return "I'm method 2"; }
};
}
})();
C#:
dynamic apiObject = webBrowser.InvokeScript("apiObject");
string property = apiObject.property;
MessageBox.Show(property);
apiObject.Method1("Hello!");
MessageBox.Show(apiObject.Method2());

Opening a Silverlight Window From Javascript and passing an object

I am looking for a way to open my silverlight application from my web application using javascript. I will also need to pass a string to the silverlight application during this process. The code below will currently open the silverlight application for me. I need to know how to do this while passing in the string value to silverlight.
$(function () {
$('.cell').on('focus', 'textarea', function () {
var inputValue = $(this).val();
window.open('/TestPage.aspx');
});
});
Note: I have searched everywhere for the answer to this and cant seem to find a decent solution. All of the demos I've found are incomplete or do not function as expected.
You could pass it in the query string:
window.open('/TestPage.aspx?input=' + inputValue);
Retrieve it in Silverlight using HtmlDocument.QueryString:
string inputValue = null;
if (HtmlDocument.QueryString.ContainsKey("input"))
inputValue = HtmlDocument.QueryString["input"];

dynamically evaluating javascript expressions in winrt/xaml/c# applications

Is there a way of evaluating javascript expressions, which are loaded from an external source at runtime, in a winrt application written in XAML and c#?
Consider the following pseudo-code:
String expression = File.ReadAll(somefile);
String result = AnyJavascriptEngineAvailableUnderWinRT.Evaluate(expression);
before winrt, we have been using Microsoft.JScript engine.
Now, with winrt, we have been trying Jint, which led to runtime exception "The API 'System.Type.ReflectionOnlyGetType(System.String, Boolean, Boolean)' cannot be used on the current platform. See http://go.microsoft.com/fwlink/?LinkId=248273 for more information."
To be honest, I would prefer addressing the built-in javascript engine coming with winrt, but I would also accept "AnyJavascriptEngineAvailableUnderWinRT", if it allows expressions to be evaluated dynamically.
You can do this easily by tapping into IE directly through the WebView.
Like this:
var js = "whatever you want";
var webView = new WebView();
var result = webView.InvokeScript("eval", new[] { js });
Best of luck!

How Can Execute Javascript Commands via GeckoFX

I try to execute a javascript command like alert('test message') via GeckoFX and C#
but I can not.
I try without results with Navigate and with ExecuteCommand
My code is
int i=0;
GeckoWebBrowser webBrowser
webBrowser.Navigate("alert('"+i.ToString()+"');");
webBrowser.ExecuteCommand("alert('" + i.ToString() + "');");
Can anyone help me?
You can use AutoJSContext to run javascript with geckofx.
Something like:
GeckoWebBrowser browser = ....;
using (AutoJSContext context = new AutoJSContext(browser.JSContext))
{
string result;
context.EvaluateScript("3 + 2;", out result)
}
See EvaluateScript unittests for more info and examples.
If you are using a super old version of geckofx you may need to get a later version - geckofx
for the new versions instead of geckoWebBrowser1.JSContext you should write geckoWebBrowser1.Window
my code is working and I've answered with sample in another old post here
You can use Navigate method to avoid AccessViolatoinException during calling document js function:
webView.Navigate("javascript:$$external.consoleLog('message text');");

Generating JavaScript in C# and subsequent testing

We are currently developing an ASP.NET MVC application which makes heavy use of attribute-based metadata to drive the generation of JavaScript.
Below is a sample of the type of methods we are writing:
function string GetJavascript<T>(string javascriptPresentationFunctionName,
string inputId,
T model)
{
return #"function updateFormInputs(value){
$('#" + inputId + #"_SelectedItemState').val(value);
$('#" + inputId + #"_Presentation').val(value);
}
function clearInputs(){
" + helper.ClearHiddenInputs<T>(model) + #"
updateFormInputs('');
}
function handleJson(json){
clearInputs();
" + helper.UpdateHiddenInputsWithJson<T>("json", model) + #"
updateFormInputs(" + javascriptPresentationFunctionName + #"());
" + model.GetCallBackFunctionForJavascript("json") + #"
}";
}
This method generates some boilerplace and hands off to various other methods which return strings. The whole lot is then returned as a string and written to the output.
The question(s) I have are:
1) Is there a nicer way to do this other than using large string blocks?
We've considered using a StringBuilder or the Response Stream but it seems quite 'noisy'. Using string.format starts to become difficult to comprehend.
2) How would you go about unit testing this code? It seems a little amateur just doing a string comparison looking for particular output in the string.
3) What about actually testing the eventual JavaScript output?
Thanks for your input!
We created a library specifically for the purpose of embedding JavaScript in a fluent-like syntax into our C# code, and then made it open source.
Have a look at Adam.JSGenerator.
I typically try to create a separate .js file for most/all of my javascript code. Usually I will need to have common bahvior applied to many elements that are dynamically created by ASP controls or server-side code, so I may not be able to code everything into a .js file.
I've found that the main reason that you want to generate javascript on the server is because you won't know the IDs of elements until the page renders. Therefore, I try to condense that dependency down as much as possibly so that I'm generating as little javascript as possible. For example, in traditional ASP.Net (not MVC) if I were rendering a set of forms such as in the example, each with multiple fields, then I would probably have something in the code behind such as this:
protected void FormRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Control form = e.Item.FindControl("MyForm");
ClientScript.RegisterStartupScript(this.GetType(), "prepareForm_" + form.ClientID, #"prepareForm('" + form.ClientID + "');", true);
}
A separate .js file would include the definition of the prepareForm function, which would be something like this:
// define a formPresenter "class" that encapsulates the behavior for a given form
function formPresenter(formId) {
this.setFirstName = function(value) {
$("#" + formId + "_FirstName").val(value);
}
this.setLastName = function(value) {
$("#" + formId + "_LastName").val(value);
}
// create other functions to handle more complicated logic
// clear fields
this.clearInputs = function() {
this.setFirstName("");
this.setLastName("");
//...
}
// receive Json object
this.handleJson = function(json) {
this.clearInputs();
// populate fields with json object
this.setFirstName(json.FirstName);
this.setLastName(json.LastName);
//...
}
// "constructor" logic
}
function prepareForm(formId) {
// create a new formPresenter object and shove it onto the specified element as the "presenter"
document.getElementById(formId).presenter = new formPresenter(formId);
}
Now almost all of your actual logic is in its own .js file, which should be much easier to maintain. If you need to access the formPresenter object for a given form, then you just need to get a reference to whatever element is referenced by the formId parameter and access the presenter variable:
"document.getElementById(" + form.ClientID + ").presenter.handleJson(json);"
Note: Since I've been using JQuery, I've found less of a need to even include any javascript generated by the server. Typically I can find the elements that I need by looking for a specific CSS class name (or something to that effect) and perform whatever setup/initialization I need.
We're doing a lot of JS generation in our project as well, and we're using StringBuilder to do it.
StringBuilder sb = new StringBuilder();
sb.Append("some javascript stuff")
.Append("some more")
.AppendFormat("formatted stuff {0}", "here");
return sb.ToString();
It's not pretty, but no solution is going to be.
And concerning testing, we don't actually do any unit tests on the generated code. Before release people go and test all the features to make sure they work as expected.
If you don't care about super duper performance you could use a templating language to generate the javascript.
Then for unit testing you would just fill the templates with their appropriate bindings/variables and then run it through a Javascript evaluator like Rhino or whatever the .NET equivalent is to at least test the syntax if not the actual JS code.
Other than that I would seriously question the design of software that is generating Javascript like this. It also looks like you are using JQuery but are referencing the $ directly which may lead to some problems down the line.
If compilers generating Javascript is one thing (ala GWT) but I would separate your client side JS code as much as possible from your .NET code (not to mention your .NET code looks like server side JS talk about confusing).
This in vogue kind of design of separating the client crap from the server is known as SOFEA. I let you google that.

Categories

Resources