NativeJS

Hi there, good folks.

Today we had a long discussion on the public Vaadin skype-chat about if Vaadin should allow running of native JavaScript as such (easily). There has been a lot of hacks for it, for example put the javascript into a label and have the browser interpret it as XHTML. Nothing worked easily and perfect and this was what the discussion was about: should Vaadin have built in support?

I, personally, was against it, for a couple of reasons. For example, it smells like a big security risk where you really can mess up something, it is a bloat-feature most won’t ever use and Vaadin tries to hide all the low-level code from the coder. That’s why it is so easy to use Vaadin. Also, I hate Javascript, a lot!

One suggestion that popped up was that it could be a custom widget, that you could add to your project if you really really need it. That way it won’t bloat Vaadin, and it’s at that point “use at own risk”. The implementation is also quite simple and it would be a nice addition for the upcoming Directory.

Therefore, I made a component that can do just this, run any javascript you want. The API contains only three functions (+ vaadin own componentfunctions) and these are setJavascript(string), getJavascript() and execute(). The usage looks like this:

NativeJS nativejs = new NativeJS("alert('Hi!')");
nativejs.execute()

where you can bind the execute function behind some button, or run on startup, and you can change the javascript in question with setJavascript(string);

Here’s a screenshot of my demo application:

You can test
the live demo is found here
. Try, for example, writing into the text field window.print();

No sources just yet, because I’m home right now, and my svn username/password is at work, so I don’t have access for the moment. I’ll try to put it there tomorrow, so that it can be found on dev.vaadin.com svn-repo under incubator/NativeJS.

If you have any suggestions on how to enhance this, send me a message.

Looks handy “keep it simple stupid” solution. Perfect for the directory ;)

This is great. But please, include it to the core library. :slight_smile: I see no extra security issues here, because calling JS has been always been possible. This would just make it as pretty as it should be.

Well, you have to talk about that with the RnD I guess. They didn’t seems so happy of the idea. :slight_smile:

+1 to have this feature in a core. Sometimes, extra piece of integration needed and it is too small to spend time creating custom widget but having an ability to invoke JS at the client side would be very helpful - this is similar to the same case when programming in plain GWT - it’s JSNI is helpful from time to time to perform non standard tasks.

If this would be in core, it should not IMO be a separate widget, but an API in the Window -class.

Something like:

myWindow.executeJavaScript("alert('foo');");

If this would be a core framework feature, it could also add provide references to DOM elements like this:

myWin.executeJavaScript("$1.style.backgroundColor='red';$2.style.backgroundColor='blue'", 
aTextFieldinMyWin, someOtherComponentInMyWin);

(In the above example the references would be to the outmost DOM element in the widget that implements the client counterpart for the given server-side UI component)

At the first sight this looks like a really handy and powerful feature. Probably there would be severe downsides also - anyone care to comment on those?

If you like this - how about creating a ticket for it? If so, this probably should have some relation to
http://dev.vaadin.com/ticket/3067


http://dev.vaadin.com/svn/incubator/NativeJS/
not found… Please commit :)

Trying. I had a busy day at work and I left my laptop there now, with the component. Tried to set it up at one point put gave up as the wlan station over there has a random generator deciding on when it wants to work. :wink: Too busy to solve it but I guess I’ll give it another try tomorrow (or today, depending on how you interpret the time)

First version is here now:
http://dev.vaadin.com/browser/incubator/NativeJS
.

I did package as it would be used with 6.2, not the way of the nightlies, because I haven’t found out yet what should be done for that and very few of those who would have need of this in ther projects have upgraded beyond the stable release.

I’ll fix up an jar version at some point.

I went on and wrote my ramblings about javascript in Vaadin on my own
blog
. Not much information there but thought that some may be interested in giving it a look.

Added a ticket:


http://dev.vaadin.com/ticket/3589

Please comment on ticket if you like/dislike this feature proposal.

I updated the component to be Vaadin 6.2 compliant.

Implemented
http://dev.vaadin.com/ticket/3589

public void executeJavaScript(String script, Paintable… paintables)

This method allows one to inject javascript from the server to client. Client implementation is not required to implenment this functionality, but currently all web-based clients do implement this.

The script may contain markers indentified with “$x”, where x is a one digit number. The number of markers must match to the number of optional Paintable reference parameters. The first marker is $1, second $2 and so on. If the markers are specified, the markers are replaced in the browser with references to outmost DOM elements connected to the given paintables.

Use example 1:

mainWindow.executeJavaScript("alert(foo");

Use example 2:

Label label = new Label("Label"); 
TextField textfield = new TextField("TestField"); 
mainWindow.addComponent(label); 
mainWindow.addComponent(textfield); mainWindow.executeJavaScript("$1.style.backgroundColor='yellow';$2.style.borderColor='red';",label,textfield);

Parameters:
script - JavaScript snippet that will be executed and that might optionally contain $1, $2, … markers.
paintables - References to number of visible paintables that correspond the to markers listed in script

Will be in next 6.2 series nightly build and in 6.2 release.

Hi

It looks nice feature.
But it only seems to be one way. this function is void. How about reading something from client using javascript.
Something like:
String fistName = mainWindow.executeJavaScript(" document.forms[0]
.firstname.value")

Saeid

Unfortunately synchronous call to client-side is impossible, but you could achieve the same thing asynchronously with proposed
JavaScript callback API
. This would require two steps: 1) setup a callback and 2) use the callback with window.executeJavaScript().

Hi
I think it is easier to create a servlet. I created a servlet wich can access the window. Using Refresher component, I could do it.

How to use callback in NativeJS ?