tag:blogger.com,1999:blog-57831840941664634342024-03-05T05:28:54.257+01:00JangarooJangaroo is a set of tools to run ActionScript 3 code in JavaScript 1.x environments, especially in current web browsers.Dennishttp://www.blogger.com/profile/09456446381126510943noreply@blogger.comBlogger20125tag:blogger.com,1999:blog-5783184094166463434.post-34850206627331958582012-07-09T10:00:00.000+02:002014-02-18T09:35:17.662+01:00Managing Sprites with SmartSprites and Smartsprites-Maven-PluginJangaroo is not only about ActionScript-to-JavaScript compilation, but generally about providing free, <span style="background-color: white;">Open Source</span><span style="background-color: white;"> </span><span style="background-color: white;">tools for Enterprise Web Developers. So today's about a small tool we just added to the stack that integrates assembly of CSS sprites into your Maven build process.</span><br />
<div class="MsoNormal">
<span lang="EN-US">You may
have heard or even used <a href="http://csssprites.org/" target="_blank">SmartSprites </a>(<a href="http://csssprites.org/">http://csssprites.org</a>) by Carrot Search / </span>Stanislaw Osinski<span style="background-color: white;">.
A small tool that lets you bundle your images into sprite sheets improving your
webapp's performance.</span></div>
<div class="MsoNormal">
<span lang="EN-US">Using SmartSprites
from over and over again, it can be tedious to always start the process manually. Since
we aren't using Ant but Maven more regularly we thought about a slim Maven
integration. While SmartSprites does offer a Maven <i>artifact</i>, we only found an outdated, unfinished Maven <i>plugin</i> to actually apply SmartSprites as part of a Maven build, and so came up with something ourselves.
</span></div>
<div class="MsoNormal">
<span lang="EN-US">We arrived at a working first version (in fact it's <strike>1.5</strike> 1.8 by now) of such a plugin. It can surely be improved </span><span style="background-color: white;">further</span><span style="background-color: white;">, but working well for our needs.</span></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span lang="EN-US">Try it out!</span></h2>
<div class="MsoNormal">
<span lang="EN-US">The Plugin is available in the <a href="http://search.maven.org/#browse%7C1957841422" target="_blank">Maven central repository</a>. This makes integration into your project really easy.</span></div>
<div class="MsoNormal">
<span lang="EN-US">Just add
the following lines of code in your project’s pom.xml:</span><br />
<br /></div>
<blockquote class="tr_bq">
<pre><code><span lang="EN-US"><plugin></span></code></pre>
<pre><code><span lang="EN-US"> </span></code></pre>
<pre><code><span lang="EN-US"> <groupId>net.jangaroo</groupId></span></code></pre>
<pre><code><span lang="EN-US"> <artifactId>smartsprites-maven-plugin</artifactId></span></code></pre>
<pre><code><span lang="EN-US"> <version>1.8</version></span></code></pre>
<pre><code><span lang="EN-US"> </span></code></pre>
<pre><code><span lang="EN-US"> <configuration></span></code></pre>
<pre><code><span lang="EN-US"> <rootDirPath>src/main/sprites</rootDirPath></span></code></pre>
<pre><code><span lang="EN-US"> <cssFiles></cssFiles></span></code></pre>
<pre><code><span lang="EN-US"> <outputDirPath>${basedir}/target/generated-resources/</span></code></pre>
<pre><code><span lang="EN-US">META-INF/resources/spritesheets</outputDirPath></span></code></pre>
<pre><code><span lang="EN-US"> <documentRootDirPath></documentRootDirPath></span></code></pre>
<pre><code><span lang="EN-US"> <logLevel>WARN</logLevel></span></code></pre>
<pre><code><span lang="EN-US"> <spritePngDepth>AUTO</spritePngDepth></span></code></pre>
<pre><code><span lang="EN-US"> <spritePngIeSix>false</spritePngIeSix></span></code></pre>
<pre><code><span lang="EN-US"> <cssFileEncoding>UTF-8</cssFileEncoding></span></code></pre>
<pre><code><span lang="EN-US"> <cssFileSuffix></cssFileSuffix></span></code></pre>
<pre><code><span lang="EN-US"> </configuration></span></code></pre>
<pre><code><span lang="EN-US"> </span></code></pre>
<pre><code><span lang="EN-US"> <executions></span></code></pre>
<pre><code><span lang="EN-US"> <execution></span></code></pre>
<pre><code><span lang="EN-US"> <id>createSprites</id></span></code></pre>
<pre><code><span lang="EN-US"> <phase>generate-resources</phase></span></code></pre>
<pre><code><span lang="EN-US"> <goals></span></code></pre>
<pre><code><span lang="EN-US"> <goal>createSprites</goal></span></code></pre>
<pre><code><span lang="EN-US"> </goals></span></code></pre>
<pre><code><span lang="EN-US"> </span></execution></code></pre>
<pre><code> </executions></code></pre>
<pre><code> </code></pre>
<pre><code></plugin></code></pre>
</blockquote>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span lang="EN-US">You could
leave out the configuration part completely and default values would be used.
Following you’ll find the complete configuration guide. As all configuration attributes follow their SmartSprites counterparts closely, the description can be taken directly from the <a href="http://csssprites.org/" target="_blank">SmartSprites documentation</a>.</span><br />
<span lang="EN-US">Below you will find the correct camel case annotation and their default values if given. </span></div>
<h4>
<b><span lang="EN-US"><rootDirPath> </span></b></h4>
<span lang="EN-US">(default: src/main/sprites)</span><br />
<h4>
<b><span lang="EN-US"><cssFiles></span></b></h4>
<h4>
<b><span lang="EN-US"><outputDirPath</span></b><b><span lang="EN-US">></span></b></h4>
<span lang="EN-US">(default: ${basedir}/target/generated-resources/META-INF/resources/spritesheets)</span><br />
<h4>
<b><span lang="EN-US"><documentRootDirPath></span></b></h4>
<h4>
<b><span lang="EN-US"><logLevel></span></b></h4>
<span lang="EN-US">(default: WARN)</span><b><span lang="EN-US"> </span></b><br />
<h4>
<b><span lang="EN-US"><spritePngDepth></span></b></h4>
<div style="font-weight: normal;">
<span lang="EN-US">(default: AUTO) </span></div>
<h4>
<b><span lang="EN-US"><spritePngIeSix></span></b></h4>
<span lang="EN-US">(default: false) </span><span lang="EN-US"> </span><br />
<h4>
<b><span lang="EN-US"><cssFileEncoding></span></b></h4>
<span lang="EN-US">(default: UTF-8) </span><br />
<h4>
<b><span lang="EN-US"><cssFileSuffix></span></b></h4>
<span lang="EN-US">(default: null)</span><br />
<br />
<h2>
<span lang="EN-US">What about a demo
application?</span></h2>
<div class="MsoNormal">
<span lang="EN-US"></span></div>
<div class="MsoNormal">
<span lang="EN-US">Please find
a <a href="https://github.com/ljagenow/smartspritesExampleApp/tree/v1.0" target="_blank">demo application on github</a> showing you how to bundle your sprites in a webapp.
It is a small example just showing you how to integrate the
SmartSprites-Maven-Plugin into a webapp.</span></div>
<div class="MsoNormal">
<span lang="EN-US">The example
is rather straightforward so you just might want to take a look at the
following files:</span><br />
<ul>
<li><span lang="EN-US" style="font-size: large;"><span style="font-family: 'Courier New',Courier,monospace;">pom.xml</span></span></li>
<ul>
<li>l<span lang="EN-US">ine
23-40 for the SmartSprites part</span></li>
<li><span lang="EN-US">line
42-53 copy the generated ressources<span style="font-size: 7pt; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"> </span></span></li>
<li><span lang="EN-US">line
55-69 Jetty</span></li>
</ul>
</ul>
<ul>
<li><span lang="EN-US"><span style="font-size: large;"><span style="font-family: 'Courier New',Courier,monospace;">src/main/webapp/index.jsp</span></span> </span></li>
<ul>
<li><span lang="EN-US">divs for showing the images, line 16-21</span></li>
</ul>
</ul>
<ul>
<li><span lang="EN-US" style="font-size: large;"><span style="font-family: 'Courier New',Courier,monospace;">src/main/sprites/css/flags.css</span> </span></li>
<ul>
<li><span lang="EN-US">css configuration part</span></li>
</ul>
</ul>
</div>
<div class="MsoListParagraphCxSpLast" style="text-indent: -18pt;">
<br /></div>
<div class="MsoNormal">
<span lang="EN-US">The other
files are just for making this example look a bit nicer.</span><br />
<span lang="EN-US"><br /></span>
<span lang="EN-US">Since we use the SmartSprites Maven plugin ourselves for building an Enterprise software product, it will be maintained for quite a while. So feel free to use it, too, and please don't hesitate to give feedback either here or at the <a href="https://groups.google.com/group/jangaroo-users" target="_blank">Jangaroo user's group</a>!</span></div>
Anonymoushttp://www.blogger.com/profile/02692962793695518494noreply@blogger.com1tag:blogger.com,1999:blog-5783184094166463434.post-45398012746191044662012-06-08T10:01:00.000+02:002012-06-08T10:01:43.337+02:00Managing JavaScript Libraries with MavenJangaroo's mission is to create and apply Enterprise software development tools to Web development. While Jangaroo is known for its ActionScript-to-JavaScript compiler <span style="font-family: 'Courier New', Courier, monospace;">jooc</span>, we also care about "native" JavaScript development. In the process of creating a Maven-based build process for compiled ActionScript, we were baffled that there was not even a Maven-based build process for JavaScript. In fact, there is no version-, dependency- and artifact-managing build process for JavaScript at all (as far as we know).<br />
<br />
In the course of creating Jangaroo 2, and utilizing a <a href="http://alexismp.wordpress.com/2010/04/28/web-inflib-jarmeta-infresources/" target="_blank">new feature of Java Servlet 3</a>, we can now present a light-weight and easy way to use Maven for managing JavaScript library versions and their dependencies and adding them to your Web application.<br />
<br />
<h3>
Approach and Related Work</h3>
Note that we are not the only ones who provide Maven JAR artifacts containing repackaged JavaScript libraries. Independently, <a href="http://www.jamesward.com/2012/04/25/introducing-webjars-web-libraries-as-managed-dependencies" target="_blank">James Ward created a project called WebJars</a>, which does something quite similar as proposed here. He also uses JARs and Maven, but the difference is that he is targeting other Web servers and languages, essentially using the JAR as a ZIP. Our approach is to use the <a href="http://alexismp.wordpress.com/2010/04/28/web-inflib-jarmeta-infresources/" target="_blank">Servlet 3 JAR layout</a>, essentially putting all Web resources under the path <span style="font-family: 'Courier New', Courier, monospace;">META-INF/resources</span>. The main advantage is that every Servlet 3 compliant application server (Jetty 8, Tomcat 7, Glassfish 3, Resin 4, WebSphere 8, WebLogic 12) understands this standardized format (<a href="http://jcp.org/aboutJava/communityprocess/final/jsr315/index.html" target="_blank">JSR-315</a>) immediately without any plugin, Servlet or other extension. Another benefit is that you can add files to the JAR that are <i>not</i> supposed to be Web resources, e.g. other meta data and of course Java classes, so that you could for example unite code implementing the client- and server-part of some service in a single JAR.<br />
<br />
An organizational advantage we have over James' artifacts is that we deploy all repackaged artifacts of Open Source libraries (almost all JavaScript libraries are Open Source!) directly to the Maven Central repository, saving you the need to add <span style="font-family: 'Courier New', Courier, monospace;"><repository></span> sections to your Maven POM and leaving you independent from <i>our</i> Maven repository being online.<br />
<br />
<h3>
Try It Out!</h3>
The first available artifact is a repackaging of Ext JS 3.4.0 (yes, it is an old version, but take it as an example of the mechanism) and a very light-weight example project using this artifact. The following steps are needed <i>once</i> to have an environment to develop Maven-managed JavaScript Web applications:<br />
<br />
<ol>
<li>Install a recent Java SDK like 6 or 7</li>
<li>Install <a href="http://maven.apache.org/" target="_blank">Apache Maven</a>, current version 3.0.4</li>
<li>[Install git]</li>
</ol>
<div>
Checkpoint: calling <span style="font-family: 'Courier New', Courier, monospace;">mvn -v</span> on a shell should give you output similar to this:</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">> mvn -v</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"></span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;">Apache Maven 3.0.4 (r1232337; 2012-01-17 09:44:56+0100)</span></div>
<span style="font-family: 'Courier New', Courier, monospace;">
</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;">Maven home: ...</span></div>
<span style="font-family: 'Courier New', Courier, monospace;">
<div>
Java version: 1.6.0_25, vendor: Sun Microsystems Inc.</div>
<div>
Java home: ...</div>
<div>
Default locale: ...</div>
<div>
OS name: ...</div>
</span></div>
<br />
<br />
To try the Ext JS example project, <a href="https://github.com/fwienber/webjars-extjs-example/downloads" target="_blank">download</a> or clone from github:<br />
<span style="font-family: 'Courier New', Courier, monospace;">> git clone git://github.com/fwienber/webjars-extjs-example.git</span><br />
<br />
Then, all you need to do is build the project (which downloads all needed stuff from Maven Central when invoked for the first time) and start a Jetty Web server via Maven, simply via<br />
<span style="font-family: 'Courier New', Courier, monospace;">> mvn jetty:start</span><br />
The default port is 8080, so you can watch the resulting Web app in any browser using <span style="font-family: 'Courier New', Courier, monospace;">http://localhost:8080</span>. To prove that Ext JS has been loaded and works, the app just opens an Ext alert box.<br />
<br />
Only three small text files are needed to<br />
<ul>
<li>download the desired Ext JS library,</li>
<li>download Jetty webserver,</li>
<li>configure Jetty to serve the contents of the Ext JS library and the local project resources, and</li>
<li>start Jetty in development mode on <span style="font-family: 'Courier New', Courier, monospace;">localhost</span> port 8080.</li>
</ul>
<div>
The three files are</div>
<div>
<ol>
<li><span style="font-family: 'Courier New', Courier, monospace;">pom.xml</span> ―The Maven "Project Object Model" that configures the build,</li>
<li><span style="font-family: 'Courier New', Courier, monospace;">src/main/webapp/index.html</span> ―the HTML file containing the simply JavaScript application,</li>
<li><span style="font-family: 'Courier New', Courier, monospace;">src/main/webapp/WEB-INF/web.xml</span> ―Java Web configuration file.</li>
</ol>
<div>
Let me give you a walk-through of these three files.</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">pom.xml</span> is the key to letting Maven create and manage your application. Fortunately, this POM is quite simple, since we take advantage of conventions, and Maven prefers <a href="http://www.sonatype.com/books/mvnref-book/reference/installation-sect-conventionConfiguration.html" target="_blank">convention over configuration</a>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><</span><span style="font-family: 'Courier New', Courier, monospace;">?xml version='1.0' encoding='UTF-8'?></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <modelVersion>4.0.0</modelVersion></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <groupId>net.jangaroo.webjars.examples</groupId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <artifactId>webjars-extjs-example</artifactId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <version>0.1-SNAPSHOT</version></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <packaging>war</packaging></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <name>webjars-extjs-example</name></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <description>...</description></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <build></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <plugins></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <plugin></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <groupId>org.mortbay.jetty</groupId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <artifactId>jetty-maven-plugin</artifactId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <version>8.1.3.v20120416</version></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </plugin></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </plugins></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </build></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <dependencies></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <dependency></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <groupId>net.jangaroo.com.sencha</groupId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <artifactId>ext-js</artifactId></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <version>3.4.0</version></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </dependency></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </dependencies></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"></project></span></div>
</div>
<div>
<br /></div>
<div>
After the inevitable XML header (which is always the same), every Maven project model needs to specify a unique combination of <span style="font-family: 'Courier New', Courier, monospace;">groupId</span> and <span style="font-family: 'Courier New', Courier, monospace;">artifactId</span>, and a <span style="font-family: 'Courier New', Courier, monospace;">version</span>. For this test project, they really do not matter, since the generated artifact will never be deployed to a repository. The packaging type <span style="font-family: 'Courier New', Courier, monospace;">war</span> tells Maven that we are building a Web application (Java terminology: Web ARchive). <span style="font-family: 'Courier New', Courier, monospace;">name</span> and <span style="font-family: 'Courier New', Courier, monospace;">description</span> are just for human readability.</div>
<div>
The only plugin that needs to be mentioned explicitly is <span style="font-family: 'Courier New', Courier, monospace;">jetty-maven-plugin</span>, and you also need to specify the exact version you want to use. Well, it's still only a couple of lines to download and start a Web server, isn't it?</div>
<div>
To download a serve all Ext JS 3.4.0 resources, a simple <span style="font-family: 'Courier New', Courier, monospace;">dependency</span> suffices, thanks to the standard-conform JAR layout and central deployment of the artifact.</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">index.html</span> is the simplest HTML page you could think of that starts an Ext JS application. The only interesting thing here is how the resource paths have been chosen, because you do not actually "see" the Ext JS resources―they are hidden in a JAR somewhere in your local Maven repository (see below). For every JavaScript library repackaging, we have to agree upon a standard path where it is served in the Web application. For Ext JS, we chose <span style="font-family: 'Courier New', Courier, monospace;">/ext-js/</span> as the base path. The file structure below this base path is exactly as in the ZIP that can be obtained from <a href="http://www.sencha.com/products/extjs3/download/" target="_blank">Sencha's Ext JS 3 download page</a>.</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">web.xml</span> is only needed to disable a Jetty feature ("file locking") that hinders development, and to satisfy the Maven WAR plugin, which would have to be configured to not <<span style="font-family: 'Courier New', Courier, monospace;">failOnMissingWebXml></span> otherwise.</div>
<div>
<br /></div>
<div>
The Jetty Maven plugin configures Jetty in a clever way: library dependencies like Ext JS, which have been downloaded to your local Maven repository automatically (usually <span style="font-family: 'Courier New', Courier, monospace;">~/.m2/repository</span>), are served directly from that JAR. That means no files are extracted, not even the JARs needed by your Web app are copied. All local project Web resources are taken directly from src/main/webapp. Try changing index.html (e.g. the alert message) and reload in the browser: it works without further build or deployment!</div>
</div>
<br />
If you want a complete Web app that could be deployed into a remote Java application server, you can invoke <span style="font-family: 'Courier New', Courier, monospace;">mvn package</span>, and a directory <span style="font-family: 'Courier New', Courier, monospace;">target/webjars-extjs-example-0.1-SNAPSHOT</span> is created which contains all needed resources. This directory is also zipped as <span style="font-family: 'Courier New', Courier, monospace;">target/webjars-extjs-example-0.1-SNAPSHOT.war</span>.<br />
<br />
Unpacking all Web resources contained in JARs, e.g. to deploy them to a static Web server like Apache HTTP Server, is also possible via Maven, but I'll cover that in a later update.<br />
<br />
<h3>
Mighty Maven</h3>
What the simple example does not show is that, if ext-js 3.4.0 had a dependency on some other artifact, say ext-core 1.0, you wouldn't have to care about it. Simply specifying a dependency on ext-js lets Maven collect all transitive dependencies and add the corresponding artifacts to your Web application. Furthermore, if two libraries you use depend upon the same third library, Maven takes care of the third library being included only once, and offers dependency management to resolve possible version conflicts.<br />
<br />
All in all, given the complexity of the problem it solves, Maven provides a light-weight way to manage complex JavaScript Web applications, making it easy to keep track of libraries used, their versions, and their dependencies. Furthermore, Java Servlet 3 helps structure a Web application as a composite of modules instead of a huge bunch of files, which speeds up build process and test system start-up.<br />
<br />
<h3>
What Next?</h3>
Next is to repackage and deploy or release several JavaScript libraries. There are several options, so here we need your vote and maybe even your help. We plan to repackage the libraries and versions we (plan to) use at CoreMedia, for example jQuery 1.7, Ext JS 4.1.0, RequireJS 2.0.1, and CKEditor 3.6.2. If you need other JavaScript libraries or other versions, you can simply create an issue at <a href="http://jangaroo.myjetbrains.com/youtrack/issues/LIBS" target="_blank">JooTrack/LIBS</a>. We need the exact location of a download package or all single download links, and if you could provide additional information which files are usually needed in an actual deployment (e.g. no examples, no documentation, ...), it would help a lot. So start refactoring your large-scale JavaScript project today―clean up the JavaScript mess!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com6tag:blogger.com,1999:blog-5783184094166463434.post-9266497888791041122012-01-30T11:17:00.000+01:002012-01-30T11:17:23.542+01:00Simulating ActionScript Rest Parameter in JavaScriptLet's continue the series on simulating ActionScript language features in JavaScript with something similar to optional parameters, namely the <span style="font-family: 'Courier New', Courier, monospace;">...</span> (rest) parameter.<br />
ActionScript allows you to specify that an arbitrary number of parameters follow the usual named and optional parameters by prefixing the last parameter with three dots (see "<a href="http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f56.html" target="_blank">The ... (rest) parameter</a>"):<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 </span><span style="font-family: 'Courier New', Courier, monospace;">public function join(separator:String, first:String,</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> ...strings:Array):String </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 strings.splice(0, 0, first);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 return strings.join(separator);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 }</span><br />
<br />
As you can see, all formal parameters following the named parameters are combined into an array. Since the <span style="font-family: 'Courier New', Courier, monospace;">...</span> (rest) parameter is always of type <span style="font-family: 'Courier New', Courier, monospace;">Array</span>, you can safely skip the type annotation.<br />
<br />
<span style="font-size: large;">The <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> variable in JavaScript</span><br />
Fortunately, JavaScript offers access to all formal parameters of a function call, even if they are not declared as named parameters of the function, through the <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> variable. For some reason, this variable does not actually hold an <span style="font-family: 'Courier New', Courier, monospace;">Array</span>. Instead, it is an array-like <span style="font-family: 'Courier New', Courier, monospace;">Object</span> with indexed properties and a <span style="font-family: 'Courier New', Courier, monospace;">length</span> property. This means that we cannot invoke Array methods directly on <span style="font-family: 'Courier New', Courier, monospace;">arguments</span>, but there is a trick: Call the <span style="font-family: 'Courier New', Courier, monospace;">slice</span> function retrieved from the <span style="font-family: 'Courier New', Courier, monospace;">Array</span> prototype, as described e.g. <a href="http://debuggable.com/posts/turning-javascript-s-arguments-object-into-an-array:4ac50ef8-3bd0-4a2d-8c2e-535ccbdd56cb" target="_blank">here</a>, and the result is a "real" <span style="font-family: 'Courier New', Courier, monospace;">Array</span>:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">Array.prototype.slice.call(arguments)</span><br />
<br />
At the same time, we can cut off the named parameters, since the first parameter to slice is the index where to start slicing from the source array. Thus, the resulting JavaScript code generated by the Jangaroo compiler <span style="font-family: 'Courier New', Courier, monospace;">jooc</span> is the following:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function join(separator, first) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> var strings = Array.prototype.slice.call(arguments,2);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 strings.splice(0, 0, first);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 return strings.join(separator);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 }</span><br />
<br />
Note the <span style="font-family: 'Courier New', Courier, monospace;">slice</span> parameter value 2, which takes care of cutting off the two named parameters. Also note how Jangaroo only adds an auxiliary statement, but keeps all other statements exactly the same, which makes debugging a lot easier.<br />
<br />
<span style="font-size: large;">Side note: <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> is an array is AS3</span><br />
The only thing Jangaroo currently does not yet implement correctly is that in ActionScript, the <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> variable is actually always an array! Thus, instead of writing<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public function joinComma() {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return arguments.join(",");</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<br />
which would be fine in ActionScript, in Jangaroo you currently have to use<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public function joinComma(...args) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return args.join(",");</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<br />
This is to save the overhead of always converting <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> into an array. Of course, the compiler could analyze whether <span style="font-family: 'Courier New', Courier, monospace;">arguments</span> is used as an <span style="font-family: 'Courier New', Courier, monospace;">Array</span> at all and only add the conversion code then. I just filed the bug as <a href="http://jangaroo.myjetbrains.com/youtrack/issue/JOO-12">issue JOO-12</a>.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-82610606854256843742012-01-28T14:23:00.000+01:002012-02-09T17:44:55.606+01:00Simulating ActionScript Parameter Default Values in JavaScriptTo continue our series on simulating ActionScript language features in JavaScript, this episode is about parameter default values.<br />
In contrast to JavaScript, ActionScript allows to specify a default value for a function (or method) parameter, like so:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public function insult(s = "fool") {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return "you " + s;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<br />
The idea is that when the method is called without providing a value for parameter <span style="font-family: 'Courier New', Courier, monospace;">s</span>, the default value <span style="font-family: 'Courier New', Courier, monospace;">"fool"</span> will be used. Details on what additional rules hold for declaring parameter default values are given in the <a href="http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f56.html" target="_blank">Adobe documentation on function parameters</a> and a bit less reference-like e.g. in a <a href="http://ntt.cc/2009/04/22/beginning-actionscript-3-default-parameter-values.html" target="_blank">tutorial on Ntt.CC</a>.<br />
<br />
<span style="font-size: large;">Why, it's easy, isn't it?</span><br />
A straight-forward implementation in JavaScript (similar to the solution <a href="http://blogs.adobe.com/bparadie/2011/11/26/classes-inheritance-interfaces-packages-and-namespaces/" target="_blank">suggested by Bernd Paradies for FalconJS</a>) would be to replace <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> paramter values by their default value:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function insult(s) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if (s === undefined) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> s = "fool";</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return "you " + s;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
<div>
(We could now start a discussion on whether it shouldn't be</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> if (typeof s === "undefined") {</span></div>
<div>
<span style="font-family: inherit;">because </span>in JavaScript, <span style="font-family: 'Courier New', Courier, monospace;">undefined</span><span style="font-family: inherit;"> may be redefined, but anybody who does so is, excuse me, a fool.)</span></div>
In JavaScript, when you omit a parameter when calling a function, the parameter value indeed is <span style="font-family: 'Courier New', Courier, monospace;">undefined</span>. But it is a fallacy to assume that <i>every</i> <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> parameter must be replaced by its default value! Consider the following ActionScript class:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public class DefaultParameterTest {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 public function DefaultParameterTest() {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 trace("1. " + </span> <span style="font-family: 'Courier New', Courier, monospace;">insult</span> <span style="font-family: 'Courier New', Courier, monospace;">("nerd"));</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 5 trace("2. " + </span>
<span style="font-family: 'Courier New', Courier, monospace;">insult</span> <span style="font-family: 'Courier New', Courier, monospace;">());</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 6 trace("3. " + </span>
<span style="font-family: 'Courier New', Courier, monospace;">insult</span> <span style="font-family: 'Courier New', Courier, monospace;">(undefined));</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 7 }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 8</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 9 public function insult(s = "fool") {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">10 return "you " + s;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">11 }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">12 }</span><br />
<div>
<br /></div>
<div>
What do you think will be traced? Try it out, and you'll see that explicitly handing in <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> does <i>not</i> trigger the default value! Thus, the result is</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">1. you nerd</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">2. you fool</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">3. you undefined</span></div>
<div>
<br /></div>
<div>
(Careful, never call a JavaScript programmer <i>"you undefined"</i>!)</div>
<div>
Using the straight-forward JavaScript implementation, the result would be</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">1. you nerd</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">2. you fool</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">3. you fool</span></div>
<div>
<br /></div>
<div>
As you can see, using parameter default values depends on the <i>number</i> of formal arguments, not on their value. This is the reason why they are also called <i>optional parameters</i>, and why after a parameter with a default value, all following parameters must also specify a default value.</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Getting it right</span></div>
<div>
Thus, the correct JavaScript equivalent (as generated by the Jangaroo compiler <span style="font-family: 'Courier New', Courier, monospace;">jooc</span>) is to check the number of formal parameters. Fortunately, this can be realized by checking <span style="font-family: 'Courier New', Courier, monospace;">arguments.length</span>:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function insult(s) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if (arguments.length < 1) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> s = "fool";</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return "you " + s;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
In fact, this solution even provides better runtime performance when using multiple optional parameters, since multiple <span style="font-family: 'Courier New', Courier, monospace;">arguments.length</span> checks can be nested, while the <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> checks in the straight-forward solution would be sequential. Consider the following example:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public function foo(p1, p2, p3 = 3, p4 = 4) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return p1 + p2 + p3 + p4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
The JavaScript fragment generated by Jangaroo looks like so:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function foo(p1, p2, p3, p4) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if (arguments.length < 4) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if (arguments.length < 3) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p3 = 3;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p4 = 4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return p1 + p2 + p3 + p4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
<div>
Jangaroo even optimizes <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> default values, since left out actual parameters are <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> in JavaScript, anyway.
</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Alternative Solutions</span></div>
We also thought of using a <span style="font-family: 'Courier New', Courier, monospace;">switch</span> statement, generating code like the following:</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function foo(p1, p2, p3, p4) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> switch (arguments.length) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 0:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 1:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 2:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p3 = 3;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // fall through</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 3:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p4 = 4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return p1 + p2 + p3 + p4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
<div>
At first sight, this solution seems more efficient, because <span style="font-family: 'Courier New', Courier, monospace;">arguments.length</span> is only evaluated once. The reason why we still chose the nested <span style="font-family: 'Courier New', Courier, monospace;">if</span> code layout is that the <span style="font-family: 'Courier New', Courier, monospace;">switch</span> solution becomes either long or non-robust when using many non-optional parameters. Note the lines <span style="font-family: 'Courier New', Courier, monospace;">case 0:</span> and <span style="font-family: 'Courier New', Courier, monospace;">case 1:</span> in the example above: although the method should never be called with less than two parameters (since the first two are <i>not</i> optional), we want to handle that case, too, since Jangaroo code may be called from JavaScript, where no function signature check is performed. When the function is called with fewer parameters than required, you would still expect the default values to pop in. So the case statements would pile up when there are many non-optional parameters. However, I could imagine a mixed solution like the following:</div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> 1 function foo(p1, p2, p3, p4) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> switch (Math.max(arguments.length, 2)) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 2:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p3 = 3;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // fall through</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> case 3:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> p4 = 4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 return p1 + p2 + p3 + p4;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 }</span><br />
<div>
<br /></div>
The most intelligent solution would be to dynamically decide whether the prior length check pays off against adding several case statements. I guess I'll add that to the Jangaroo backlog!</div>Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com5tag:blogger.com,1999:blog-5783184094166463434.post-75881108764736035862011-12-06T09:28:00.000+01:002012-01-28T14:06:33.356+01:00Simulating ActionScript in JavaScript: Private Members Cont'dIn the <a href="http://blog.jangaroo.net/2011/11/simulating-actionscript-in-javascript.html">first blog post about simulating private members in ActionScript</a>, I compared different solutions to represent private members in JavaScript. The solution implemented by Jangaroo is to rename private members, so that they do not name-clash with private members of the same class, defined on a different inheritance level.<br />
<a href="http://blog.jangaroo.net/2011/11/simulating-actionscript-in-javascript.html?showComment=1322963920098#c7266168798175422949">Bernd Paradies asked</a> how Jangaroo solves untyped access to private members. Since the answer is rather extensive, I'll dedicate this follow-up post to the topic.<br />
<br />
The short answer is: it's the nature of the beast. Untyped access to private members cannot be detected at compile time. However, <i>potential</i> access to private members can be detected at compile time and generate code that repeats the check at runtime, although Jangaroo does not implement this at the moment.<br />
<br />
<span style="font-size: large;">Typed Private Member Access</span><br />
Let's recall the typical way to access private members, which can easily be detected by the Jangaroo compiler:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public class Foo {</span><br />
<div style="font-family: "Courier New",Courier,monospace;">
2 private var foo:String = "bar";</div>
<div style="font-family: "Courier New",Courier,monospace;">
3 public function getFoo():String {</div>
<div style="font-family: "Courier New",Courier,monospace;">
4 return foo;</div>
<div style="font-family: "Courier New",Courier,monospace;">
5 }</div>
<span style="font-family: 'Courier New', Courier, monospace;"> 6 }</span><br />
<br />
As <span style="font-family: 'Courier New', Courier, monospace;">foo</span> in line 4 is resolved to a field of the class, and there is no implicit <span style="font-family: 'Courier New', Courier, monospace;">this</span> access in JavaScript, the Jangaroo compiler adds <span style="font-family: 'Courier New', Courier, monospace;">this.</span> before <span style="font-family: 'Courier New', Courier, monospace;">foo</span>. Also, as field <span style="font-family: 'Courier New', Courier, monospace;">foo</span> is declared private, the compiler renames it to <span style="font-family: 'Courier New', Courier, monospace;">foo$1</span> (see previous blog post) and thus generates the following JavaScript code for the body of method <span style="font-family: 'Courier New', Courier, monospace;">getFoo()</span>:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 return this.foo$1;</span><br />
<br />
<span style="font-size: large;">Where is My Type?</span><br />
Now consider the following code (which does not really make sense, but illustrates the point):<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 1 public class Foo {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 2 private var foo:String = "bar";</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 3 public function getFoo():String {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 var untypedThis:Object = this;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 5 return untypedThis.foo;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 6 }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 7 }</span><br />
<br />
Of course, in this simple example it would still be possible to determine the runtime type of <span style="font-family: 'Courier New', Courier, monospace;">untypedThis<span style="font-family: inherit;"> </span></span>statically, but it is easy to imagine a situation where this is not possible. In the current Jangaroo implementation, the following JavaScript code would be generated for the body of method <span style="font-family: 'Courier New', Courier, monospace;">getFoo()</span>:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 4 var untypedThis = this;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> 5 return untypedThis.foo;</span><br />
<br />
As you can see, the compiler fails to detect that <span style="font-family: 'Courier New', Courier, monospace;">foo</span> actually refers to the private member, does not rename the access to <span style="font-family: 'Courier New', Courier, monospace;">foo$1</span>, and thus the <span style="font-family: 'Courier New', Courier, monospace;">undefined</span> value of <span style="font-family: 'Courier New', Courier, monospace;">untypedThis.foo</span> would be returned.<br />
<br />
A (partial) solution is to let the compiler detect any expression of the form <span style="font-family: 'Courier New', Courier, monospace;">untyped</span><span style="font-family: 'Courier New', Courier, monospace;">.</span><i>private-member</i> and generate code that takes into account the runtime type of <span style="font-family: 'Courier New', Courier, monospace;">untyped</span>, like so:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 5 return untyped[untyped instanceof Foo ? 'foo$1' : 'foo'];</span><br />
<br />
Trusting today's JavaScript JIT compilers' optimizations, this code should be moved to a utility function to avoid double evaluation of the untyped expression (which could have side effects):<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> 5 return Foo.$class.get(untyped, 'foo');</span><br />
<br />
where <span style="font-family: 'Courier New', Courier, monospace;">Foo.$class</span> provides access to Jangaroo's "meta class" of <span style="font-family: 'Courier New', Courier, monospace;">Foo</span>, and <span style="font-family: 'Courier New', Courier, monospace;">get()</span> would be implemented there like this:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> public function get(object:Object, property:String):* {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> return object[object instanceof this.publicConstructor ?</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> property + this.inheritanceLevel : property];</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<br />
<span style="font-size: large;">The Weak and the Wicked</span><br />
Looking at ActionScript carefully, you'll notice that the identifier or expression left of the dot does not even have to be untyped, but may just be typed with a more general type, and the same scenario may apply. For example, assume our class <span style="font-family: 'Courier New', Courier, monospace;">Foo</span> is a subclass of <span style="font-family: 'Courier New', Courier, monospace;">dynamic</span> class <span style="font-family: 'Courier New', Courier, monospace;">Bar</span>, we could replace <span style="font-family: 'Courier New', Courier, monospace;">Object</span> by <span style="font-family: 'Courier New', Courier, monospace;">Bar</span>, and the example would still work! Even if <span style="font-family: 'Courier New', Courier, monospace;">Bar</span> is not <span style="font-family: 'Courier New', Courier, monospace;">dynamic</span>, we could access the private member <span style="font-family: 'Courier New', Courier, monospace;">foo</span> through a local variable of type <span style="font-family: 'Courier New', Courier, monospace;">Bar</span> using square brackets, like so:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public class Foo extends Bar {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> private var foo:String = "bar";</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> public function getFoo():String {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> var weaklyTypedThis:Bar = this;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> return weaklyTypedThis['foo'];</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
The Flex compiler does not complain, and at runtime, in Flash, indeed the private member is accessed. Compare this to the following example, where we try to access the private member of a superclass:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">public class Baz extends Foo {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> public function Baz() {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> super();</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> var superThis:Foo = this;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> trace(superThis['foo']); // is undefined, not "bar"!</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
Maybe you'll be surprised that the result is not any kind of access violation, but simply <span style="font-family: 'Courier New', Courier, monospace;">undefined</span>—the private member of the superclass is simply <i>not visible</i> for the subclass! This is well emulated by Jangaroo through renaming private members. The Jangaroo compiler just has to take care to detect every <i>correct</i> access of a private member and rename the property upon access.<br />
<br />
<span style="font-size: large;">Turing Strikes Again</span><br />
Things get even nastier when the <i>property</i> is a dynamic expression. Consider<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> return this[veryComplicatedComputation()];</span><br />
<br />
Here, too, we'd have to generate<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> return Foo.$class.get(this, veryComplicatedComputation());</span><br />
<br />
and extend the utility function by a runtime check whether the property is actually a private member name:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> public function get(object:Object, property:String):* {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> return object[object instanceof this.publicConstructor &&</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> this.getMemberDeclaration("private", property) ?</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> property + this.inheritanceLevel : property];</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<br />
<span style="font-size: large;">Summary</span><br />
Taken together, the important criterion when to generate code for possible private member access is not whether the left-hand expression of the dot is untyped, but the compiler has to check whether the complete <i>property access</i> is not typed. This is the case exactly when the property is not a compile-time constant or when the property cannot be resolved statically within the type of the expression, and in any case, the type of the expression must be a supertype of the current class or the current class itself.<br />
<br />
To wrap up, the compiler would have to generate a call to the dynamic access function if and only if<br />
<ol>
<li>the left-hand expression <i>could</i> have a runtime type compatible to the current class <i>and</i> </li>
<li>the property expression <i>could</i> be one of the current class's private members.</li>
</ol>
Here, <i>could</i> means that it may be, but is not certain at compile time. If both conditions are certain at compile time, the compiler knows for sure that the code represents access to a private member, and can simply use the renamed property.<br />
<br />
One more thing: I have been talking about read access of private members. The same strategy would have to be applied when <i>writing</i> members, resulting in another utility function<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: inherit;"> </span>set(object, property, value)</span>.<br />
<br />
<span style="font-size: large;">Optimize?</span><br />
Of course, we could optimize runtime performance by using specific utility functions for the following three different cases:<br />
<ol>
<li>The property is definitely a private member, but the left-hand expression may or may not be of the current class: check <span style="font-family: 'Courier New', Courier, monospace;">instanceof</span> only.</li>
<li>The left-hand expression is definitely of the current class, but the property may or may not be a private member: check the property only.</li>
<li>Both the left-hand expression may or may not be of the current class, and the property may or may not be a private member: check <span style="font-family: 'Courier New', Courier, monospace;">instanceof</span> <i>and</i> the property.</li>
</ol>
However, my guess is that this optimization is not necessary. Firstly, checking <span style="font-family: 'Courier New', Courier, monospace;">instanceof</span> and whether some string is contained in a fixed and not very large set are cheap operations. Secondly, when using ActionScript (and not untyped JavaScript), you should avoid untyped access of properties whenever possible. Thus, the situation is a rare case, and would only be implemented for full ActionScript semantic compatibility. If the developer wants better performance, she can either insert a type cast to convert the property access to a typed one, or move dynamic properties to a dedicated object whose type is statically incompatible with the current class (e.g. use <span style="font-family: 'Courier New', Courier, monospace;">Dictionary</span>), and thus no runtime check would be generated.<br />
If this solution proves to inflict significant runtime overhead, the compiler should issue a warning when it has to generate runtime checks.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com4tag:blogger.com,1999:blog-5783184094166463434.post-48429954669371951802011-11-30T14:35:00.000+01:002011-12-02T13:13:22.605+01:00Simulating ActionScript in JavaScript: Private MembersInspired by Adobe's Bernd Paradies, member of the FalconJS / FlashRT team, <a href="http://blogs.adobe.com/bparadie/" target="_blank">blogging about his ideas on "Compiling ActionScript to JavaScript"</a>, I thought it was about time to give more details about how Jangaroo implements ActionScript language features. Because there are so many of them, blogging about them one at a time seems like a good idea. Let's start with "private members".<br />
<br />
<span style="font-size: large;">The Early Days</span><br />
When people started simulating class-based OOP in JavaScript, many thought that it is not possible to define private members that support the principle of <i>information hiding</i>, because in JavaScript, all properties of an object are publicly accessible. So in many cases, the convention was used to let private members start with an underscore ("_"), meaning "don't use this member, best assume it is not existing at all".<br />
<br />
<span style="font-size: large;">The Reference Solution</span><br />
As we all know in the meantime, it <i>is</i> possible to implement real information hiding in JavaScript, namely by using closures / lexical scoping. Douglas Crockford (who else?) has written a nice summary of this approach back in 2001: <a href="http://javascript.crockford.com/private.html" target="_blank">Private Members in JavaScript</a><br />
So it looks like all we have to do to simulate ActionScript's private members in JavaScript is to use this pattern, right? Of course, it is not that easy, as in practice, there are two problems with private members à la Crockford:<br />
<ol>
<li>Runtime overhead</li>
<li>Source-code placement</li>
</ol>
While the first is a general problem, the second is Jangaroo-specific.<br />
The runtime overhead of closures results from the fact that in Crockford's solution, private members and privileged methods (methods that use private members) have to be defined inside the constructor. This means that the corresponding function objects are created <i>for every instance of the class</i>! This results in a performance penalty as well as in increased memory usage. Of course, this is not an issue for classes with few instances (extreme: singletons), but for classes like events, where you create many, many instances, this can quickly become a major problem.<br />
The second problem, source-code placement, results from a specific Jangaroo feature. In <a href="http://www.jangaroo.net/tutorial/debugging/" target="_blank">debug mode</a>, the Jangaroo compiler generates JavaScript code that keeps every piece of executable code at exactly the same line as in the ActionScript source file. This is a central feature of Jangaroo and very important for source-level debugging with a free choice of JavaScript debugger. So how can we place private and privileged methods inside the constructor, when in the ActionScript source code, they are not?<br />
<br />
<span style="font-size: large;">The Super-Secret Private This</span> <br />
For solving the source-code placement issue, I came up with the idea of a "shared private this" object. It turned out that this approach makes things a bit more complicated and only mitigates (but not removes) the runtime overhead, so it did not actually make it into Jangaroo, but still I'd like to present it here.<br />
The basic idea is that private members, as opposed to being local variables in constructor scope, are properties of a single object that is defined inside the constructor. To be shared, this "private this" object has to be "injected" into, i.e. put in the surrounding lexical scope of every privileged method. Consider the following class, which is the ActionScript version of the example used by Douglas Crockford:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;"> 1 public class Container {<br /> 2 public var member:String;<br /> 3 private var secret:int;</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> 4</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> 5 public function Container(param:String) {<br /> 6 member = param;</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> 7 secret = 3;</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> 8 }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> 9 </span><br />
<span style="font-family: "Courier New",Courier,monospace;">10 public function stamp(string:String):String {</span><br />
<span style="font-family: "Courier New",Courier,monospace;">11 return member + string;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">12 }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">13</span><br />
<span style="font-family: "Courier New",Courier,monospace;">14 private function dec():Boolean {</span><br />
<span style="font-family: "Courier New",Courier,monospace;">15 if (secret > 0) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;">16 secret -= 1;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">17 return true;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">18 } else {</span><br />
<span style="font-family: "Courier New",Courier,monospace;">19 return false;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">20 }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">21 }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">22</span><br />
<span style="font-family: "Courier New",Courier,monospace;">23 public function service():String {</span><br />
<span style="font-family: "Courier New",Courier,monospace;">24 return dec() ? member : null;</span><br />
<span style="font-family: "Courier New",Courier,monospace;">25 }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">26 }</span></blockquote>
To inject the "private this" into all privileged methods, we wrap these inside functions. What Douglas calls <span style="font-family: "Courier New",Courier,monospace;">that</span>, we'll call <span style="font-family: "Courier New",Courier,monospace;">this$</span>, and all other helper idenfiers are suffixed with <span style="font-family: "Courier New",Courier,monospace;">$</span>. Here is the resulting JavaScript code:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace; font-size: small;"> 1 Container = (function() {<br />
2 //public var member:String;<br />
3 //private var secret:int;<br />
4<br />
5 var Container = function(param) { var this$ = init$(this);<br />
6 this.member = param;<br />
7 this$.secret = 3;<br />
8 };<br />
9<br />
10 Container.prototype.stamp = function(string) {<br />
11 return this.member + string;<br />
12 };<br />
13<br />
14 var dec = function() {<br />
15 if (this.secret > 0) {<br />
16 this.secret -= 1;<br />
17 return true;<br />
18 } else {<br />
19 return false;<br />
20 }<br />
21 };<br />
22<br />
23 var service$ = function(this$){return function(){<br />
24 return this$.dec() ? this.member : null;<br />
25 };};<br />26<br />27 var init$ = function(o) {<br />28 var this$ =</span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> {<br />29 dec: dec<br />30 };</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">31 o.service = service$(this$);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">32 return this$;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">33 }</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">34</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">35 return Container;<br />36 })();</span></span></blockquote>
Note how all executable code stays in exactly the same line, and how similar it can be expressed in JavaScript!<br />
The following variants of Douglas' patterns were used:<br />
<ul>
<li>Private methods are only defined once (reduces runtime overhead!), and are supposed to be called on the "private this". If they need to access public members, too, we could easily extend the "private this" by a reference to the "public this".</li>
<li>Privileged methods are wrapped in a function that receives the "private this", so that the current "private this" is in lexical scope. </li>
<li>To keep all source code at its original location, all additional initialization is moved to a generated method <span style="font-family: "Courier New",Courier,monospace;">init$</span>. It creates the "private this" <span style="font-family: "Courier New",Courier,monospace; font-size: small;">this$</span> with all private members, creates instances of privileged methods handing in <span style="font-family: "Courier New",Courier,monospace;">this$</span>, and assigns these to the "public this".</li>
</ul>
<br />
<span style="font-size: large;">The Pragmatic Solution</span><br />
As said above, this solution still introduces runtime overhead and a bit complexity, so we looked for a more efficient and simpler alternative. I mentioned the naive approach to use a simple naming convention. The real flaw in this approach is <i>not </i>that you can access "private" members when you should not be able to. When compiling ActionScript to JavaScript, we can check access rights on the ActionScript source, so this is not an issue. But what this approach breaks is that private members are also used to <i>avoid name clashes between subclass and superclass</i>!<br />
Image you define a framework, and provide some base class that is supposed to be extended by clients of the framework. This base class usually provides members with different visibility. The private members (and the "internal" ones, which we neglect for now) can <i>not</i> be seen by a subclass. A client's subclass could define its own private members any way they like, as long as they don't name-clash with public or protected members of the superclass.<br />
Now you update the framework and add a private method, as you think this should not change the framework API. But if we use the naive naming convention of prefixing all private members with an underscore (or the like), there is now the chance that the new private member of the superclass name-clashes with an existing private member of the client's subclass!<br />
Jangaroo's pragmatic solution to separate private members of different inheritance levels within one class is to suffix private member names with a <span style="font-family: "Courier New",Courier,monospace;">$</span> followed by the numeric <i>inheritance level</i>. <span style="font-family: "Courier New",Courier,monospace;">Object</span> has inheritance level 0, and a class extending X has the inheritance level of X plus one. This effectively prevents name-clashes between private members of the same name, but defined on different inheritance levels, and thus solves the framework update problem described above.<br />
We used to compute the inheritance level of a class at runtime, but this made class loading and initialization more complex. Thus, we later decided to let the compiler compute the inheritance level. Of course this reduces "binary" compatibility, meaning that when you refactor a framework class e.g. by introducing an intermediate class in the inheritance hierarchy, clients will have to recompile their code, or the inheritance level of their subclass will be incorrect. But recompiling (without changing the source code) after updating a framework should not really be a problem.<br />
To give a concrete example, here is the simplified generated JavaScript code for the example above. It is not exactly what Jangaroo would produce, as there are many other features covered by the Jangaroo Runtime, which I'll elaborate on in upcoming blog posts. Also, it does not illustrate the inheritance issue, but just imagine a subclass that also defines a private field <span style="font-family: "Courier New",Courier,monospace;">secret</span>, which would then be renamed <span style="font-family: "Courier New",Courier,monospace;">secret$2</span>.<br />
<blockquote class="tr_bq">
<div style="font-family: "Courier New",Courier,monospace;">
<span style="font-size: small;"> </span><span style="font-family: "Courier New",Courier,monospace; font-size: small;">1 Container = (function() {<br />
2 //public var member:String;<br />
3 //private var secret:int;<br />
4<br /> 5 var Container = function(param) {<br />
6 this.member = param;<br />
7 this.secret$1 = 3;<br />
8 };<br />
9<br />
10 Container.prototype.stamp = function(string) {<br />
11 return this.member + string;<br />
12 };<br />
13<br />
14 Container.prototype.dec$1 = function() {<br />
15 if (this.secret$1 > 0) {<br />
16 this.secret$1 -= 1;<br />
17 return true;<br />
18 } else {<br />
19 return false;<br />
20 }<br />
21 };<br />
22<br />
23 <span style="font-family: "Courier New",Courier,monospace;">Container.prototype.</span>service = function() {<br />
24 return this.dec$1() ? this.member : null;<br />
25 };<br />26<br />27 </span><span style="font-size: small;">return Container;<br />28 })();</span></div>
</blockquote>
<span style="font-size: large;">Wrap-Up</span><br />
Let me conclude with an overview of the four solutions for private members in JavaScript discussed here.<br />
<table border="1">
<tbody>
<tr>
<td></td>
<td>naive naming convention</td>
<td>private members<br />
(D. Crockford)
</td><td>private this</td>
<td>inheritance level suffix<br />
(used in Jangaroo)</td>
</tr>
<tr>
</tr>
<tr>
<td>information hiding</td>
<td>✕</td>
<td>✓</td>
<td>✓</td>
<td>✕</td>
</tr>
<tr>
<td>avoiding name-clashes</td>
<td>✕</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>no runtime overhead</td>
<td>✓</td>
<td>✕</td>
<td>✕</td>
<td>✓</td>
</tr>
<tr>
<td>keep source lines</td>
<td>✓</td>
<td>✕</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody></table>
As you can see in the table, there is no perfect solution (no column
with checkmarks in every row), so for Jangaroo, we chose the pragmatic
one that ensures good performance, while having some drawbacks on
information hiding.<br />
<br />
<span style="font-size: large;">Outlook</span><br />
Since performance is the only argument against the "private this" solution, we should investigate in performance analysis of today's JavaScript engines to quantify the time and space overhead introduced by the appoach. Maybe it is not that bad after all.<br />
With all modern browsers supporting the JavaScript API <span style="font-family: "Courier New",Courier,monospace;">Object.defineProperty()</span>,we can improve Jangaroo's pragmatic solution's information hiding by defining all private members to not be enumerable. Taking a closer look at ActionScript semantics, actually, <i>all</i> class members are not enumerable, i.e. they are all not visible in a <span style="font-family: "Courier New",Courier,monospace;">for ... in</span> loop (only dynamic properties are).<br />
There are several possible improvements to approximate ActionScript semantics more closely when relying on features of a modern JavaScript engine (ECMAScript 5). I'll come to these when discussing further ActionScript language features.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com5tag:blogger.com,1999:blog-5783184094166463434.post-68606030712668737972011-11-10T22:04:00.000+01:002011-11-10T23:37:22.486+01:00Enterprise JavaScript with Jangaroo at PLASTIC / SPLASH 2011While almost one year ago, we talked about "Jangaroo - AS3 w/o FlashPlayer", we thought it was about time to stress the other story, namely using Jangaroo for creating large-scale JavaScript applications. Because that's what we do very successfully at CoreMedia.<br />
Several people (thanks Florian, Martin!) pointed us at a very fitting call for papers of the <a href="http://plastic.host.adobe.com/" target="_blank">PLASTIC workshop</a> at the <a href="http://splashcon.org/2011/" target="_blank">SPLASH 2011</a>. It is about Programming Languages And Systems Technologies for Internet Clients, with a focus on "compilation and runtime techniques for Internet client programming
languages". Andreas kicked off the paper, Olaf and Dennis supported with proof-reading, LaTeX support and helpful comments, and I fleshed out the text and extended the parts of my expertise, namely the runtime, libraries, and build process. The paper, entitled <i>Enterprise JavaScript with Jangaroo --<br />Using ActionScript 3 for JavaScript ”Programming in the Large”</i>, was accepted and can be <a href="http://plastic.host.adobe.com/plastic4.pdf" target="_blank">downloaded here</a>.<br />
On 24th of October, I presented the corresponding talk at the PLASTIC workshop in Portland, Oregon. To not bore the part of the audience who already read the paper (maybe the empty set?), the slides show a third category of "how to execute another programming language in the browser", since providing a client-side interpreter seems to be a hot topic (mostly because of <a href="http://www.google.com/doubleclick/studio/swiffy/" target="_blank">Google swiffy</a>, but there are others, too). But have a look at the slides for yourself.<br />
<div id="__ss_9865205" style="width: 425px;">
<b style="display: block; margin: 12px 0pt 4px;"><a href="http://www.slideshare.net/FrankWienberg/plastic-2011-enterprise-javascript-with-jangaroo" target="_blank" title="PLASTIC 2011: "Enterprise JavaScript with Jangaroo"">PLASTIC 2011: "Enterprise JavaScript with Jangaroo"</a></b><b style="display: block; margin: 12px 0pt 4px;"> </b> <iframe frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/9865205" width="425"></iframe> <br />
<div style="padding: 5px 0pt 12px;">
View more <a href="http://www.slideshare.net/FrankWienberg" target="_blank">presentations about Jangaroo</a> </div>
</div>
Before starting with the slides, I showed off the demos <a href="http://www.jangaroo.net/files/examples/flash/box2d/" target="_blank">Box2D</a> and <a href="http://www.jangaroo.net/files/examples/flash/open-flash-chart/data-files/joo.html" target="_blank">Open Flash Charts</a>, which I admit are a bit off-topic, since they rather belong to the "port Flash applications to HTML5" story than to "Enterprise JavaScript", but hey, they are always good to get people's attention ;-).<br />
I hope I could get across what Jangaroo is able to, and got some interesting feedback. Adam Welc (Co-Chair of the workshop, in his other life working on Flash at Adobe) pointed me to another Flash-related Open Source projects, <a href="http://sourceforge.net/apps/trac/lightspark" target="_blank">lightspark</a>, which might help in getting on with Jangaroo's Flash re-implementation <a href="https://github.com/CoreMedia/jangaroo-libs/tree/master/jooflash/src/main/joo/flash" target="_blank">JooFlash</a>.<br />
People liked the way Jangaroo keeps the generated code close to the source, even keeping line numbers to allow source-level debugging.<br />
The most motivating part when visiting a workshop or conference is of course about meeting people. I remembered Google's Mark Miller from the <a href="http://ajaxexperience.techtarget.com/conference/index.html" target="_blank">Ajax Experience 2009 in Boston</a>, who here at PLASTIC co-authored a paper about <a href="http://plastic.host.adobe.com/plastic1.pdf">traits.js</a>: recommended read! Christian Hammer, Andreas Gampe, Aiman Erbad and several others also presented and we had interesting discussions. Was nice getting to know you guys!<br />
Another JavaScript guru I also met first on Ajax Experience is Rik Arends, then at ajax.org, who now does a wonderful job over at <a href="http://c9.io/about.html" target="_blank">Cloud9IDE</a>. I tell you he's one of the good guys (even if we disagree on where to use typed languages and compilers)!<br />
Finally, I loved the key note of David Ungar, <a href="http://www.dynamic-languages-symposium.org/dls-11/program/media/Ungar_2011_EverythingYouKnowAboutParallelProgrammingIsWrongAWildScreedAboutTheFuture_Dls.pdf"><i>Everything You Know (about Parallel Programming) Is Wrong! A Wild Screed about the Future</i></a>; he really is a great presenter! Using <i>Romeo and Juliet</i> as an example of parallel actions that went wrong (and might have ended up "hunky-dory" in a different sequentialization) is really funky...Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0Hilton, 921 SW 6th Ave, Portland, OR 97204, USA45.517523 -122.67992745.516132 -122.6823945 45.518913999999995 -122.67745950000001tag:blogger.com,1999:blog-5783184094166463434.post-29403134194968931722010-11-26T12:29:00.000+01:002010-11-26T12:29:16.772+01:00Jangaroo at FlashCodersNYTyler Larson of <a href="http://flashcodersny.com/">FlashCodesNY</a> asked us whether we'd be interested to present and discuss Jangaroo on one of their weekly meetings in Manhatten. The <a href="http://jangaroo-at-fcny.eventbrite.com/?ref=estw">event took place</a> on Wednesday 17th of November in Manhattan, while Andreas and I were connected via live streaming from Hamburg. Well, our time zone offset is not really ideal for meetings in the late afternoon in New York, but with lots of coffee and adrenaline, we hopefully managed to give an exciting presentation of what Flash coders can do with Jangaroo.<br />
<div id="__ss_5859158" style="width: 425px;"><object height="355" id="__sse5859158" width="425"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jangaroo-flash-coders-ny-101122051710-phpapp01&stripped_title=jangaroo-flashcodersny&userName=FrankWienberg" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5859158" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jangaroo-flash-coders-ny-101122051710-phpapp01&stripped_title=jangaroo-flashcodersny&userName=FrankWienberg" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>After showing some <a href="http://www.slideshare.net/FrankWienberg/jangaroo-flashcodersny">general slides about Jangaroo</a>, we went right into coding with the brand new Jangaroo version 0.7.12. Using IntelliJ IDEA 9 as the cockpit for development, we showed how to import and build a Jangaroo Maven project. Examples of Jangaroo-Flash projects were the well-known <a href="https://github.com/jangaroo/Box2DFlashAS3">Box2DFlashAS3 Jangaroo port</a> and a Jangaroo version of <a href="http://wonderfl.net/c/hLab">AS3 Lemmings</a>.<br />
Most attendees liked the idea of being able to deploy Flash applications to the browser without a FlashPlayer plugin. However, they were also concerned about performance especially on mobile devices (iOS JavaScript and canvas performance currently only suffices for quite simple applications) and API completeness, correctness and compatibility. One feedback concerning missing AS3 features in Jangaroo was that against our previous assumption, some developers like and use E4X quite a lot. Also better support for annotations is important for using certain Flash/Flex libraries, e.g. FlexUnit 4.<br />
<br />
To run Flash code directly in the browser, Jangaroo not only has to compile ActionScript 3 to JavaScript, but also all Flash APIs have to be re-implemented. While the documentation is under a Creative Commons license and can be reused, the implementation is not open. One central feature of Flash are the graphics, which can be emulated in the browser by using HTML5's canvas. Our library "jooflash" does exactly that. This is a big effort.We challanged all FlashCodersNY and of course any other Flash coder enthusiastic about Open Source to contribute to the jooflash library. <a href="https://github.com/CoreMedia/jangaroo-libs/tree/master/jooflash/">jooflash is available on github</a>, so please go ahead, fork, code, and do a pull request!<br />
In the session, there were many in-depth questions about how to debug Jangaroo code, how to use other IDEs, and many more, which indicated great interest in the technology.<br />
For example, one very interesting new topic was whether multiple embedded Jangaroo "Flash objects" on the same page are possible and how they behave. The answer is yes, you can run many Jangaroo applications on the same page. Usually, all code is loaded directly into the page, leading to shared classes, but also to shared static variables. If this is not what you want, simply load each application in an <span style="font-family: "Courier New",Courier,monospace;">iframe</span>. A more elegant solution that shares code, but not state, would require changes in the Jangaroo Runtime.<br />
<br />
Although only virtually present, we felt really welcome and were quite amused when we were asked the final question: "When was the last time you stayed up until 3 o'clock in the morning?"<br />
Thanks FlashCodersNY, it was worth it!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com2tag:blogger.com,1999:blog-5783184094166463434.post-8139702532340425312010-11-22T13:09:00.002+01:002013-10-24T08:50:03.220+02:00Jangaroo 0.7.12: More AS3 Features, even for IE9<h4>
What's new in Jangaroo 0.7.12?</h4>
We are proud to present our latest Jangaroo release with many improvements and new features in several different areas.<br />
Our last blog post is a while ago, but in the meantime, we delivered several intermediate releases and used light-weight Twitter announces (just follow <a href="http://twitter.com/Jangaroo">@Jangaroo</a>).<br />
<h4>
General</h4>
<ul>
<li><b>github</b><br />
Jangaroo is on github now!<br />
Check out Jangaroo Tools (compiler, Maven plugins, IDEA plugin) from <a href="https://github.com/CoreMedia/jangaroo-tools">https://github.com/CoreMedia/jangaroo-tools</a>.<br />
Find Jangaroo JavaScript wrapper APIs (browser API, Ext JS, CKEditor, soundmanager 2) and libraries (URI utils, JooUnit, JooFlash) at <a href="https://github.com/CoreMedia/jangaroo-libs.">https://github.com/CoreMedia/jangaroo-libs</a>.<br />
</li>
<li><b>Maven Central</b><br />
Since version 0.7.9 you can use Jangaroo from Maven without specifying any <code><repository></code> or <code><pluginRepository></code> now, so the POMs get even simpler. This is possible because all new Jangaroo Maven artifacts are deployed to Maven Central. Sonatype kindly offers this service to all Open Source projects. The old Jangaroo Maven repository still exists to host the old versions.<br />
</li>
<li><b>Compiler and Runtime Version in Generated Code</b><br />
The compiler now adds version information, so that the Jangaroo Runtime can check compatibility of generated JavaScript code. A class runtimeApiVersion/compilerVersion is compatible with the current Runtime if<br />
<br />
<ul>
<li>the runtimeApiVersion matches the Runtime's runtimeApiVersion exactly and</li>
<li>the compilerVersion is lower or the same as the Runtime's compilerVersion.</li>
</ul>
The idea is that runtimeApiVersion is only incremented when the contract between compiler and runtime changes. Thus, you may use library code compiled with an older compiler together with a runtime plus your code compiled with a later compiler. This may be important if you want to use a library and a new compiler feature, but the library is not yet available compiled with the latest compiler version. As long as we release all Jangaroo libraries ourselves, this may be academic, but this situation is bound to change sooner or later.<br />
</li>
<li><b>Cyclic Static Dependency Detection</b><br />
The Runtime now logs a warning if a cyclic static initializer dependency is detected. This happens if one class triggers initializing another class and the other class directly or indirectly triggers initializing the first class, which is already in progress. This situation does not have to cause problems, but the first class is already used while it is not yet fully initialized, so e.g. members might still be "undefined". Clean code should not contain such initialization cycles.</li>
<li><b>IntelliJ IDEA 9 Plugin</b><br />
As always, the <a href="http://plugins.intellij.net/plugin/?idea&id=4281">Jangaroo Language IDEA plugin</a> has been updated to use the latest compiler. In IDEA, simply go to Settings | Plugins | Available, search for Jangaroo Language, and click the "Download & Install" or "Update Plugin" button. After restarting IDEA, you can import Jangaroo Maven projects and enjoy code completion, fast compile-and-deploy turn-around ("Make Project"), and instant static type checking.</li>
</ul>
<h4>
Newly Supported AS3 Features</h4>
<br />
<ul>
<li><b>Full <code>trace()</code> Compatibility and More</b><br />
In previous Jangaroo versions, <code>trace()</code> only took a single parameter to print to the JavaScript console. However, in AS3, trace takes arbitrary parameters and joins them to a string (using space as separator). We now implement exactly this method signature and semantics.<br />
To also take advantage of Firebug's different console log levels, indicated through icons, without changing the method signature, we use the following convention: If you start your trace output with one of <code>[LOG]</code>, <code>[INFO]</code>, <code>[WARN]</code> or <code>[ERROR]</code>, the corresponding Firebug console method (<code>log()</code>, <code>info()</code>, <code>warn()</code> or <code>error()</code>) is invoked with the remainder of the message. For other environments, the string is printed as-is.<br />
</li>
<li><b>Variable Default Values</b><br />
Depending on their type, class variables (fields) are initialized to standard values as defined in the <a href="http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f9d.html">AS3 language specification</a> (see bottom of page). Note that this feature is only implemented for class variables, including statics, but not yet for local variables.<br />
</li>
<li><b>Helper Classes</b><br />
Out-of-package helper classes, i.e. non-public class definitions contained in the source file of a public class, are now fully supported. Unfortunately, I could not find any official Adobe reference documentation on helper classes, so please refer e.g. to this <a href="http://www.rubenswieringa.com/blog/class-syntax-in-actionscript30">blog post on helper classes </a>. <br />
</li>
<li><b>Annotations</b><br />
Basic support for annotations, i.e. meta data in square brackets added to classes or methods, has been added to the Jangaroo compiler and runtime. Since we do not yet fully implement <code>flash.utils.describeType()</code>, the only way to query meta data at runtime is through a Jangaroo-specific API which is subject to change. If you want to give it a try, find the meta data for a class using the following code:<br />
<pre>var metadata:Object =
joo.SystemClassDeclaration(SomeClass['$class']).metadata;
</pre>
To retrieve the metadata of a public class member, use the following pattern:<br />
<pre>var memberMetadata:Object =
joo.SystemClassDeclaration(SomeClass['$class'])
.getMemberDeclaration("public", "someMember").metadata;
</pre>
In both cases, the according annotation is transformed to an Object straight-forwardly, e.g.<br />
<pre>[SWF(width=465, height=465,
backgroundColor=0, frameRate=15)]
</pre>
results in the metadata object<br />
<pre>{SWF:{width:465, height:465,
backgroundColor:0, frameRate:15}}
</pre>
</li>
<li><b><code>as</code> Operator</b><br />
Jangaroo has been supporting <code>as</code> for quite some time, but so far, it was not transformed into any code (only comments in debug mode).<br />
Now, <code>as</code> is implemented with its original AS3 semantics, i.e. checking the object's type and evaluating to <code>null</code> if there is no match. Be aware that this changes semantics of your code, for example if you used <code>as</code> to cast to a type to call some method, which might have worked at runtime without the object actually being an instance of the type. In such cases, you can fall back to the type cast syntax (Type(expr)), which still generates comments only. Be warned that this code might someday throw a <code>TypeError</code> when using a later Jangaroo release.<br />
</li>
</ul>
<br />
<h4>
Browser Compatibility</h4>
<br />
<ul>
<li><b><code>trace()</code> in IE</b><br />
<code>trace()</code> now also works with Internet Explorer's console. It already worked before with Firefox with Firebug, WebKit, Opera, and any browser using Firebug light.<br />
</li>
<li><b>Property Accessor Functions in IE9</b><br />
So far, Jangaroo supported AS3 properties (<code>function get</code>/<code>set</code>) in WebKit, Firefox and Opera, but not in any version of Internet Explorer. IE9 is the first to implement custom properties accessor functions for any JavaScript object. IE8 already introduced the <a href="http://ejohn.org/blog/ecmascript-5-objects-and-properties/">ECMAScript 5 methods to define properties</a>, but they were only implemented for DOM objects. Thus, Jangaroo only supports property accessor functions in IE9.<br />
To simulate this feature also in older IE versions is a much harder task, but still we might tackle it later (see <a href="http://groups.google.com/group/jangaroo-users/browse_thread/thread/39afd2e109f92bb9">discussion on Jangaroo User Group</a>).<br />
</li>
<li><b>Workaround for IE9 Crash</b><br />
Jangaroo stores class meta data under the expando property <code>$class</code> of the class's constructor function. Even for built-in classes, when used from Jangaroo code, the Runtime attaches this property. So far, this approach worked well with IE, but IE9 beta crashed (!) when trying to run our Box2D demo.<br />
After intensive debugging, I figured out that IE9 does not like the <code>$class</code> property of built-in class <code>TypeError</code> being accessed. With some more digging into, the real source revealed itself: If in IE9 document mode, you set any expando property on the built-in <code>Error</code> class and query it through a subclass (like <code>TypeError</code>), IE9 beta crashes. Comprising only 21 characters, this might actually be the shortest JavaScript "code of death" for IE9:<br />
<pre>Error.x=1;TypeError.x
</pre>
The workaround for Jangaroo is not to set <code>$class</code> on the <code>Error</code> class, but Microsoft will have to fix this bug anyway, or there will be lots of Websites with links that say: "To crash IE9, please click here."<br />
</li>
<li><b><code>@</code>-Properties in IE</b><br />
Respect that IE does not like properties starting with <code>@</code>, and quote them.<br />
</li>
</ul>
<h4>
Bug Fixes, Improvements and API Changes</h4>
<ul>
<li>fixed a minor bug in regular expressions syntax and improved parser error messages</li>
<li>improved class initialization, which was sometimes triggered eagerly when not necessary</li>
<li>cleaned up Runtime logging in debug mode: log class initialization instead of class loading</li>
<li>Introduced <code>joo.boundMethod()</code> in favor of <code>Function.prototype.bind()</code>. See its ASDoc for details.</li>
<li>overhauled <code>joo.ResourceBundleAwareClassLoader</code> API. See its ASDoc for details.</li>
</ul>
<h4>
Jangaroo Libraries</h4>
Together with a new release of the Jangaroo tools, we always release all Jangaroo libraries, too. Besides being recompiled with the latest compiler version, there are also many updates and new features.<br />
<ul>
<li><b>Flash Compatibility <code>jooflash</code></b><br />
This library re-implements the Flash APIs in the browser, using HTML5 features like canvas. It is still rather incomplete, but nevertheless suffices for demos like <a href="https://github.com/fwienber/flash-lines">flash-lines</a> as well as quite complex applications like <a href="https://github.com/jangaroo/Box2DFlashAS3/wiki">Box2DFlashAS3</a>.<br />
</li>
<li><b>Network Utilities <code>jangaroo-net</code></b><br />
This new module contains utilities for URI parsing, formatting, relativizing and resolving functionality according to <a href="http://tools.ietf.org/html/rfc3986.html">RFC 3986</a>.<br />
</li>
<li><b>Ext JS ActionScript API <code>ext-as</code></b><br />
The library Ext AS is an ActionScript 3 wrapper for <a href="http://www.sencha.com/products/js/">Ext JS</a> 3.2.2, so you can do Ext coding with code completion and type checks while keeping a fast turn-around.</li>
<li>Many more libraries, which we will cover in a future blog post. </li>
</ul>
<br />
As always, comments, questions, corrections, praise etc. are highly welcome! Why not contribute by issuing pull requests on github to include your bug fixes?<br />
<br />
<i>Andreas and Frank</i>Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-44224121942359597532010-08-09T22:13:00.004+02:002010-08-10T11:12:23.912+02:00Jangaroo 0.7.0 ReleasedIn the latest release, Jangaroo features Runtime optimizations, localization, and semicolon insertion.<br />
<h4>Jangaroo Runtime without <span style="font-family: "Courier New",Courier,monospace;">with</span></h4>After concentrating on compiler and build process in release 0.6, the new release 0.7 cleans up the Jangaroo Runtime accordingly.<br />
Many features that used to be implemented in the Runtime became obsolete, because the compiler now takes care of them:<br />
<ul><li>The mapping of <i>private member names</i> now consists of a set of local variable assignments, generated by the compiler. The runtime merely still contributes the class inheritance level, which can only be computed at runtime if we want to keep "binary" update compatibility with libraries. This removed the last <span style="font-family: "Courier New",Courier,monospace;">with</span>-statement from the generated code! Since <span style="font-family: "Courier New",Courier,monospace;">with</span> is <a href="http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/">considered harmful</a>, we are proud to now avoid it completely. This results in less ambigous code ("where the heck does that <span style="font-family: "Courier New",Courier,monospace;">$foobar </span>variable come from?") and most likely in better performance, since modern JavaScript engines with their just-in-time compilers have better chances to perform optimizations without <span style="font-family: "Courier New",Courier,monospace;">with</span>.</li>
<li><i>Resolving unqualified identifiers</i> (usually class names without package) is no longer done at runtime, but completely at compile time. Even implicit imports, i.e. usages of classes of the same package or the top level package, are detected and made explicit by the compiler. Thus, the runtime no longer has to deal with imports. It still needs to know which other classes to load (i.e. its dependencies). We may re-introduce more concise code for imported classes later.</li>
</ul><h4>New Feature: Localization Support</h4>Localization means to provide your software with different texts and configuration, depending on the user's locale settings. For Jangaroo, this means that there should be some standard way to access the current user's locale and that the runtime should be able to load differnet resources depending on that user locale. Since the Runtime can already <a href="http://www.jangaroo.net/documentation/runtime/automatic_class_loading.html">load classes automatically</a>, representing resource bundles as classes suggests itself. To help you creating such classes, there is a new tool, the <i>Properties Compiler</i>. Actually, it has been included with the Jangaroo tools for quite some time as a hidden feature. But after we have revamped it with the 0.7 release, we're glad no-one (but ourselves) has used it yet ;-). The properties compiler takes a set of properties files for different locales, in Java often called a resource bundle, and generates an ActionScript class for each locale, and one for the defaults. We will add an example to the Jangaroo website soon, also explaining how to let a user choose her locale.<br />
<br />
<h4>Automatic Semicolon Insertion</h4>The Jangaroo compiler jooc is now capable of inserting semicolons according to the <a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf%20">ECMA-262 specification</a> (of which ActionScript 3 is an implementation). For compiler writers: this is done by exploting the error recovery mechanism of the CUP LALR(1) parser generator.<br />
We implemented this feature not beause we like it so much, but to increase our ActionScript 3 compatibility, esp. for the purpose of porting 'legacy' code. For example, we needed to patch the FlexUnit library at many places just because some semicolon was missing. These patches are now no longer necessary.<br />
When writing new code, you should <i>not</i> use the optional-semicolon feature of ActionScript 3, as recommended by Adobe in the <a href="http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions#CodingConventions-Statements">Flex SDK coding conventions and best practices</a>.<br />
Semicolon Insertion is considered one of the bad parts of JavaScript, and ActionScript 3 inherited them: a line terminator might trigger semicolon insertion which might change the meaning of the program in unexpected ways. Because of these bad vibes, we added a compiler switch which configures the behaviour of jooc with regard to semicolon insertion. The syntax is <span style="font-family: "Courier New",Courier,monospace;">-autosemicolon </span><i>mode</i>, and possible modes are:<br />
<ul><li><span style="font-family: "Courier New",Courier,monospace;">warn</span> (which is the default) will issue a compiler warning if a line terminator is the cause for semicolon insertion</li>
<li><span style="font-family: "Courier New",Courier,monospace;">error</span> will treat this as an error (some kind of strict mode, recommended setting).<span style="font-family: "Courier New",Courier,monospace;"> </span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">quirks</span> silently inserts all these semicolons as JavaScript interpreters and Flex compc do (good luck with this setting!)</li>
</ul>Note that the ECMA-262 rule which inserts a missing semicolon right before a closing brace ('<span style="font-family: "Courier New",Courier,monospace;">}</span>') is unaffected by this switch. This rule basically states that a semicolon is optional at the end of a block, which we consider a favourable thing.<br />
One last tip: IntelliJ IDEA offers a code style setting for ActionScript to highlight unterminated statements. Just open <i>Settings - Project Settings - Code Style - JavasScript/ECMAScript/ActionScript</i> and place a checkmark at <i>Use semicolons to terminate statements.</i><br />
<br />
<i>Frank and Andreas</i><br />
<br />
P.S.: As always, we updated the Jangaroo IDEA plugins <i>Jangaroo Language</i> and <i>Jangaroo EXML</i> (containing the properties compiler) to the new version.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-16124520550296996702010-07-16T18:27:00.006+02:002010-07-16T18:44:27.538+02:00Jangaroo 0.6.0 released: No More GuessingThis brand new Jangaroo version comes with several improvements which further enhance our ActionScript 3 compatibility.<br /><br />Up until now, the Jangaroo compiler <span style="font-family:courier new;">jooc </span>processed one source file at a time, without taking a look at declarations residing in other source files. However, in certain situations, <span style="font-family:courier new;">jooc </span>needs to decide whether a given symbol denotes a class, a package-global function, and whether it is static or a non-static member. This information is important because <span style="font-family:courier new;">jooc </span>has to generate different JavaScript code in each case.<br /><br /><span style="font-family:courier new;">jooc </span>based some of these decisions upon heuristics and generated a warning if he wasn't sure (e.g. the warning <span style="font-family:arial;">"undeclared identifier foo, assuming it is an inherited member"</span>), just to tell you about it, giving a chance to review the decision. However, this typically generated a lot of warnings, and nobody actually cared about them any more (broken window effect).<br /><br />We now took off the blinders and enabled <span style="font-family:courier new;">jooc </span>to look into sources other than the single one at hand. This allows the compiler to do his job based on facts, not on assumptions.<br /><br />On the other hand, now <span style="font-family: courier new;">jooc </span>needs to find the definitions of all external symbols which are used within a given source file. We added two new compiler switches which tell <span style="font-family:courier new;">jooc </span>where to look for these:<br /><ul><li><span style="font-family:courier new;">-sourcepath:</span> a list of source root directories in the same module (e.g. <span style="font-family:courier new;">"src/main/joo;target/main/generated-sources/joo;src/test/joo"</span>), and</li><li><span style="font-family:courier new;">-classpath</span>: a list of directories or Jangaroo module jars where to find symbols in module dependencies.</li></ul>Furthermore, we added another compiler switch <span style="font-family: courier new;">-api</span> which tells jooc to generate so called API stubs for your ActionScript sources. These stubs contain just the API part of your code. That is, any private members are left out, and all methods are declared native, leaving out the method body. Any API documentation comments before the remaining declarations are retained. These API stubs are looking quite similar to the ActionScript files we are using as the API declaration for native JavaScript libraries (e.g. Ext JS).<br /><br />If you are using Maven to build your Jangaroo application (as we do), you are lucky: the new version of the Jangaroo Maven Plugin configures all these new compiler switches with reasonable defaults. Your Jangaroo project should build right out of the box with the new Jangaroo version. The new Jangaroo Maven plugin automatically generates and packages API stubs for every Jangaroo module into the <span style="font-family:courier new;">META-INF/joo-api</span> directory within the module jar file.<br /><br />We also updated the Jangaroo IDEA plugin to take advantage of the new compiler switches. The Plugin is now compatible with IDEA 9.0.2. By the way, a neat side effect of the new API stub packaging is that you may now both get a 'green square' for sources within the IDEA editor <span style="font-style: italic;">and</span> access the API documentation with <span style="font-style: italic;">Quick Documentation Lookup</span> (<span style="font-family:courier new;">CTRL-Q</span>) <span style="font-style: italic;">without </span>having to download the source artifacts of dependencies.<br /><br />Last but not least, here are some additional enhancements which come with the new Jangaroo version:<br /><ul><li>Static superclass members are now in scope which means that you do not need to qualify the member with the superclass identifier any more.</li><li>Private members of the same class are now also accessible for parameters and variables. Previously, private members where only accessible if (implicitly or explicitly) qualified by <span style="font-family:courier new;">this</span>.</li><li>Old-style type casts are now recognized correctly and commented out in the generated JavaScript code, just like the new-style type casts using the as keyword. Note that we still do not generate any runtime code for both kinds of type cast.</li><li>The restrictions of dynamic class loading are removed, you may now use <span style="font-family:courier new;">*</span>-imports and put classes under other source root directories, given you configured the <span style="font-family:courier new;">-sourcepath</span> option accordingly.<br /></li></ul>Not to mention many internal compiler re-factorings which simplified the code base, much better test coverage and lots of bug fixes.<br /><br />As always, we’d be glad about feedback and hope you have fun developing with Jangaroo!Andreashttp://www.blogger.com/profile/00617027750473728423noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-40636633181515795792010-02-10T09:41:00.009+01:002010-11-02T11:17:47.804+01:00Jangaroo on The Flex Show<i><b>Edit: </b>On 08/13/2010, I corrected some outdated information using <strike>strike-through</strike> and italics.</i><br />
A couple of days ago, Jeffry Houser and John Wilker of <a href="http://www.theflexshow.com/">The Flex Show</a> gave me the chance to talk about Jangaroo. Thank you again! Today,<a href="http://www.theflexshow.com/blog/index.cfm/2010/2/10/The-Flex-Show-Episode-97--Frank-Wienberg-talks-Jangaroo"> the episode has been published</a>, so I'll repeat some of the things mentioned in the interview here and provide some updated information you may need to get started with Jangaroo.<br />
John and Jeffry asked for the <span style="font-style: italic;">differences between AS3 and Jangaroo</span>, which are documented <a href="http://www.jangaroo.net/documentation/language/1484/nativeas.html">here</a>.<br />
You can find the Flash / Jangaroo <span style="font-style: italic;">demo</span> mentioned in the interview <a href="http://www.jangaroo.net/files/examples/flash/lines/">here</a>. It is an example of how to use Jangaroo to run a Flash demo without a Flash plugin. The AS3 source code, borrowed from <a href="http://lab.andre-michelle.com/">Andre Michelle</a>, is compiled to JavaScript with the Jangaroo compiler, using the Jangaroo Flash Library (which is still quite incomplete, but suffices for this demo). With only a few lines of JavaScript, that code is loaded and run in any browser supporting the HTML5 canvas element (i.e. not IE). If you are connected to the Internet and your browser has a Flash plugin, you can also see the original demo running in a Flash player at the right side. Don't they look like twins?<br />
<br />
My personal project, the game "Jangaron", completely developed using Jangaroo, is located at <a href="http://www.jangaron.net/">http://www.jangaron.net</a>.<br />
<br />
In the interview, I mention the Maven build process. <strike>Since the information on our Web page is not really up-to-date (shame on me), </strike>I'll step you through getting started with the demo / example I mentioned.<br />
<ol><li>Download and install <a href="http://maven.apache.org/download.html">Maven 2.2.1</a>.</li>
<li>Download and unpack the <a href="http://www.jangaroo.net/files/examples/flash/lines/jangaroo-example-flash-lines-src.zip">demo source code</a>.</li>
<li>Point a command line to the directory where you unpacked the demo source code and run<br />
<span style="font-family: courier new;">mvn package<br />
</span>If this is your first Maven build, you have to be online and it may take a while.</li>
<li>When the build process has finished successfully, a full Web application has been created under <span style="font-family: courier new;">target/flash-lines-0.1.1</span><span style="font-family: courier new;">-SNAPSHOT</span>. Simply open the following file in any browser <span style="font-style: italic;">but </span>IE (alas: no canvas!):<br />
<span style="font-family: courier new;">target/flash-lines-0.1.1-SNAPSHOT/index.html</span></li>
</ol>If you want to play around with the demo<span style="font-style: italic;">,</span> I recommend using <a href="http://www.jetbrains.com/idea/download/index.html">IntelliJ IDEA <strike>8.1.4</strike> <i>9.0.x Ultimate</i></a> (<i>where x > 1 for the Jangaroo plugin to work!</i>). They offer a 30 day trial, and if you want to use IDEA to contribute to the Jangaroo project, there also is a free Open Source license which can be obtained by <a href="http://www.jangaroo.net/contact/">applying via mail</a>.<br />
<strike>Note that the Jangaroo plugin is currently <span style="font-weight: bold;">not compatible with IDEA 9</span> -- the update is in progress, stay tuned!</strike><br />
If you'd rather use a free, Open Source IDE, since there is no free AS3 support for Eclipse yet, I recommend <a href="http://www.flashdevelop.org/wikidocs/index.php?title=Main_Page">Flash Develop</a>. I'm not an expert for FD, but I managed to edit Jangaroo source code with FD, and it felt quite nice. I'm sure the FD guys will help you getting started!<br />
<br />
Getting started with IDEA <strike>8</strike> <i>9</i> and Jangaroo is really simple and consists of the following steps:<br />
<ol><li>Install the Jangaroo Language Plugin (see below).<br />
</li>
<li>Import the demo Maven project (see below). Only do this <span style="font-style: italic;">after</span> installing the plugin, as it also plugs into IDEA's Maven import process!</li>
</ol>In detail, installing the Jangaroo Language Plugin:<br />
<ol><li>Open "Settings", "Plugins".</li>
<li>Select the "Available" tab.</li>
<li>Find the "Jangaroo Language" plugin. As of today, latest version is <strike>0.3.22</strike> <i>9.0.7.0.0</i>.</li>
<li>Right-click, "Download and Install".</li>
<li>IDEA asks you to let it restart. Do so.</li>
</ol>Importing the demo Maven project: <br />
<ol><li>Create a new project (from the start screen or "File", "New Project").</li>
<li>Select "Import from external model", "Next".</li>
<li>Select "Maven", "Next".</li>
<li>Select the root directory of the downloaded demo sources (the one that contains the pom.xml), "Next".</li>
<li>The only Maven project found is preselected. "Next".</li>
<li>Confirm name and project with "Finish".</li>
<li>After the import is finished, in the "Maven Projects" window, click "Download artifacts" (the third button in "Maven Project" window's top toolbar). After that, the AS3 code should be "green" (or "yellow", but not "red").</li>
</ol>You have to build the Web application once using Maven as described above or from inside IDEA as follows. In the "Maven Projects" window, you open the root node of the tree, then "Lifecycle". Find "package" and start (click green arrow, you can also double-click "package" right away).<br />
After that, you can use IDEA's make process to a) get a quicker turn-around and b) jump to error locations directly with a double-click. Use "Make Project" (Ctrl-F9) to build incrementally, which is <span style="font-style: italic;">way</span> faster than a Maven build and provides better compiler error messages. After building, simply reload the page in your browser. You may need to reload without cache (Ctrl-R) or even clear the browser cache for changes to take effect. For Firefox, there is a nice plugin for that called "Clear Cache Button".<br />
<br />
Now, you can develop a JavaScript based Web application with a level of convenience never achieved before. The key to that is that ActionScript, as a typed language, gives the IDE far more options to offer correct completions and refactorings than JavaScript. Go ahead a try IDEA's completion (Ctrl-space), quick documentation lookup (Ctrl-Q), parameter info (Ctrl-P), or goto declaration (Ctrl-B). Try rename refactoring or "introduce variable". Granted, not all refactorings known from Java are yet available, but Jetbrains are continuously improving AS3 support. Enjoy!<br />
<br />
If you have any problems or questions, feel free to <span style="font-weight: bold;">comment</span> here, post in the <a href="http://groups.google.com/group/jangaroo-dev/">Jangaroo developer group</a>, or <a href="http://www.jangaroo.net/contact/">contact us directly</a>.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com2tag:blogger.com,1999:blog-5783184094166463434.post-19194279233635093942009-08-01T13:49:00.016+02:002009-08-02T16:22:16.447+02:00Jangaroo 0.3.1: Less Imports, More RhinoWe just released version 0.3.1 with some nice updates:<br /><span style="font-size:130%;"><br /><span style="font-weight: bold;">No more same-package imports</span></span><br />With Jangaroo 0.3.1, you no longer need to import classes of the same package to enable <a href="http://www.jangaroo.net/documentation/runtime/automatic_class_loading.html">automatic class loading</a>. The compiler now scans the directory of the current source file for all <span style="font-family:courier new;">*.as</span> files, so that it knows about all declarations in the same package. The <a href="http://www.jangaroo.net/documentation/language/limitations.html">limitation</a> that you have to import <span style="font-style: italic;">top-level</span> Jangaroo classes for automatic class loading to work remains---hopefully only until the next release! For more info about Jangaroo and top-level classes, read on below.<br /><span style="font-size:130%;"><br /><span style="font-weight: bold;">Oh, behave, Rhino!</span></span><br />Jangaroo works in many environments: in most browsers, and also in <a href="http://www.mozilla.org/rhino/">Rhino</a>. For example, to run automated Jangaroo unit tests, the easiest way is to start a cross-platform, stand-alone JavaScript engine like Rhino.<br />While in principle, the Jangaroo runtime worked inside Rhino, some classes were not loaded and there were strange error messages. After some investigation, we found out that Rhino behaves badly in polluting the global namespace with <span style="font-family:courier new;">[JavaPackage]</span> objects for all imported top-level Java package name prefixes<span style="font-family:courier new;"></span>. You cannot get rid of some Java packages imported by default, among which are <span style="font-family:courier new;">com</span> and <span style="font-family:courier new;">net</span>, and even more badly, any property of Rhino's <span style="font-family:courier new;">[JavaPackage]</span> objects is claimed to be defined, and they are all again <span style="font-family:courier new;">[JavaPackage]</span>. For example, if Rhino knows of a Java class in <span style="font-family:courier new;">com.mydomain</span>, the JavaScript expression <span style="font-family:courier new;">com.foobar</span> also returns a <span style="font-family:courier new;">[Java package]</span> object, even if there is no such package!<br />This odd behavior made the Jangaroo runtime think that any Jangaroo class in a package starting with <span style="font-family:courier new;">com</span> or <span style="font-family:courier new;">net</span> is already defined. It seems Rhino cannot be configured to behave less obtrusive, so we had to find a workaround in the Jangaroo runtime. The solution was to treat any JavaScript object whose string representation contains "<span style="font-family:courier new;">[JavaPackage</span>" as non-existent and overwrite it with a clean Jangaroo package object. If you still need to access the overwritten Java packages, Rhino also places them under the top-level object <span style="font-family:courier new;">Packages</span>, so simply use <span style="font-family:courier new;">Packages.com.mydomain</span>.<br /><br /><span style="font-weight: bold;font-size:130%;" >Alias for top-level package</span><br />The updated Jangaroo runtime defines the alias <span style="font-family:courier new;">js</span> for the top-level package. Why?<br />ActionScript seems to have a problem with top-level classes. Say you have a top-level class <span style="font-family:courier new;">Node</span>, and some framework defines a class <span style="font-family:courier new;">org.w3c.dom.Node</span>. In your client code, you need to use both classes, so you have to <span style="font-family:courier new;">import org.w3c.dom.Node</span> (the top-level class is in scope by default). With <span style="font-family:courier new;">asdoc</span> (which is based on the Flex ActionScript compiler), this situation leads to the error that <span style="font-family:courier new;">Node</span> is not defined (I also tried importing the top-level <span style="font-family:courier new;">Node</span> explicitly). Whether this is a compiler bug or a conceptual problem in ActionScript, I don't really care, since we cannot wait for <span style="font-family:courier new;">asdoc</span> to be fixed. My theory is that the import mapping is removed as a result of the name clash, as there is a rule that two imports with the same local name cancel each other out, which means that both classes have to be used with their fully qualified names. But what is the fully qualified name of a top-level class?!<br />We ran into this situation when trying to provide built-in browser APIs as ActionScript 3 classes and interfaces. Most JavaScript frameworks define wrapper classes for top-level types and put them into their own package (e.g. Ext.Element). So our solution now is to declare the API for a top-level JavaScript type in the package <span style="font-family:courier new;">js</span>, which at runtime is the same as the top-level package. Then, to come back to my example, you can use both<span style="font-family:courier new;"> js.Node</span> and <span style="font-family:courier new;">org.w3c.dom.Node</span> in the same class. You can find an alpha of the Jangaroo library defining most built-in browser APIs as ActionScript classes and interfaces under the name <a href="http://repo.jangaroo.net/maven2-snapshots/net/jangaroo/js2native/0.1-SNAPSHOT/js2native-0.1-20090730.084747-11-sources.jar">"js2native" in the Jangaroo Maven snapshot repository</a>.Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-36799515537224350792009-07-01T21:42:00.009+02:002009-07-01T22:52:34.022+02:00Jangaroo 0.3: Amplified ActionScript 3 CompatibilityIt's been quite a while, but eventually, I am proud to announce <a href="http://www.jangaroo.net/download/">Jangaroo 0.3</a>, featuring highly improved ActionScript 3 compatibility and better build and deployment support:<br /><ul><li>interfaces, <span style="font-family: courier new;">is</span></li><li>type casts (<span style="font-family: courier new;">as</span> and support for the legacy syntax)<br /></li><li>bound methods (get <span style="font-family: courier new;">this</span> right!)</li><li>no more need to always use <span style="font-family: courier new;">this.x</span> instead of <span style="font-family: courier new;">x</span></li><li><span style="font-family: courier new;">*</span>-imports</li><li>fully AS3 compatible Array class</li><li><span style="font-family: courier new;">include</span> directive<br /></li><li>annotations (syntax only)<br /></li><li>getter and setter methods (unfortunately not in IE)<br /></li><li>automatic loading of dependent classes<br /></li><li>Maven plugin provides Jangaroo with a flexible and powerful build system<br /></li></ul>Actually, many of these features were already introduced with the 0.2.x versions, but these were only released in the <a href="http://repo.jangaroo.net/">Jangaroo Maven repository</a>. Now, the main effort was to round things off and update all documentation, so please go ahead and re-visit the <a href="http://www.jangaroo.net">Jangaroo Web site</a> to find an updated story ("JavaScript 2 is dead, long live ActionScript 3!") and many new <a href="http://www.jangaroo.net/documentation">technical details</a>.<br /><span style="font-size:130%;">Jangaroo Tool Support</span><br />Jangaroo has always used a subset of AS3, so that all AS3 tools like asdoc and IDEs can be used with Jangaroo code. As <a href="/2008/12/idea-8-supports-actionscript-3-and.html">mentioned before</a>, IntelliJ IDEA 8 supports ActionScript 3 and thus Jangaroo very well. To top that, we have implemented a Jangaroo IDEA plugin that will be released in the near future.<br /><span style="font-size:130%;">Porting AS3 Libraries to Jangaroo<br /></span>Now that we have added all these nice AS3 language features, it is possible to translate most existing AS3 code with the Jangaroo compiler and run it in the browser (without any Flash plug-in!).<br />For example, we work on a port of <a href="http://opensource.adobe.com/wiki/display/flexunit/">FlexUnit</a> and, with very few code changes, can already run its self-test-suite successfully in the browser. Our FlexUnit variant (of course called JooUnit!) will be released shortly, and some of the changes (missing semicolons, mixed DOS/UNIX line end encodings, asdoc glitches) will be submitted back to FlexUnit's main branch.<br />Of course, making the browser understand AS3 natively is only half the truth: Most AS3 code relies on standard libraries, namely Adobe's Flash API. Thus, another running project is to re-implement the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/">Adobe Flash 9 API</a> in Jangaroo as an adapter to native browser APIs (including canvas for drawing), so that most Flash code and even programs that draw and animate can be run, and as always when using Jangaroo: without a Flash plugin, thus seamlessly embedded into any HTML page!<br />Based on the Flash API, we recently also managed to <span style="font-style: italic;">compile</span> the whole open source <a href="http://livedocs.adobe.com/flex/3/langref/">Flex 3.3 framework</a> after some Jangaroo-friendly changes, but it is still quite some way to go until it would actually <span style="font-style: italic;">work</span>, so we hope to get you ActionScript whiz people to contribute soon...<br />Have fun with a new way of experiencing JavaScript and ActionScript 3! We can't wait for your feedback!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-39693377747664993462009-01-22T14:18:00.004+01:002009-01-22T14:40:27.335+01:00Jangaroo Discussion Groups StartedLatest news: We have started two discussion groups for Jangaroo, one for developers and one for "users", i.e. appliers of Jangaroo language and tools:<br /><a href="http://groups.google.com/group/jangaroo-dev">http://groups.google.com/group/<b>jangaroo-dev</b></a><br /><a href="http://groups.google.com/group/jangaroo-users">http://groups.google.com/group/<b>jangaroo-users</b></a><br />We felt that commenting in this blog and e-mailing does not really compensate for real discussion groups. The idea of two groups was that tool developer discussions could be quite boring for people who just want to use the tools and see new features. Discussions about new features should be started in the users group, and if the feature is supported by the user community, developers could take over and discuss how to implement the feature.<br />To get started, I reposted some e-mail discussions in the users group. Please go ahead and read what's there, and feel free to post your comments and opinion!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-17440485539293444562008-12-10T21:00:00.008+01:002008-12-10T23:38:21.799+01:00IDEA 8 Supports ActionScript 3 and JetBrains Supports JangarooOne main point about Jangaroo is that it is based on a language being standardized, not inventing a new one. The main advantage is that all kinds of resources available for that language can be reused: documentation, know how, best practices, and last but not least tools.<br />As a <span style="font-style: italic;">Java</span> developer, I've been using Jetbrains' <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a> since version 5, and I really like it. As far as I can tell, it offers the best code inspections and refactorings in the Java world.<br />As a <span style="font-style: italic;">Jangaroo</span> developer, I switched to IDEA 8 when the first milestone was available, because to support Flex, IDEA's <span style="font-weight: bold;">JavaScript and ActionScript 3 capabilities were boosted</span>. This makes IDEA 8 the best Jangaroo development environment (and thus the best JavaScript IDE) available!<br />When version 8 became final, I started using an evaluation license, but became a bit nervous how I would continue after 30 days. So I applied for an Open Source license for IDEA, and voilà, after just three days, I received a free unlimited users license for Jangaroo development!<br />Thank you, Jetbrains, the Jangaroo team really appreciates your support of Open Source software! I can't wait to do a screencast on how to develop, build & debug (!) a Jangaroo application using IDEA 8!<br />To not seem too biased ;-), in the following, I'd like to give you pointers to other IDEs that can be used for Jangaroo development.<br />Of course, there is the <a href="http://www.adobe.com/products/flex/features/flex_builder/">Flex Builder</a> by Adobe. It may be the best tool to develop Flex applications, but I have to admit I never tried it for Jangaroo. As far as I know, even as an Open Source developer, after the usual trial period, you have to buy a license.<br />Like Flex Builder, <a href="http://fdt.powerflasher.com/">FDT 3</a> is Eclipse-based and has sophisticated ActionScript 3 support, but targets at Flash (not Flex) development . I tried it with a demo license, and it works really well with Jangaroo code. Although commercial, too, you can apply for an Open Source license as well, and I think I'll do that next.<br />The last candidate I had a look at is the only <span style="font-weight: bold;">free Open Source</span> ActionScript 3 IDE I could find.<a href="http://www.flashdevelop.org/wikidocs/index.php?title=Features"> FlashDevelop 3</a> (FD) is based on .net and seems to be a quite fully-featured IDE for AS2, AS3 / MXML, and HTML. Being an Open Source project, it might be the right place to add a special Jangaroo mode, although .net is not really our favorite environment (we are a Java shop...).<br />What all these tools have in common is that they support ActionScript 3, not JavaScript 2 or even ECMAScript 4, and expect ActionScript 3 class files to have the <span style="font-family:courier new;">.as</span> extension, not <span style="font-family:courier new;">.js2</span>. (IDEA seems to be the only tool that cares about JS2/ES4.) This evidence and the impression that the ECMAScript specification committee seems to deal rather with their team <a href="https://mail.mozilla.org/pipermail/es-discuss/2008-August/006837.html">harmony </a>than with solving real-world JavaScript development problems made us move Jangaroo from JS2/ES4 towards ActionScript 3 -- stay tuned for a major update!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com2tag:blogger.com,1999:blog-5783184094166463434.post-37840593521789541302008-09-09T20:13:00.003+02:002008-09-09T20:46:19.434+02:00Sneak preview of the Jangaroo Maven pluginGood news for <a href="http://maven.apache.org/">Maven2</a> users: with the introduction of the <span style="font-family:courier new;">jangaroo-maven-plugin</span>, it will soon be easier than ever to compile Jangaroo sources as part of your build process.<br /><br />The plugin is an alternative to the provided Ant task and will be part of the next Jangaroo tools release. In the meantime you can already try the 0.1.2-SNAPSHOT version from the Jangaroo snapshot repository. The following <span style="font-family:courier new;">pom.xml</span> demonstrates how to use the plugin to build the <span style="font-family:courier new;">helloWorld </span>example, which is included with the Jangaroo distribution. Simply create a file called <span style="font-family: courier new;">pom.xml</span> in the root directory of the example (the one containing the <span style="font-family: courier new;">build.xml</span> file) and paste the following to it:<br /><pre><br /><project xmlns="http://maven.apache.org/POM/4.0.0"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0<br /> http://maven.apache.org/maven-v4_0_0.xsd"><br /> <modelversion>4.0.0</modelversion><br /> <groupid>net.jangaroo.examples</groupid><br /> <artifactid>hello-world</artifactid><br /> <packaging>war</packaging><br /> <version>1.0-SNAPSHOT</version><br /> <name>hello-world-example</name><br /><br /> <pluginrepositories><br /> <pluginrepository><br /> <id>jangaroo</id><br /> <name>Jangaroo repository</name><br /> <url>http://repo.jangaroo.net/maven2</url><br /> </pluginrepository><br /> <pluginrepository><br /> <id>jangaroo-snapshots</id><br /> <name>Jangaroo repository</name><br /> <url>http://repo.jangaroo.net/maven2-snapshots</url><br /> <snapshots><br /> <enabled>true</enabled><br /> </snapshots><br /> </pluginrepository><br /> </pluginrepositories><br /><br /> <build><br /><br /> <plugins><br /> <plugin><br /> <groupid>net.jangaroo</groupid><br /> <artifactid>jangaroo-maven-plugin</artifactid><br /> <version>0.1.2-SNAPSHOT</version><br /> <executions><br /> <execution><br /> <id>compile-jangaroo-sources</id><br /> <goals><br /> <goal>compile</goal><br /> <goal>copy-runtime</goal><br /> </goals><br /> <configuration><br /> <br /> <!-- Default output directory is<br /> {project.build.directory}/${project.build.finalName}/js<br /> --> <br /> <outputdirectory><br /> ${project.build.directory}/${project.build.finalName}<br /> </outputdirectory> <br /><br /> <!-- All of the following configuration parameters are optional,<br /> the values shown are the defaults.<br /> --> <br /> <sourcedirectory><br /> ${basedir}/src/main/js2<br /> </sourcedirectory> <br /><br /> <verbose>false</verbose><br /> <debug>true</debug><br /> <debuglevel>source</debuglevel><br /> <br /> </configuration><br /> </execution><br /> </executions><br /> </plugin><br /><br /> <plugin><br /> <artifactid>maven-war-plugin</artifactid><br /> <version>2.1-alpha-2</version><br /> <configuration><br /> <failonmissingwebxml>false</failonmissingwebxml><br /> </configuration><br /> </plugin><br /><br /> </plugins><br /><br /> </build><br /></project><br /></pre><br />Two mojos are available and will usually be run together: <span style="font-family:courier new;">compile </span>and <span style="font-family:courier new;">copy-runtime</span>. The latter one extracts the Jangaroo runtime joo/Class.js to the output directory.<br /><br />To build the project, run<span style="font-family:courier new;"> mvn package</span> in the directory containing <span style="font-family:courier new;">pom.xml</span>. Obviously, a working Maven2 installation is required to do so.<br /><br />We still have some important homework to do before the plugin will be released, such as serious documentation or an option to concatenate all compiled output files into one compact JavaScript file. However, feedback to the plugin at this early stage is higly welcome. Just drop a comment below.Dennishttp://www.blogger.com/profile/09456446381126510943noreply@blogger.com1tag:blogger.com,1999:blog-5783184094166463434.post-76771733924897557242008-09-03T11:01:00.011+02:002008-09-03T15:38:45.010+02:00Jangaroo Applications Work on Google ChromeJust a few days ago, Google released the first beta of their <a href="http://www.google.com/chrome">Chrome browser</a>. Since the browser is based on <a href="http://webkit.org/">WebKit</a>, and Jangaroo has been tested on Safari, you could think Jangaroo should also work on Chrome. But WebKit is only the HTML rendering engine: Google created a completely different JavaScript engine called V8, including performance optimizations (among others, compilation to native code) and multi-tasking! So it was rather an open question whether there are any problems with Jangaroo applications or not.<div>We have good news for you: The largest Jangaroo application so far, <a href="http://www.jangaron.net/jangaron0.5/jangaron.html">Jangaron</a>, runs <span class="Apple-style-span" style="font-weight: bold;">without any problems and really fast and smoothly</span>! Congratulations, Google, you did a great job!<div><br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsd6B8j2l7G6QgFrwjNkrtoO2hRb-p78IqY6axHhWdMuudhANODtFnHS8jJ0FcB5QN_uzyYGmjQkk_Q4pBE3kdQAzC8KE55bq8aEn9GkEDS6UYCCvafgAQJiq8NIDBUZeJjeRaJ3TEXeZD/s1600-h/Jangaron-Chrome.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsd6B8j2l7G6QgFrwjNkrtoO2hRb-p78IqY6axHhWdMuudhANODtFnHS8jJ0FcB5QN_uzyYGmjQkk_Q4pBE3kdQAzC8KE55bq8aEn9GkEDS6UYCCvafgAQJiq8NIDBUZeJjeRaJ3TEXeZD/s400/Jangaron-Chrome.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5241780444563077362" /></a></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGVL579hHzsCI5TWi7NgI7XkDwxRdd_Pyl66acYBamRYBc7_OBvOlO0D5F6Cj0mjBtk3GmdQOo4adKNE8sZjdvctbSJ0GkFAS8z3mdeWj6rQ2hwpgR3bSBtUFbQs1ucIbLUjg_MIRBqVzJ/s1600-h/Jangaron-Ingame-Chrome.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGVL579hHzsCI5TWi7NgI7XkDwxRdd_Pyl66acYBamRYBc7_OBvOlO0D5F6Cj0mjBtk3GmdQOo4adKNE8sZjdvctbSJ0GkFAS8z3mdeWj6rQ2hwpgR3bSBtUFbQs1ucIbLUjg_MIRBqVzJ/s400/Jangaron-Ingame-Chrome.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5241783003772043170" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ot8w-B6nKNTDThvD2YRB3ckoWlZ-CUFOa8zJRK7REITazNi2R3EFfVNSnaIcEJbu8prGjqBLWrDWawVde-y6U1LHjTnC_R58C_4tzp65ocaD8xWxP4iqou6Pk9QAHEk4cUYcZfPnvyfF/s1600-h/Jangaron-Ingame-Chrome.PNG"></a><div>P.S.: I wrote this post using Chrome...</div>Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-730513806628767742008-08-05T17:21:00.007+02:002008-08-05T21:46:52.616+02:00Jangaroo 0.1.1 - iPhone support!One of my most important personal goals concerning <span style="font-style: italic;">Jangaroo</span> has been reached with <a href="http://www.jangaroo.net/download/index.html#download-current">brand new version 0.1.1</a>: it now runs on Safari/<span style="font-weight: bold;">iPhone</span>!<br />As a side-effect, this also makes <span style="font-style: italic;">Jangaroo</span> run on older browsers based on KHTML or WebKit (tested under Linux with Konqueror 3.4), and as an even better side effect, I was now able to get my <span style="font-style: italic;">Jangaroo</span>-based Tron Lightcycle game <a style="font-style: italic;" href="http://jangaron.blogspot.com/2008/08/jangaroo-released-and-jangaron-updated.html">Jangaron</a> running on the iPhone, too! Since the iPhone is missing the keys needed to control your Lightcycle in the game, I have set up a <a href="http://www.jangaron.net/khtml/jangaron.html">special iPhone version</a> with on-screen buttons -- feel invited to go ahead and try!<br /><br />So what was the problem with <span style="font-style: italic;">Jangaroo</span> and old KHTML / WebKit versions? There were several <span style="font-weight: bold;">bugs in the </span><span style="font-weight: bold;">KHTML / WebKit JavaScript engine </span> we had to work around:<br /><ol><li>When using <span style="font-family:courier new;">new Function()</span>, it was not possible to set the <span style="font-family:courier new;">prototype</span> property, while with <span style="font-family:courier new;">function(){}</span>, it works as expected.<br /></li><li><span style="font-family:courier new;">with()</span> seems to behave differently when <span style="font-style: italic;">setting</span> properties of the "withed" object. Avoid it to be really cross-browser compatible!</li><li><span style="font-family:courier new;">delete obj.property</span> showed strange behavior: it seems that in some cases, the property is deleted from the prototype (i.e. for all instances!) instead of from <span style="font-family:courier new;">obj</span> only. We also refrained from using it in the runtime.<br /></li><li>In order to keep compiled code as close as possible to the source code, we tried to retrieve the generated function's name at runtime. Unfortunately, in older KHTML / WebKit versions there seems no way to do so: Firefox's <span style="font-family:courier new;">Function#name</span> is not defined and <span style="font-family:courier new;">Function#toString()</span> returns the whole source code of the function <span style="font-style: italic;">save</span> its name. Thus, we had to change the runtime method syntax slightly, sacrificing a bit code similarity for better browser compatibility. For example, the compilation output of a JS2 method<br /><span style="font-family:courier new;"> public function foo(x) { }</span><br />was<br /><span style="font-family:courier new;"> "public", function foo(x) { }</span><br />and now looks like this:<br /><span style="font-family:courier new;"> "public foo", function(x) { }</span><br />or like this in debug mode:<br /><span style="font-family:courier new;"> "public foo", function foo(x) { }</span><br /></li></ol>The mean thing about these bugs is that they are all fixed in "Desktop-Safari" (Mac and Windows), so they are really hard to reproduce and even harder to debug. While we didn't have an iPhone or iPod touch available for long-term testing and debugging (I had to ask a colleague for the final test), and not even a Mac, my good old Suse Linux 9.3 with Konquror 3.4 served me reasonably well for this task. It seems Konqueror (whose KHTML engine is the prime father of WebKit) is more similar to Safari/iPhone than Safari/Desktop! Konqueror's JavaScript debugger is... er... limited, and its German localization is incredible (for those who understand German: guess what "Umbruch bei nächster Feststellung" is supposed to mean...), but at least it exists. So I hunted them bugs down, and here you go. The quite complex <span style="font-style: italic;">Jangaron</span> settings UI (implemented with <span style="font-style: italic;">Jangaroo Facelets</span>, more about that another day), and its even more complex real-time 3D graphics now all work perfectly and with reasonable performance on the iPhone! Please use the <a href="http://www.jangaron.net/khtml/jangaron.html">special iPhone version</a> already mentioned above.<br />Speaking of <span style="font-weight: bold;">performance</span>: the <span style="font-style: italic;">Jangaroo</span> compiler update also increased performance for some common special cases. Sounds contradictory, but there <span style="font-style: italic;">are</span> "common special cases", i.e. special code patters that still <span style="font-style: italic;">occur</span> quite often, like the fly-weight pattern: simple classes that have many instances. We optimized the <span style="font-style: italic;">Jangaroo</span> runtime (Class.js) so that for classes which refrain from using field initializers and/or inheritance, there is a measurable speed-up that leaves almost no performance penalty compared to manually created JavaScript 1.x code.<br />Have fun with the increased browser-compatible, performance-optimized new <span style="font-style: italic;">Jangaroo</span> version! We are eager to hear about your opinion and discuss your suggestions, so please don't hesitate to comment!Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0tag:blogger.com,1999:blog-5783184094166463434.post-8412240511938230262008-07-18T17:57:00.003+02:002014-02-22T13:26:33.671+01:00Former Life and Birth of JangarooToday, <a href="http://www.coremedia.com/">CoreMedia</a> released a first version of the Jangaroo language and tools as Open Source. This was a wonderful moment for me, because this little project has a long history and played an important <em>under</em>part in my professional life at CoreMedia over the last years. Please read about it, download, apply, spread the word! Be prepared to develop JavaScript like you never did before! The new Web site should offer you everything for a quick start. If not, feel free to ask! In this first blog post, however, you are going to hear Jangaroo's story, which covers its birth, coming of age, and reincarnation, if you want.<br />
<div class="p--heading-1">
Trying Not to Be Eclectic</div>
When in 2003, I had my first deeper dive into JavaScript, I never had thought it would become a passion. As most Java developers, I despised the style of <em>eclectic programming</em> that was then common among JavaScript hackers: To implement some requirement, they didn't use frameworks or libraries, but grabbed code snippets from other Web pages or forums and somehow assembled them to make them work on their Web pages. My impression was that it is hardly possible to implement serious business in such a patchwork language. But I had to, since a new Web application for CMS content entry waited to be designed and implemented.<br />
<div class="p--heading-1">
Patching a Patchwork Language</div>
My colleague Andreas Gawecki surely agreed on that and decided that, before even starting to dirty our hands on pure JavaScript, we needed a tool to transfer at least some of the amenities of Java to the JavaScript world. But because that was in the days before the Web 2.0 hype and the JavaScript Renaissance, there was no such tool. If you know Andreas, you may be able to imagine what happened: Within a week or so, he had gone through the JavaScript 2 / ECMAScript 4 standard proposals and came up with a compiler that could translate a subset of JavaScript 2 language features to JavaScript 1.x! Of course, Andreas had done research on how classes are usually simulated in JavaScript, and of course he had implemented those JS2-features a Java developer would need most desperately when having to program in JavaScript. I was one of his first Guinea Pigs, and also his primary sparring partner for the language. We started developing tons of JavaScript 2 code, because there were not even JavaScript 1 frameworks available, and we had to do all the cross-browser compatibility code ourselves. Andreas even implemented a Rich Text Editor that had features like table editing that were rare in 2003 - and all that using the JavaScript 2 subset and his compiler.<br />
<div class="p--heading-1">
One Thing Leads to Another</div>
This first shot of the compiler was simply named <strong>jscc</strong> (JavaScript Class Compiler), and the source file extension was <span style="font-family: courier new;">.jsc</span><span style="font-size: 0;">, so the language was also called <strong>JSC</strong></span>. Soon, more tools and libraries followed: Holger Tewis implemented a javadoc-counterpart, naturally called <strong>jscdoc</strong>, that tricked Java doclets into generating HTML API documentation for JSC programs. I did a port of <a href="http://jsunit.berlios.de/">JsUnit</a> to JSC, needless to say called <strong>JscUnit</strong>, in about two days (and of course its self-tests were green then). We experimented with writing IDE plug-ins for the unfinished language. Having learned from the WebEditor, we implemented another UI framework, which we so far only used for popping up a context menu on preview Web pages to let the user invoke content-related actions (sounds a bit like breaking a fly on the wheel, doesn't it?).<br />I loved working with JSC, but to be honest it had some serious drawbacks:<br />
<ul>
<li>There was no real IDE support.</li>
<li>No type checker, types are just remarks used for API documentation.</li>
<li>Bugs and request were not fairly tracked and never really tackled.</li>
<li>No class dependencies or automatic class loading: each class file had to be listed, and even in the right sequence before all its depending classes.</li>
</ul>
Worst, there was almost no documentation and the build process was tied to our primary product. JSC was suffering the typical fate of an internal development tool that had no (paying) customer, although a lot of value or at least potential. At that time, our company grew, and even other projects in the very same company did not use JSC for their JavaScript development. I felt there was something going wrong.<br />
<div class="p--heading-1">
Time for a Change</div>
CoreMedia went through some changes, which opened up new possiblities. We evolved to a learning company, where all members are given time for "peer group" work, i.e. work in small groups of people who pursue a common goal and handle a topic of individual choice. Luckily, I found fellows who were, like me, interested in reanimating JSC. The new spirit and transparency of our company was the perfect breeding ground for the idea to release JSC to the public, as Open Source. It was the perfect candidate:<br />
<ul>
<li>En vogue topic.</li>
<li>Focussed, general purpose tool.</li>
<li>Not too big to handle.</li>
<li>Nothing anyone would want to sell: development tools are hard to sell, anyway, and these are not our company's focus.</li>
<li>We had to document and clean up, anyway, so hardly any additional cost.</li>
</ul>
The main goal of the peer group, consisting of Andreas Gawecki, Olaf Kummer, Matthias Buse, Mark Michaelis, and myself, was to prepare a decision memo convincing CoreMedia to spend resources on our first real Open Source project.<br />
At that time, JavaScript really enjoyed a renaissance and AJAX was a hype. Interesting new articles about JavaScript mushroomed and inspired me to create a new JSC runtime supporting features like private and protected members, lazy class initializing, and even better readable compiled code. After several iterations, we decided to skip "really private" and protected members for performance reasons, but nevertheless found a solution that does the job to avoid unexpected name clashes. We also updated the language syntax to the latest standard proposals. Suddenly, IDEs started to support ActionScript 3, which is also an ECMAScript 4 language, so we could benefit from that, too.<br />
We were overcoming most disadvantages of JSC. In other words, we had even more to offer than what we had used successfully as an internal tool for years. <br />
The peer-group found that JSC needed a proper name: it should be Web-2.0-ish, cool, foolish, looney (add your favorite adjectives containing <em>oo</em>-s), and artificial, so that we could still grab the domain, the blogger subdomain (sic!), the user ID for community <em>xyz</em>, and so on. All our peer groups have rather silly animal names, and we were <em>True Kangaroo</em>. Replacing the first letter by a JavaScript <em>J</em> and keeping the popular <em>oo</em>-s finally led to <strong>Jangaroo</strong>. I guess the cool name must have been the critical factor when CoreMedia decided to give us a <em>go</em>.<br />
<div class="p--heading-1">
Walking the Talk</div>
In the execution phase, Masiar Bostanipoor (Web site) and Dennis Homann (build infrastructure, tutorial) joined the team. Andreas and Olaf rounded off compiler (now coherently called <strong>jooc</strong>) and runtime (where I helped a bit). Olaf wrote most of the language and compiler documentation. Kudos to numerous CoreMedians who helped us with the project, in no particular order and surely not complete: Thomas Stegmann, Gunnar Klauberg, Uli Henningsen, Tobias Baier, Jan Brauer, Carsten Böttcher, Stefanie Wegener, and Christian Pesch.<br />
We used the project time CoreMedia granted us mainly to come up with a stable infrastructure and an appealing presentation (at least we hope so), not to create more tools. We got the domain jangaroo.net, created a <a href="http://www.jangaroo.net/">Web home for Jangaroo</a>, started this blog, wrote <a href="http://www.jangaroo.net/documentation">documentation</a>, set up a proper build process involving a Maven repository, cared about license issues (German license jurisdiction is a nightmare!), and so on. Of course, some infrastructure is still missing, most importantly a forum and a bug tracker -- we are working on that, please bear with us! Until then, please comment in this blog for public discussions, and <a href="http://www.jangaroo.net/contact/">e-mail</a> for direct communication. We also have a twitter user <a href="http://www.twitter.com/Jangaroo">Jangaroo</a>, feel free to follow if you like! Many of the tools and libraries mentioned here may follow <strong>jooc</strong>, so stay tuned!<br />
I hope you have enjoyed hearing about Jangaroo's first life as JSC and its rebirth as an Open Source project. What I described is just the way I personally remember and feel about things. In the future, be prepared to find a bit more technological facts in my postings...Frankhttp://www.blogger.com/profile/07941551987898697351noreply@blogger.com0