Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [e4-dev] E4/JavaScript additional thoughts

Thanks Pat. Comments in-lined
 
> Patrick Mueller

> Looking at the wiki page:
>
>    http://wiki.eclipse.org/E4/_javascript_
>
> I've got a few more thoughts.
>
> - I don't fully grok where you're going with the bundled JSON bit.  I  
> realize we need to have a way of being able to bundle a bunch of  
> things, presumably even a number of "plugins" into one wad, for  
> efficiency sake, at deployment time.  But this really needs to run in  
> an "unbundled", "file-based" way at development time.  At development  
> time, I need to be able to edit a .js file, save, and "reload" (for  
> some definition of reload).  Without having to go through a "build"  
> step.  Almost seems like the declarative bits need to all be kinda  
> file-based, with some other declarative bits providing advisory  
> information on where "bundled" versions might be located, or something.

The JSON bit is just packaging for the equivalent metadata of an OSGi Manifest and is not used for the overall packaging of the JS Bundle (although that's probably pretty reasonable in some cases). As much as possible I'd like to separate out the concepts of how the framework fetches the script payloads as I'm most definitely aware of the efficiency issues and need to wad-ify scripts to avoid zillions of individual load requests. What's currently in place is fairly naive in that it will just load using relative URIs. Inefficient yes, but for now allows us to experiment with "file", "http", "jar" and "bundleentry" based URIs. The initial target is primarily _javascript_ residing in a bundle and for this case the "access" performance is equivalent to loading a class.

The dev time experience is not bad in that even for JS Bundles destined to be part of a jar file as the project is of course file based. We compile the scripts as the JS bundle is resolved so the refresh use-case is possible now only by refreshing the OSGi bundle (or restarting the JSFramework) but better dev hooks to recognize when scripts are modified (similar to what we have for JSP in Equinox) is very doable.

>
> - Any thought given to handling more languages than just _javascript_?  

YES!! There's some interesting efforts to get languages that are pre-compiled to bytecode (Clojure, Scala) that I suspect will be able to re-use the existing OSGi metadata and perhaps more important PDE tooling. My main interest is in the dynamic languages; Jython and (some day) PHP are on my list. I strongly suspect we could do something interesting with Jython that re-uses the _javascript_ resolver without a huge amount of effort. With that said my chief interest is ensuring the _javascript_ story is really great before moving on.

> One way to handle this, and make things like the "script descriptor"  
> in the plugin.xml a bit neater, would be to define a prefix that  
> mapped to a class adapter per language kind of thing.  eg, here's a  
> sample of a plugin.xml entry:
>
> <extension point="org.eclipse.equinox.http.registry.servlets">
>    <servlet
>        class="js:jsHello:myServlet">
>    </servlet>
> </extension>
>
> with the idea being of folding in a bunch of things at once - the  
> factory, the alias, the resource identifier, and for JS, the "class  
> identifier".  The "js" prefix would be a key to the script adapter,  
> the remaining bits would be an adapter-specific resource identifier  
> which would need to identify the actual class.  A Jython version would  
> simply replace the value of the class attribute with  
> "jython:jyHello.myServlet", where jyHello identified a Python module  
> (in the file jyHello.py file), which contains a class named  
> myServlet.  Very natural for Python, seems like.  Obviously, we'd need  
> to come up with some conventions for referring to JS "modules" and  
> things within them.

At a glance, your syntax looks remarkably similar to what Boris used in the E4 photo app demo where we implemented a callback "handler" in _javascript_. My take is that as long as we're just using some id/symbol with something like "callable/function" semantics and then execute it we're good. In terms of what we've got now, the syntax we require for integration in plugin.xml is a bit cludgy but works with the extension registry and requires no furher special parsing. The bundle org.eclipse.equinox.e4._javascript_.registry provides an IExecutableExtensionFactory that makes it pretty easy to use _javascript_ with our existing tooling. We've had similar success for JSP/Extenstion registry support in org.eclipse.equinox.jsp.jasper.registry.

> - for the example _javascript_ code, there's a couple of glorpy things  
> here.  One is that there is a repetition of the "some" variable back  
> to the extension.  I've removed that in my plugin example above, with  
> the implied suggestion that there would be something like a magic  
> global variable, say called "module" or something, which you would use  
> instead of the "some" variable in the _javascript_ code.  You would also  
> remove the initialization of that variable, it would be initialized  
> for you (to an empty object) at "creation time".

The "some" variable is just part of a manufactured _javascript_ namespace and of course not necessary and just part of the example. You can directly get the JSBundle object and call directly into it but the module is separate from any namespacing issue. (I suspect I'm missing your point here - sorry). In the example I didn't pre-initialize the variable because I want a new instance of the Servlet generated every time.

> - the other glorpy bit, for the _javascript_ code, is the indirection of  
> the Java class-ization of the JS bits. Why not just return the class?  
> Here's an example, with a different bit of style (but equivalent,  
> depending on semantics of the "global scope") for specifying the  
> instance methods:
>
> function service(req, resp) {
>    this.super$service(req, resp); // this is very important
> }
>
> function doGet(req, resp) {
>    resp.getWriter().write("<html><body>");
>    resp.getWriter().write("Hello World from a " +  
> this.getServletInfo());
>    resp.getWriter().write("</html></body>");
> }
>
> function getServletInfo() {
>    return "_javascript_ Servlet";
> }
>
> module.myServlet = new  
> JavaAdapter(Packages.javax.servlet.http.HttpServlet, {
>    "service":        service,
>    "doGet":          doGet,
>    "getServletInfo": getServletInfo
> })
All styles are free to play. To be honest your style is probably slightly more efficient as I tend to be a bit closure happy. I think what you wrote is valid regardless if we're running in module or global scope.


-Simon


Back to the top