Download

Go here to download ready-to-run and source distributions of Jangaroo. more...

Showing posts with label browser compatibility. Show all posts
Showing posts with label browser compatibility. Show all posts

Monday, November 22, 2010

Jangaroo 0.7.12: More AS3 Features, even for IE9

What's new in Jangaroo 0.7.12?

We are proud to present our latest Jangaroo release with many improvements and new features in several different areas.
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 @Jangaroo).

General

  • github
    Jangaroo is on github now!
    Check out Jangaroo Tools (compiler, Maven plugins, IDEA plugin) from https://github.com/CoreMedia/jangaroo-tools.
    Find Jangaroo JavaScript wrapper APIs (browser API, Ext JS, CKEditor, soundmanager 2) and libraries (URI utils, JooUnit, JooFlash) at https://github.com/CoreMedia/jangaroo-libs.
  • Maven Central
    Since version 0.7.9 you can use Jangaroo from Maven without specifying any <repository> or <pluginRepository> 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.
  • Compiler and Runtime Version in Generated Code
    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

    • the runtimeApiVersion matches the Runtime's runtimeApiVersion exactly and
    • the compilerVersion is lower or the same as the Runtime's compilerVersion.
    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.
  • Cyclic Static Dependency Detection
    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.
  • IntelliJ IDEA 9 Plugin
    As always, the Jangaroo Language IDEA plugin 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.

Newly Supported AS3 Features


  • Full trace() Compatibility and More
    In previous Jangaroo versions, trace() 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.
    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 [LOG], [INFO], [WARN] or [ERROR], the corresponding Firebug console method (log(), info(), warn() or error()) is invoked with the remainder of the message. For other environments, the string is printed as-is.
  • Variable Default Values
    Depending on their type, class variables (fields) are initialized to standard values as defined in the AS3 language specification (see bottom of page). Note that this feature is only implemented for class variables, including statics, but not yet for local variables.
  • Helper Classes
    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 blog post on helper classes .
  • Annotations
    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 flash.utils.describeType(), 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:
    var metadata:Object =
      joo.SystemClassDeclaration(SomeClass['$class']).metadata;
    
    To retrieve the metadata of a public class member, use the following pattern:
    var memberMetadata:Object =
      joo.SystemClassDeclaration(SomeClass['$class'])
      .getMemberDeclaration("public", "someMember").metadata;
    
    In both cases, the according annotation is transformed to an Object straight-forwardly, e.g.
    [SWF(width=465, height=465,
         backgroundColor=0, frameRate=15)]
    
    results in the metadata object
    {SWF:{width:465, height:465,
          backgroundColor:0, frameRate:15}}
    
  • as Operator
    Jangaroo has been supporting as for quite some time, but so far, it was not transformed into any code (only comments in debug mode).
    Now, as is implemented with its original AS3 semantics, i.e. checking the object's type and evaluating to null if there is no match. Be aware that this changes semantics of your code, for example if you used as 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 TypeError when using a later Jangaroo release.

Browser Compatibility


  • trace() in IE
    trace() now also works with Internet Explorer's console. It already worked before with Firefox with Firebug, WebKit, Opera, and any browser using Firebug light.
  • Property Accessor Functions in IE9
    So far, Jangaroo supported AS3 properties (function get/set) 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 ECMAScript 5 methods to define properties, but they were only implemented for DOM objects. Thus, Jangaroo only supports property accessor functions in IE9.
    To simulate this feature also in older IE versions is a much harder task, but still we might tackle it later (see discussion on Jangaroo User Group).
  • Workaround for IE9 Crash
    Jangaroo stores class meta data under the expando property $class 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.
    After intensive debugging, I figured out that IE9 does not like the $class property of built-in class TypeError 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 Error class and query it through a subclass (like TypeError), IE9 beta crashes. Comprising only 21 characters, this might actually be the shortest JavaScript "code of death" for IE9:
    Error.x=1;TypeError.x
    
    The workaround for Jangaroo is not to set $class on the Error 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."
  • @-Properties in IE
    Respect that IE does not like properties starting with @, and quote them.

Bug Fixes, Improvements and API Changes

  • fixed a minor bug in regular expressions syntax and improved parser error messages
  • improved class initialization, which was sometimes triggered eagerly when not necessary
  • cleaned up Runtime logging in debug mode: log class initialization instead of class loading
  • Introduced joo.boundMethod() in favor of Function.prototype.bind(). See its ASDoc for details.
  • overhauled joo.ResourceBundleAwareClassLoader API. See its ASDoc for details.

Jangaroo Libraries

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.
  • Flash Compatibility jooflash
    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 flash-lines as well as quite complex applications like Box2DFlashAS3.
  • Network Utilities jangaroo-net
    This new module contains utilities for URI parsing, formatting, relativizing and resolving functionality according to RFC 3986.
  • Ext JS ActionScript API ext-as
    The library Ext AS is an ActionScript 3 wrapper for Ext JS 3.2.2, so you can do Ext coding with code completion and type checks while keeping a fast turn-around.
  • Many more libraries, which we will cover in a future blog post.

As always, comments, questions, corrections, praise etc. are highly welcome! Why not contribute by issuing pull requests on github to include your bug fixes?

Andreas and Frank

Saturday, August 1, 2009

Jangaroo 0.3.1: Less Imports, More Rhino

We just released version 0.3.1 with some nice updates:

No more same-package imports

With Jangaroo 0.3.1, you no longer need to import classes of the same package to enable automatic class loading. The compiler now scans the directory of the current source file for all *.as files, so that it knows about all declarations in the same package. The limitation that you have to import top-level 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.

Oh, behave, Rhino!

Jangaroo works in many environments: in most browsers, and also in Rhino. For example, to run automated Jangaroo unit tests, the easiest way is to start a cross-platform, stand-alone JavaScript engine like Rhino.
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 [JavaPackage] objects for all imported top-level Java package name prefixes. You cannot get rid of some Java packages imported by default, among which are com and net, and even more badly, any property of Rhino's [JavaPackage] objects is claimed to be defined, and they are all again [JavaPackage]. For example, if Rhino knows of a Java class in com.mydomain, the JavaScript expression com.foobar also returns a [Java package] object, even if there is no such package!
This odd behavior made the Jangaroo runtime think that any Jangaroo class in a package starting with com or net 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 "[JavaPackage" 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 Packages, so simply use Packages.com.mydomain.

Alias for top-level package
The updated Jangaroo runtime defines the alias js for the top-level package. Why?
ActionScript seems to have a problem with top-level classes. Say you have a top-level class Node, and some framework defines a class org.w3c.dom.Node. In your client code, you need to use both classes, so you have to import org.w3c.dom.Node (the top-level class is in scope by default). With asdoc (which is based on the Flex ActionScript compiler), this situation leads to the error that Node is not defined (I also tried importing the top-level Node explicitly). Whether this is a compiler bug or a conceptual problem in ActionScript, I don't really care, since we cannot wait for asdoc 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?!
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 js, which at runtime is the same as the top-level package. Then, to come back to my example, you can use both js.Node and org.w3c.dom.Node 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 "js2native" in the Jangaroo Maven snapshot repository.

Wednesday, September 3, 2008

Jangaroo Applications Work on Google Chrome

Just a few days ago, Google released the first beta of their Chrome browser. Since the browser is based on WebKit, 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.
We have good news for you: The largest Jangaroo application so far, Jangaron, runs without any problems and really fast and smoothly! Congratulations, Google, you did a great job!




P.S.: I wrote this post using Chrome...

Tuesday, August 5, 2008

Jangaroo 0.1.1 - iPhone support!

One of my most important personal goals concerning Jangaroo has been reached with brand new version 0.1.1: it now runs on Safari/iPhone!
As a side-effect, this also makes Jangaroo 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 Jangaroo-based Tron Lightcycle game Jangaron 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 special iPhone version with on-screen buttons -- feel invited to go ahead and try!

So what was the problem with Jangaroo and old KHTML / WebKit versions? There were several bugs in the KHTML / WebKit JavaScript engine we had to work around:
  1. When using new Function(), it was not possible to set the prototype property, while with function(){}, it works as expected.
  2. with() seems to behave differently when setting properties of the "withed" object. Avoid it to be really cross-browser compatible!
  3. delete obj.property showed strange behavior: it seems that in some cases, the property is deleted from the prototype (i.e. for all instances!) instead of from obj only. We also refrained from using it in the runtime.
  4. 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 Function#name is not defined and Function#toString() returns the whole source code of the function save 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
    public function foo(x) { }
    was
    "public", function foo(x) { }
    and now looks like this:
    "public foo", function(x) { }
    or like this in debug mode:
    "public foo", function foo(x) { }
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 Jangaron settings UI (implemented with Jangaroo Facelets, 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 special iPhone version already mentioned above.
Speaking of performance: the Jangaroo compiler update also increased performance for some common special cases. Sounds contradictory, but there are "common special cases", i.e. special code patters that still occur quite often, like the fly-weight pattern: simple classes that have many instances. We optimized the Jangaroo 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.
Have fun with the increased browser-compatible, performance-optimized new Jangaroo version! We are eager to hear about your opinion and discuss your suggestions, so please don't hesitate to comment!