Skip to content

qooxdoo News
Syndicate content
The qooxdoo news section
Updated: 1 hour 42 min ago

The week in qooxdoo (2010-03-05)

Fri, 03/05/2010 - 16:47

Howdy, all! Still bent on performance improvements and support for internal projects, this is what we have this week.

Performance Optimizations

One of the major goals for qooxdoo 1.1 is improving the overall performance of the framework. You can't optimize what you can't measure. That's why we started by writing a little benchmark application called PerformanceRunner. It is based on our TestRunner and we use it to measure the performance of certain actions and to monitor performance regression. We plan to integrate performance reports into our nightly builds to be able to quickly react on commits, which degrade performance.

In the last week we've been concentrating mostly on object creation. Besides some smaller improvements we were able to remove the constructor wrapper in almost all cases. This resulted in a significant performance boost, when instantiating qooxdoo objects using the new statement. The next milestone will be to optimize widget creation/rendering and the decorators.

Generator

For those who care, there is a new background article about the technical details on how to provide a component, like TestRunner or ApiViewer, as a standard job to all applications. It also covers a fair bit of general ground how parametrization of jobs can be achieved.

Bugs

Here is the usual canned bugzilla query for the past week's fixed bugs.

So much for this week - be in touch next time.

Categories: Open Source

qooxdoo @ Open Source Days 2010

Mon, 03/01/2010 - 18:57

Open Source Days is one of the largest open source conferences, held in Copenhagen, Denmark on March 5-6, 2010.

opensourcedays2010

The website says: "It's your opportunity to meet, share, and learn from professional open source experts." Well, for you as a qooxdoo user it is not just about any open source experts. As Tobi Oetiker, of OSS fame and a long-time qooxdoo contributor, already announced on the qooxdoo mailing list a while ago, he'll be at the conference to talk about "qooxdoo: Writing Complete Applications in JavaScript".

If you happen to make it to Open Source Days 2010, don't miss to get in touch with him for some decent tech discussion and for qooxdoo schwag. Thanks Tobi and good luck with your qooxdoo talk!

Categories: Open Source

The week in qooxdoo (2010-02-26)

Fri, 02/26/2010 - 22:16

Welcome back to another weekly status update.

All good things come in threes

Part 3 of the tutorial series is here, this time integrating communication features while utilizing qooxdoo's data binding layer. If you haven't, check out this tutorial.

Part Loading

For the last two weeks we've been working on the part loader. The part loader is used to load qooxdoo parts on demand into the browser. We specifically worked in the following three areas:

  1. Remove dependencies from the part loader
  2. Load packages in parallel
  3. Improve error handling
Remove dependencies from the part loader

Some applications use the part loader in a very early state. The boot part of these applications only consists of the part loader and very few custom code. However, before our improvements the minimal (uncompressed) size of such a boot package was ~100KB. By rewriting the part loader using only functionality provided by qx.Bootstrap we were able to shrink the size by a factor of 5! Now a package containing a part loader is usually smaller than 20KB. This is a great way to reduce the startup time of an application.

Load packages in parallel

Parts consist of one or more packages. A package basically is just a JavaScript file containing a subset of the required classes. When loading a part it is important to evaluate the packages in the correct order. Note that I say evaluate and not load. We can load the packages in any order and even load them in parallel if we can control when their contents are evaluated. We tweaked our generator to wrap each package content in a closure and pass this closure to a global function. This function can store the closure and evaluate it at any given time. The technique is a similar to the one described by the SproutCore team. The result is that we can now load packages in parallel. As a bonus we can even tell the part loader to pre-load a part from the server without evaluating the code until it is actually required.

Improve error handling

One issue with the old implementation came up recently. An application had unexpected errors in IE, which seemed to be related to part loading but were very hard to track. It turned out that the server was busy and occasionally could not deliver a JavaScript file. To load the scripts we dynamically insert script tags but Opera and Internet Explorer do not fire an error event to signal server errors. Since each package now calls a global notify function once it is loaded, we can simply start a timer when we start loading a file and stop the timer once the global function is called. If the timer is not stopped we will assume that loading the file failed and fire an error event. This way we have proper error handling in all supported browsers.

Generator Parts

Part collapsing has been enhanced, to avoid issues with class dependencies during the process. The generator now employs new constraints that take better care of dependencies between packages. At the same time, the part verifier has been augmented with additional checks to test for violations of these dependencies. It will now raise an exception when a violation is detected (rather than just issue warnings). But this behavior can be toggled with the packages/verifier-bombs-on-error config setting.

I18N

Work is underway to have internationalization data as separate parts. This is extending on functionality available with the (experimental) packages/i18n-with-boot config setting, which when set to false would cause the generator to write I18N data in separate files. Currently, these files contain locale information (time and date formats, etc.) and translated strings for a particular language code (e.g. "en"). This makes it easy to load only one such file after application startup, rather than have all the information for all supported language codes in the browser all the time. This can make a significant difference in bandwidth and memory consumption for large applications with lots of translated strings.

Currently, those data files have to be loaded and evaluated by custom code in the application. They shall now be made into proper packages which can be loaded through corresponding parts. This leverages on qooxdoo's part loading mechanism and saves the application programmer from writing boilerplate code for them. It also leverages on the extended qooxdoo package format, which supports data alongside to code in a package.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

That's it for now, see you around next time.

Categories: Open Source

The week in qooxdoo (2010-02-19)

Fri, 02/19/2010 - 16:43

Greetings all, for another round-up of the most recent news bits in qooxdoo land. We are currently particularly focusing on performance topics, mostly concerning application start-up and run time behaviour, but also over the whole life cycle of an application. This will show in some of today's entries. To that end, we are also working on new tool support, playing with a Performance Runner application.

Tutorial, continued

Part 2 of the three-part tutorial series has landed in the blog, this time fleshing out the UI of the demo twitter app. If you are a beginner-to-medium level qooxdoo user, this one is for you.

Part Loading

We are currently working on the part loading mechanism of qooxdoo. For those who don't know what parts are, here is the idea of parts. A part is a set of JavaScript "packages" which will be loaded on demand. Each package holds a number of qooxdoo classes and in the build version is usually comprised of a single JavaScript file. Those packages have dependencies between each other, so they need to be loaded in a predefined order.... really?! No, they have to be executed in that order! This is the thing we are currently working on. We try to load the packages in parallel and then execute them in the predefined order.

Generator

The generator has now enhanced verbose logging, offering verbose log filters that can be defined on the configuration level, to limit what gets printed with the -v command line switch. See the dedicated post.

The main generator function has been reorganized, to minimize the calculation of dependency lists. As a trade-off, resource copying is now done per variant set. So in case you are using n-valued (n>1) variant keys in your config when generating the application, you will see as many resource copying steps as script compile steps.  The rational is that it is cheaper to copy files around than to calculate dependencies. Please report back if this doesn't hold true for you.

Windows 7

Thanks to the feedback of Marc Otto the regular cmd.exe shell of Windows 7 might have troubles when trying to use qooxdoo's tool chain in certain cases. He was successful, though, when using the PowerShell which is installed on Windows 7 by default. To launch it hit the Win+R keys and enter powershell. To execute a regular app generation, do not forget to prepend the command with the local directory explicitly: .\generate.py source. PowerShell has proven to be useful on other Windows versions as well, e.g. when you want to redirect generator output to a file.

Are there any other tips & tricks you like to share, or info on how to use the regular command shell for qooxdoo app development under Windows 7?

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

That's it for today, see you around next time.

Categories: Open Source

Tutorial Part 3: Time for Communication

Fri, 02/19/2010 - 15:13

After we created the application and the main window in the first tutorial part and finished the UI in the second, we will build the communication layer today. With that part the application should be ready to use.

Pre-Evaluation

First, we need to specify what's the data we need to transfer. For that, we need to take a look what tasks our application can handle:

  1. Show the friends timeline for a specific user.
  2. Post a tweet.

So it's clear that we need to fetch the friends timeline (that's how it is called by twitter), and we need to post a message to twitter. It's time to take a look at the twitter API so that we know what we need to do to communicate with the service.
But keep in mind that we are still on a website so we can't just send some POST or GET requests due to cross-site scripting restrictions. The one thing we can and should do is take advantage of JSONP. If you have never heard of JSONP, take some time to read the article on ajaxian to get further details.

Creating the Data Access Class

Now, that we know how we want to communicate, we can tackle the first task, fetching the friends timeline. twitter offers a JSONP service for that which we can use. Luckily, twitter also takes care of the login process on the server side so we don't need to bother with that in the client. The following URL returns the friends timeline wrapped in a JavaScript method call (that's what JSONP is about):

http://twitter.com/statuses/friends_timeline.json?callback=methodName

Now we know how to get the data from twitter. Its time for us to go back to the qooxdoo code. It is, like in the case of the UI, a good idea to create a separate class for the communication layer. Therefore, we create a class named TwitterService. We don't want to inherit from any advanced qooxdoo class so we extend straight from  qx.core.Object. The code for that class should looks like this:

qx.Class.define("twitter.TwitterService",
{
  extend : qx.core.Object,
  members :
  {
  }
});
Fetching the Data

As you can see, we omitted the constructor because we don't need it currently. But we already added a members block because we want to add a method named fetchTweets:

    fetchTweets : function() {
 
}

Now it's time to get this method working. But how do we load the data in qooxdoo? As it is a JSONP service, we can use the JSONP data store contained in the data binding layer of qooxdoo. But we only want to create it once and not every time the method is called. Thats why we save the store as a private instance member and check for the existence of it before we create the store. Just take a look at the method implementation to see how it works.

      if (this.__store == null) {
        var url = "http://twitter.com/statuses/friends_timeline.json";
        this.__store = new qx.data.store.Jsonp(url, null, "callback");
        // more to do
      } else {
        this.__store.reload();
      }

We already added the code in case the store exists. In that case, we can just invoke a reload. I also mentioned that the instance member should be private. The two underscores (__) mark the member as private in qooxdoo. The creation of the store or the reload method call starts the fetching of the data.

But where does the data go? The store has a property called model where the data is available as qooxdoo objects after it finished loading. This is pretty handy because all the data is already wrapped into qooxdoo objects! Wait, hold a second, what are qooxdoo properites? Properties are a way to store data. You only need to write a definition for a property and qooxdoo will generate the mutator and accessor methods for that property. You will see that in just a few moments.

We want the data to be available as a property on our own service object. First, we need to add a property definition to the TwitterService.js file. As with the events specification, the property definition goes alongside with the members section:

  properties : {
    tweets : {
      nullable: true,
      event: "changeTweets"
    }
  },

We named our property tweets and added two configuration keys for it:

  • nullable describse that the property can be null
  • event takes the name of the event fired on a change of the property

The real advantage here is the event key which tells the qooxdoo property system to fire an event every time the property value changes. This event is mandatory for the whole data binding we want to use later. But that's it for setting up a property. You can find all possible property keys in the documentation.

Now we need to connect the property of the store with the property of the twitter service. That's an easy task with the single value binding included in the qooxdoo data binding. Just add the following line after the creation of the data store:

        this.__store.bind("model", this, "tweets");

This line takes care of synchronizing the two properties, the model property of the store and the tweets property of our service object. That means as soon as data is available in the store, the data will also be set as tweets in the twitter service. Thats all we need to do in the twitter service class for fetching the data. Now its time to bring the data to the UI.

Bring the tweets to the UI

For that task we need to go back to our Application.js file and create an instance of the new service:

      var service = new twitter.TwitterService();

You remember the debug listener we added in the last tutorial? Now we change the reload listener to fetch the tweets:

      // reload handling
      main.addListener("reload", function() {
        service.fetchTweets();
      }, this);

Thats the first step of getting the data connected with the UI. We talk the whole time of data in general without even knowing how the data really looks like. Adding the following lines shows a dump of the fetched data in your debugging console.

      service.addListener("changeTweets", function(e) {
        this.debug(qx.dev.Debug.debugProperties(e.getData()));
      }, this);

Now it's time for a test. We added a new classes so we need to invoke the generator and load the index file of the application. Hit the reload button of the browser and see the data in your debugging console. The important thing you should see is that the data is an array containing objects holding the items we want to access: the twitter message as text and "user.profile_image_url" for the users profile picture. After evaluating what we want to use, we can delete the debugging listener.

But how do we connect the available data to the UI? qooxdoo offers controllers for connecting data to a list widget. Thats the right thing we need in that case. But we currently can't access the list of the UI. Thats something we need to change.

Switch to the MainWindow.js file which implements the view and search for the line where you created the list. We need to implement an accessor for it so its a good idea to store the list as a private instance member:

    this.__list = new qx.ui.form.List();

Of course, we need to change every occurance of the old identifier list to the new this.__list. Next, we add an accessor method for the list in the members section:

    getList : function() {
      return this.__list;
    }
Data Binding Magic

That was an easy one! Now back to the application code in Application.js. We need to set up the already mentioned controller. Creating the controller is also straight forward:

      // create the controller
      var controller = new qx.data.controller.List(null, main.getList());

The first parameter takes a model we don't have right now so we just set it to null. The second parameter takes the target, the list. Next, we need to specify what the controller should use as label, and what to use as icon:

      controller.setLabelPath("text");
      controller.setIconPath("user.profile_image_url");

The last thing we need to do is to connect the data to the controller. For that, we use the already introduced bind method, which every qooxdoo object has:

      service.bind("tweets", controller, "model");

As soon as the tweets are available the controller will know about it and show the data in the list. How about a test of the whole thing right now? You need (again) to tell the generator to build the source version of the application.

After the application has been loaded in the browser, I guess you see nothing until you hit the reload button of the UI. That's one thing we have to fix: Load the tweets at startup. Two other things are not quite the way we want them to be: The tweets get cut off at the end of the list, and the icons can be delivered by twitter in different sizes. So let's fix those three problems.

The first thing is quite easy. We just add a fetch at the end of our application code and that will initiate the whole process of getting the data to the UI:

      // start the loading on startup
      service.fetchTweets();

The other two problems have to be configured when creating the items for the list. But wait, we don't create the list items ourselves. Something in the data binding layer is doing that for us and that something is the controller we created. So we need to tell it how to configure the UI elements it is creating. For exactly such scenarios the controller has a way to handle code from the user, a delegate. You can implement the delegate method configureItem to manipulate the list item the controller creates:

      controller.setDelegate({
        configureItem : function(item) {
          item.getChildControl("icon").setWidth(48);
          item.getChildControl("icon").setHeight(48);
          item.getChildControl("icon").setScale(true);
          item.setRich(true);
        }
      });

You see that the method has one parameter which is the current UI element which needs to be configured. This item is a list item which stores its icon as a child control you can access with the getChildControl method. After that, you can set the width, height and the scaling of the icon. The last line in the configurator set the item to rich, which allows the text to be wrapped. Save your file and give it a try!

step3

Now it should be the way we like it to be. Sure it's not perfect because it has no error handling but that should be good enough for the tutorial.

Posting tweets

As you have seen in the last paragraphs, creating the data access layer is not that hard using qooxdoo's data binding. That is why we want you to implement the rest of the application: Posting of tweets. But I will give you some hints so it does not take that much time for you.

  1. twitter does not offer a JSONP API for posting tweets. Thats why you should use YQL for that. They have a blog post on how to use YQL to post on twitter.
  2. YQL uses HTTPS. If you want to use the qooxdoo YQL store, you have use the trunk version of qooxdoo because we added the HTTPS feature lately.
  3. Use the easiest input forms available in JavaScript (prompt) to get the additionally data you need. Its about the data access layer and not the UI!
  4. Clear the text area and reload the tweets after you send the post. That should be enough feedback that the posting worked.

That should be possible for you right now! If you need to take a look at an implementation, you can always take a look at the code on github or fork the project.

That's it for the third part of the tutorial. With this tutorial, the application should be ready and we can continue our next tutorial lines based on this state of the application. As always, if you have any feedback, please let us know!

Tutorial Part1 Tutorial Part2

Categories: Open Source

Tutorial Part 2: Finishing the UI

Wed, 02/17/2010 - 09:51

In the first part of the tutorial, we built a basic window for our target application, a twitter client. In the second part of the tutorial, we want to finish the UI of the application. So lets get started, we got a lot to do!

I hope you remember the layout of the application we are trying to build. If not, here is a little reminder.

twitterMockup

The first thing we need to do is to set a layout for our window. You can see that the text area and the button are side by side while all the other elements are ordered vertically. But all elements are aligned in a grid so we should choose a grid layout for that. We can add the grid layout in our own window class. Just add these lines of code in MainWindow.js:

    // add the layout
    var layout = new qx.ui.layout.Grid(0, 0);
    this.setLayout(layout);

But a layout without any content is boring so we should add some content to see if it's working. Lets add the first two elements to the window, the toolbar and the list view.

Layout and Toolbar

First, we need to create the toolbar before we can add it. Creating the toolbar and adding it is straight forward.

    // toolbar
    var toolbar = new qx.ui.toolbar.ToolBar();
    this.add(toolbar, {row: 0, column: 0});

This will add the toolbar to the grid layout of our main window. The only thing you should take care of is the second parameter of .add(). It contains a map with layout properties. You can see the available layout properties in the API of the layout, in this case of the grid layout. Here, we use only the row and column property to tell the layout that this is the element in the first row and column (rows and columns start at index 0, you guessed it).

List and Layout, again

Adding the list should look familiar now.

    // list
    var list = new qx.ui.form.List();
    this.add(list, {row: 1, column: 0});

Now its time to see our work in the browser. But again, we have added new class dependencies so we need to invoke the generator with ./generate.py source. After that, we can see the result in the browser. I guess it's not the way we like it to be. You cannot see any toolbar, the list has too much padding against the window border and doesn't fit the whole window. That's something we should take care of now.

First, get rid of that padding we don't need. The window object has a default content padding which we just  to set to 0.

    this.setContentPadding(0);

Put that line in your windows constructor and the padding is gone.

Next, we take care of the size of the list. The layout does not know which column(s) or row(s) it should stretch. So we need to tell the layout which one it should use:

layout.setRowFlex(1, 1);
layout.setColumnFlex(0, 1);

The first line tells the layout to keep the second row (the row for the list) flexible. The second row does the same for the first column.

The last thing we need to fix was the invisible toolbar. If you know the reason why it's not visible, you sure know how to fix it. It contains not a single element so it won't be visible. Fixing it means adding an element, in our case we just add the reload button. We already know how to create and add widgets so just add the following lines of code.

    // reload button
    var reloadButton = new qx.ui.toolbar.Button("Reload");
    toolbar.add(reloadButton);

Now its time to see if all the fixes work. But be sure to run the generator before you reload the browser page because we added (again) another class (the button). Now everything should look the way we want it to be.

Text Area and Button

After that success, we can got to the next task, adding the text area and "Post" button. This is also straight forward like we have seen in all the other adding scenarios.

    // textarea
    var textarea = new qx.ui.form.TextArea();
    this.add(textarea, {row: 2, column: 0});
 
    // post button
    var postButton = new qx.ui.form.Button("Post");
    this.add(postButton, {row: 2, column: 1});

This time, we have to add the button in the second column to get the button and the text area aligned horizontally. Its time to test this... again generate and reload.

Like the last time, the result is not quite what we want it to be. The list and toolbar do not fill the whole window. But that's a home-made problem because we extended our grid to two columns by adding the post button. The list and the toolbar need to span both available columns to have the result we want. But that's easy too, add colSpan: 2 to the layout properties used by adding the list and the toolbar. Your code should look like this:

    this.add(toolbar, {row: 0, column: 0, colSpan: 2});
    // ...
    this.add(list, {row: 1, column: 0, colSpan: 2});

This time, we did not add a new class dependency so we can just reload the index file and see the result.

Breathing Life into the UI

The UI now looks like the one we have seen in the mockup. But how does the UI communicate with the application logic? It's a good idea to decouple the UI from the logic and use events for notifying the behaviour. If you take a look we only have two actions where the UI needs to notify the rest of the application: reloading the tweets and posting a tweet.

These two events we add to our window. Adding events is a two step process. First, we need to declare what kind of event we want to fire. Therefore, we add an events section alongside to the constructor section of the window class definition:

  events :
  {
    "reload" : "qx.event.type.Event",
    "post"   : "qx.event.type.Data"
  },

As you can see in the snippet here, it ends with a comma. It always depends on what position you copy the section if the comma is necessary. Just take care the the class definition is a valid JavaScript object. But now back to the events. The reload event is a plain event which only notifies the receiver to reload. The post event is a data event which contains the data to post to twitter. That's why there are two different types of events used.

Declaring the events is the first step of the process. The second part is firing the events! Let's take a look at the reload event. It needs to be fired when the reload button was triggered (or "was executed" in qooxdoo parlance). The button itself fires an event on execution so we could use this event to fire our own reload event.

    reloadButton.addListener("execute", function() {
      this.fireEvent("reload");
    }, this);

Here we see two things: First, how to add an event listener and second, that firing an event is as easy as a method call. The only parameter to .fireEvent() is the name of the event we have declared in the class definition. Another interesting thing here is the third parameter of the addListener call, this. It sets the context of the callback function to our window instance, so the this in this.fireEvent() is resolved correctly.

The next case is a bit different but also easy.

    postButton.addListener("execute", function() {
      this.fireDataEvent("post", textarea.getValue());
    }, this);

This time, we call the fireDataEvent method to get a data event fired. The second parameter is the data to embed in the event. We simply use the value of the text area. That's it for adding the events. To test both events we add a debug listener for each event in out application code, in the main() method of Application.js:

      main.addListener("reload", function() {
        this.debug("reload");
      }, this);
 
      main.addListener("post", function(e) {
        this.debug("post: " + e.getData());
      }, this);

You can see in the event listener functions that we use the qooxdoo debugging function debug. Now it's time to test the whole UI. Open the index file in a browser you like and see the UI. If you want to see the debugging messages you have to open either a the debugging tool of your chosen browser or use the qooxdoo debugging console. Press F7 to get the qooxdoo console visible.

Finishing Touches

As a last task, we can give the UI some finishing touches. Wouldn't it be nice if the text area had a placeholder text saying you should enter your message here? Easy task!

    textarea.setPlaceholder("Enter your message here...");

Another nice tweak could be a twitter logo in the windows caption bar. Just download this logo from twitter and save it in the source/resource/twitter folder of your application. Adding the logo is easy because the window has also a property for an icon, which can be set in the constructor. Adding the reference to the icon in the base call should do the job.

    this.base(arguments, "twitter", "twitter/t_small-c.png");

This time, we added a new reference to an image. Like with class dependencies, we need to run the generator once more. After that, the image should be in the windows caption bar.

Two more minor things are left to finish. First, the button does not look very good. Why don't we just give it a fixed width to fit its height.

    postButton.setWidth(60);

The last task is a bit more complicated than the other tweaks before. As you probably know, twitter messages have a maximum length of 140 characters. So disabling the post button if the entered message has more the 140 characters could help us out in the communication layer. A twitter message with no text at all is also useless and we can disable the post button in that case. To get that we need to know when the text was changed in the text area. Fortunately, the text area has a data event for text changes we can listen to:

    textarea.addListener("input", function(e) {
      var value = e.getData();
      postButton.setEnabled(value.length < 140 && value.length > 0);
    }, this);

The event handler has only two rows. The first gets the changed text of the text area from the data event. The second row sets the enabled property of the post button if the length of the message is lower than 140 characters and not 0. Some of you might have a bad feeling about this code because the listener is called every time the user adds a character. But that's not a problem because the qooxdoo property system takes care of that. Setting a already set value will cancel the whole process of setting a new value.

The last thing we should consider is the startup of the application. The text area is empty but the button is enabled. Disabling the button on startup is the way to go here.

    postButton.setEnabled(false);

Now go back to the browser and test your new tweaks. It should look like this.
step2

That's it for building the UI. Again, if you want to take a look at the code, fork the project on github.
Next time we take care of getting the data. If you have feedback on this post, just let us know!

Tutorial Part 1 Tutorial Part3

Categories: Open Source

Generator Verbose Logging

Tue, 02/16/2010 - 16:20

The generator since long supports the -v command line switch. Turning this switch on will make the generator print out lots of messages and internal data while going through configurations and running jobs. This is one of the first and easiest means to inspect the workings of the generator as it proceeds, and has been very helpful in tracking down issues with custom configurations and job delivery.

But as more and more functionality went into the generator the amount of verbose logging has grown tremendously. You had to redirect its output to a file and then wade through it in a suitable editor or viewer, in order to gather the pieces of information you were actually interested in. So if you just wanted to know which qooxdoo classes were brought together to make up your application, or which of those classes made it into which part (if you were using parts), this could be a challenge although the information was readily available.

On top of the known -v switch the generator now offers two more features around verbose logging. A new command-line switch, -w/--config-verbose, has been introduced to separate verbose logging of all the generator activities before actually running a given job. (As this is mainly processing of the configuration file and its directives, hence the long name of the option). On the other side, the scope of -v has been restricted and now specifically applies to running the jobs themselves.

The other feature is that you can specify log4j-like module patterns of the generator, and then verbose logging will be restricted to these modules and their functions only. It is implemented as a sub-key of the "log" config key, namely as log/filter/debug. This key takes an array of module patterns, similar to the class patterns of other config keys. If a function now tries to log a message verbosely, its module path is matched against all of the given patterns, and the message is only printed on a successful match. E.g

"log" : { "filter" : { "debug" : [ "generator.code.PartBuilder.*" ] } }

will only allow functions from the generator.code.PartBuilder module to be printed. This greatly reduces verbose log output and allows you to focus on the areas you are interested in. I think the future will see some common, pre-defined filters that can be easily added to a job so you are not forced to go down to the basic config key level to enable them.

Categories: Open Source

The week in qooxdoo (2010-02-12)

Fri, 02/12/2010 - 20:33

This week we were rather busy with updating some of our hard/software infrastructure, refining the various responsibilities within the team (also in anticipation of Fabian's leave), and identifying and addressing topics of the upcoming releases.

So if you haven't already, make yourself familiar with the new series of tutorials that started this week, take comfort in the following list of bugfixes and stay tuned for more news and tutorials next week.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

Categories: Open Source

Saying Farewell

Fri, 02/12/2010 - 19:46

After more than three years as full time qooxdoo developer I (Fabian) am going to leave 1&1 at the end of March. Looking back it is amazing how much qooxdoo has evolved.

  • When I came to 1&1, the qooxdoo core team consisted only of Alex, Andreas, Sebastian and me. Today the qooxdoo team has eight full time developers.
  • IE7 just came out and we were just starting to experiment with Safari. Today we have HTML5, CSS3, the mobile web and more.
  • In 2006 JavaScript was still regarded as a toy language. Today we have JavaScript everywhere. On the Phone, on the Desktop, on the Server and of course in the browser.
  • qooxdoo itself has come a pretty long way as well. We've added the OOP layer with version 0.7. In version 0.8 we reimplemented the widget and layout system from scratch. This all resolved into qooxdoo 1.0 which we released last December.
  • The perception and adoption of qooxdoo has changed as well. From the little known framework with a weird name, qooxdoo has grown up to be recognized as one of the top rich client JavaScript frameworks. Inside of 1&1 it has become the basis for most of the JavaScript development including the impressive gmx.com mail client.

The team is awesome, the community is extremely nice and qooxdoo is on a very good way - why on earth would someone leave this behind? One reason is that qooxdoo is leaving the rough waters of creative and sometimes chaotic development and entering the calm waters of a stable business approved toolkit. Deep in my heard I'm still a creator, who wants to build stuff. I'm not as good in maintaining things. That's why it's time for me to move on.

I'm really proud and thankful for being part of the team. I know qooxdoo can do without me - time will tell if I can do without qooxdoo.

Thank You

Categories: Open Source

Tutorial Part 1: The Beginning of a twitter App

Mon, 02/08/2010 - 17:21
The Missing Manual

We have heard it a couple of times: Users are missing a tutorial a bit more complex than the simple "Hello World" tutorial we already have. Today, we want to close that gap between the first tutorial and the demo applications included in the framework like the Feedreader.

As you sure have read in the headline, we are building a simple twitter application. twitter is a well known service for posting public short messages and has a good API for accessing data. The following mockup shows you how the application should look like at the end.

twitterMockup
If you take a closer look at the mockup, you see a window containing a toolbar, a list, a text area and a button to post messages. This should cover some common scenarios of a typical qooxdoo application.

In the first part you'll learn how to create a new application and how to build a part of the main UI. But before we get started, be sure you looked at the "Hello World" tutorial. We rely on some of the fundamentals explained there.

Getting started

The first step is to get a working qooxdoo application where we can start our development. You should have already have the qooxdoo SDK and know how to use create-application.py, so we just create an application called twitter.

create-application.py -n twitter

After that, we should check if everything works as expected. Change the directory to twitter and run ./generate.py source. Now the skeleton application is ready to run and you can open the index file located in the source directory. After that, open the Application.js file located in source/class/twitter/Application.js with your favorite editor and we are set up for development!

You should see the unchanged skeleton code of the application containing the creation of a button. We don't need that anymore so you can delete it including all the listener stuff.

The first part is to create a Window. As the Window contains all the UI controls, we should extend from the qooxdoo Window and add the controls within that class. Adding a new class is as easy as creating a new file. Just create a file parallel to the Application.js file named MainWindow.js. Now it is time to add some code to that file. We want to create a class so we use the qooxdoo function qx.Class.define for that. Add the following lines to your newly created file.

qx.Class.define("twitter.MainWindow",
{
  extend : qx.ui.window.Window,
 
    construct : function()
    {
      this.base(arguments, "twitter")
    }
});

We have created our own class extending the qooxdoo Window. In the constructor, we already set the caption of the window, which is the first constructor parameter of the qooxdoo window. So you already have guessed it, this.base(arguments) calls the overridden method of the superclass, in this case the constructor.
To test the window, we need to create an instance of it in the main application. Add these two lines of code in the Application.js file to create and open the window.

      var main = new twitter.MainWindow();
      main.open();

Now its time to test the whole thing in the browser. But before we can do that, we need to run the generator once more because we added the window class as new dependency. So run ./generate.py source and open the page in the browser. You should see a window in the top left corner having the name "twitter".

Programming as Configuring

The last task of this tutorial part is to configure the window. Opening the window in the left corner does not look so good, so we should move the window a bit away from the edges of the viewport. To do this add the following line to your application file:

      main.moveTo(50, 30);

Another thing we should configure are the buttons of the window. The user should not be able to close, minimize nor maximize the window. So we add the following lines of code in our windows constructor.

    // hide the window buttons
    this.setShowClose(false);
    this.setShowMaximize(false);
    this.setShowMinimize(false);

The last thing we could change is the size of the window on startup. Of course the user can resize the window but we should take care of a good looking startup of the application. Changing the size is as easy as hiding the buttons, just tell the window in its constructor:

    // adjust size
    this.setWidth(250);
    this.setHeight(300);

At this point, your application should look like this. step1

Thats it for the first part. If you want to have the code from the tutorial, take a look at the project on github and just fork the project.
The next part of the tutorial will contain the building of the rest of the UI. If you have feedback or want to see something special in further tutorials, just let us know!

Tutorial Part2 Tutorial Part3

Categories: Open Source

The week in qooxdoo (2010-02-05)

Fri, 02/05/2010 - 18:35

Another weekly status update fresh from the oven:

TabView focus indicator

There was an open issue for a while now about a missing indicator for keyboard focus of the TabView widget. We now added a nice keyboard indicator to the TabView.

Dispose

We increased the granularity of the qx.disposerDebugLevel, which can help you find memory leaks in your application. There now is an additional level for just warning about undisposed qooxdoo objects without warning for undisposed JavaScript objects.

The following listing shows the levels and their meaning:

  • 0: No warnings at all
  • 1: Warn for undisposed qooxdoo objects
  • 2: Warn for undisposed qooxdoo and JavaScript objects
  • 3: Warn for undisposed qooxdoo and JavaScript objects and log every disposed object
Dependencies

A long standing bug has been fixed which forced classes to unnecessarily maintain an explicit require to qx.core.Variant. These explicit requires can now be removed, as has been done for qx.Theme, qx.Mixin and qx.Interface. Previously, the dependency of classes to qx.core.Variant got lost in the source version when variant settings were defined in the build configuration, as the dependency tracker works on the optimized tree, where code blocks for unneeded variant values has been removed - and with it the calls to qx.core.Variant. But the calls would still be there in the source version, so this dependency had to be preserved for source builds, which is the case now.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

Have a nice week(end)!

Categories: Open Source

The week in qooxdoo (2010-01-29)

Fri, 01/29/2010 - 22:44

Welcome to the regular weekly blog post. With all the other highlights during the week, most noticeably the release of qooxdoo 1.0.1, coincidentally at the day of qooxdoo's 5 year anniversary, we'll keep it short:

Patch for qooxdoo 0.7.4 in Firefox 3.6

This week we found out that the legacy qooxdoo 0.7.4 version has an inadvertently incomplete bug fix for the deprecated "getBoxObjectFor" method in Firefox 3.6, which was released a few days ago. We now created a patch to allow qooxdoo 0.7.4 to run as intended, i.e. correctly, in Firefox 3.6.

Download the complete ''qx.html.Loaction'' class file and replace the local one, or apply the SVN diff to the 0.7.4 version. For more details have a look at the corresponding bug report.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

C U around next time.

Categories: Open Source

qooxdoo 1.0.1 released

Wed, 01/27/2010 - 20:17

After the successful launch of qooxdoo 1.0 end of last year, here comes a regular update to incorporate the latest bug fixes and also a number of enhancements.

qooxdoo 1.0.1 is a patch release, meant to be backwards compatible to the previous major release qooxdoo 1.0. No migration steps should be necessary to continue to develop and build your existing apps. Please upgrade to take full advantage of this latest stable release.

From the detailed release notes, here are some of the most important fixes:

  • Fixed an issue in Firefox 3.6, which was released last week (01/21/2010). The native scrollbar widgets did no longer react on clicks on the scrollbar buttons. This is a known regression in Firefox 3.6, but fortunately we could find a workaround for this issue.
  • Fixed a critical issue that prevented IE to run properly under SSL. See Bug #3305 for details. It is strongly recommended to update to this release, if your application is deployed via https.
  • Hiding elements, which use the AlphaImageLoader, can occasionally cause IE to completely black out the screen. We now use a technique described here to fix it.

As the latest stable version it is also perfect for new users to easily get started with qooxdoo. Download and enjoy this brand new qooxdoo release.

Categories: Open Source

5 Year Anniversary

Wed, 01/27/2010 - 20:15

That's right. Today we can all celebrate qooxdoo's 5th anniversary. :-)

While it is hard to exactly determine the actual start of a project like qooxdoo, January 27th, 2005 was the day the project was registered at SourceForge, the world's largest OSS development web site. This first official appearance certainly qualifies as the "birthday" of qooxdoo.

As a true open source project qooxdoo used public code repositories right from the start. Everyone that followed the progress of the framework over time, either in a passive or active role, saw some very remarkable steps: after the first official release in early 2005 there have been a total of 27 stable releases of qooxdoo, including some ground-breaking and really innovative packages.

When talking about 2005, it is interesting to note that qooxdoo started a month before the term "AJAX" was even coined. While nobody could really foresee all the hype about Ajax, there was already a clear understanding of the potential if not power of JavaScript and modern, cross-browser applications. And a need for qooxdoo as an advanced application framework to make that vision a reality.

It is our pleasure to thank all the people that kept believing in this vision and made it such a fascinating reality! The support by 1&1 as the initiator and maintainer of the framework is indispensable, employing us as a team of full-time core developers. Working with fellow committers and a large number of contributors is a great every-day experience and always a source of inspiration. You really help making this an outstanding JavaScript framework. Last but not least many thanks to all of you who create impressive applications with it, but don't forget to let us know about weak points to address, and also to tell others about the strong points and the fun in working with qooxdoo.

Lets make it another 5 years of innovation, success and fun of developing and using qooxdoo!

Categories: Open Source

The week in qooxdoo (2010-01-22)

Fri, 01/22/2010 - 21:55

Here comes another weekly status report. This time it is a rather short one, since we were quite busy with bugfixing, roadmap planning and various other stuff.

Native JSON support

Last week we have landed a commit, which adds native JSON support to qooxdoo. There is a new class qx.lang.Json, which has exactly the same interface as the JSON object defined in the EcmaScript 5 specification. All new browsers like Firefox 3.5, Internet Explorer 8, Opera 10.5 or Safari 4 support it natively. In browsers without native JSON support a modified version of Douglas Crockford's json2 is used. This is great news because parsing and serializing JSON is a lot faster in those browsers.

Playground enhancements

Just in case you missed it: There is a detailed blog post about some experimental enhancements to the Playground.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

That's it for this week, see you around next time.

Categories: Open Source

Playground enhancements

Fri, 01/22/2010 - 21:44

As reported in last week's blog post, we worked further on the features of the Playground, especially on the gist support.

GitHub describes gists as a "[...] simple way to share snippets and pastes with others. All gists are git repositories, so they are automatically versioned, forkable and usable as a git repository". The main idea for the Playground is to be able use those gists as custom code examples.

gist

The implementation of that feature was harder than we thought, because the API for accessing gists is not that well documented and accessible. The easiest way to get a clean API for it was to implement a custom YQL table for accessing the gists. With that table, we can now access the gists using the YQL data store, which is already included in qooxdoo. So getting the gists into the playground is just some lines of qooxdoo code. But getting the gists from the Playground back to GitHub is another problem we decided not to solve, because it would be a lot of work with not that much of an added value.

For accessing the gists in the user interface, we added a special gist menu to the Playgrounds toolbar, which has some special features: First, you can easily enter you own GitHub user name and load your own gists (if you don't have your own gists already, try "wittemann" to to see it in action). You might not want to have all your gists listed in the playground, because not all of them are qooxdoo code! Thus we added a filter which limits the gists shown according to a [qx] in each gist's description. With that, you can easily "tag" your gists as qooxdoo snippets.
As already mentioned, we did not implement an integrated editing feature for gists. But of course, adding as well as editing a gist should be as easy as possible. To satisfy the first requirement we added a button for adding gists to the menu, which opens the GitHub page for adding new gists. The same applies for editing, every gist listed has an additional button, which opens the edit page of that gist on GitHub.

If you use the Playground on a daily basis, you don't want to type in your user name every time. We also thought of that and added cookie support to the Playground. The gist user name, gist filtering and the toggle state of the Playground's syntax highlighting are stored in a cookie and restored every time you start the Playground.

Last but not least, the gists also made it into the URL. Adding #gist=id to the Playground URL will load the gist with the given id on startup. That makes it easy to share code snippets stored on GitHub, even for all versions of Internet Explorer, which have problems handling the very long URLs the Playground usually uses for code sharing.

To wrap it up, we added a couple of new features to the Playgorund:

  • bit.ly support for URL shortening
  • Loading, filtering and using gists
  • Loading gists by URL parameter
  • Cookie support for storing some preferences

Give it a try in the latest devel version of the Playground. This devel snapshot may not be all too stable yet, and the recently added features are still experimental. But we wanted to let you try out the features early. Please tell us what you think of the new features and enhancements! Hope you like it.

Categories: Open Source

The week in qooxdoo (2010-01-15)

Fri, 01/15/2010 - 17:44

Welcome back to the first weekly status report in 2010. Of course, this series of activity reports continues to allow you to closely follow the project and its progress.

Applications Demobrowser

You might have already noticed the filter capacity of the demobrowser. This filter enables you to search for demos with a specific name and some predefined tags. We defined a new search criterion this week by adding the qooxdoo classes that are used by any specific demo application. Now you can search for every demo using qx.ui.form.TextField for example. You can also filter for namespaces or parts of namespaces. If you are interested in all classes of the qx.bom package, just use a 'qx.bom' filter so see every demo using it.

Playground

We took the last week to refactor the whole playground code. This gives us now a solid base for further features of the playground. The first of the new features is an integration of bit.ly, the URL shortening service. The playground now features a button which brings up a shortened URL for the current playground URL including its hash. This gives you the chance to share your code snippets easily without the need to bother with the very long URL containing the playground example code.

The next task is to support gist.github.com. We already started the implementation and hope to have it ready for the next weekly.

Bugs

For a complete list of bugs fixed during the last working week, use this bugzilla query.

Generator Configuration

An new and experimental configuration feature has been added: the use of a user-specific profile directory. Currently, the generator will look for a file <user-home-directory>/.qooxdoo/generator.json, "user-home-directory" being the platform-specific path to the current user's home directory (ie. what Python's os.path.expanduser("~") evaluates to). On *ix platforms, this is equivalent to the shell's "~" directory, on Windows platforms something of the form C:\Documents and Settings\<username>.

If the generator.json file is present, it will be automatically included as the first include file in the current configuration file. This way, you can inject generator settings into all jobs you run in various applications. The syntax of the generator.json file is that of a normal qooxdoo configuration file. You can e.g. enable extensive logging for all source builds, or force a format:false for all build scripts.

Performance

Work has been done to improve the re-use of cache objects during build runs of the generator. For one thing, there was an inconsistency in the way syntax trees were written to the cache, so that same trees were calculated and written twice, rather than re-used. This has been fixed.

Another improvement concerns builds with variants. In general, the syntax tree and (consequently) the dependency information of a class is affected by the variant set that is to be build, so this information is stored in the cache under a key specific to the variant set. But what if a class uses only a subset of the variant keys in the current set (or doesn't use variants in its code at all, for that matter)? Then its tree and dependency information could be re-used for several variant sets where changes in the value of a variant doesn't affect the specific class. Exactly this kind of re-use has now been implemented, resulting in less cache space and less run time requirements (as e.g. only 33% of the framework classes use variants code at all).

Finally, for the calculation of image information (e.g. image sizes), cache access has been optimized, so the generated information is written less often to the cache. For applications using a lot of images (i.e. a couple of thousands), this was a hot spot, too.

All optimizations together can lead to remarkable speed gains for an initial build run (empty cache) in certain scenarios, like more than 50% for a project that creates several variants with lots of graphics.

Community QxWT

Along with the release of qooxdoo 1.0 a new parallel project QxWT has been made available. Kudos go to Tom Schindl from BestSolution.at, who did a fantastic job of creating a GWT-wrapper for qooxdoo: QxWT exposes most of the qooxdoo-JavaScript-API to GWT-Java-developers. Just like qooxdoo is a JavaScript-only application framework (without requiring HTML, CSS or DOM knowledge), think of QxWT as a Java-only version of qooxdoo, based on the Google Web Toolkit.

There has been some more progress since the original release, and Tom posted a series of more detailed articles, #1, #2, #3. If you're heavily into Java or have been using GWT already, you should check it out.

That's it for this week, see you around next time.

Categories: Open Source

qooxdoo on Stack Overflow

Thu, 01/07/2010 - 13:11

Before the 1.0 release we did a survey on our mailing list about "Your favorite aspects of qooxdoo". One of the often mentioned aspects was the support by the community on the mailing list. Many of you were quite happy with it, but not everyone likes mailing lists and some people refuse to register on the list for different reasons.

So we want to test an extension of community support channels. You have certainly heard about, maybe already used Stack Overflow, one of the most popular programming Q & A sites on the web. From Wikipedia: "Stack Overflow is a website featuring questions and answers on a wide range of topics in computer programming. The website features the ability for users to ask and answer questions, and, through membership and active participation, to vote questions and answers up or down and edit questions and answers in a wiki fashion. Users of Stack Overflow can earn reputation points and “badges”".

As a possible alternative to the regular mailing list, some people might prefer to ask qooxdoo-related questions on Stack Overflow, as it might have some advantages:

  • The system shows - during typing a question - already asked questions, which might have an answer to your question. This can bring you to a solution without even asking.
  • Stack Overflow uses tags to categorize all questions. qooxdoo has its own tag ("qooxdoo", of course) which gives you the ability to tag your questions and additionally subscribe to a RSS-feed containing all qooxdoo-tagged questions.
  • You can vote answers to show which was the most suitable answer for you. This can also help to find a solution fast.

But don't worry, we are not planing to replace the mailing list with Stack Overflow. This is just a test for a parallel usage of the two systems. If you like to continue to ask your question on the mailing list, that's just fine as it is the primary qooxdoo community support channel. But if you haven't seen Stack Overflow (or are an active user there already for non-qooxdoo questions), give it a try. It's worth looking! Let us know what your experience and preference is regarding the existing mailing list and/or Stack Overflow, and what you think about such alternative communication channels.

Categories: Open Source

The year in qooxdoo (2009)

Thu, 01/07/2010 - 12:37

On behalf of the qooxdoo core team: "Happy New Year!" to everyone, welcome back in 2010.

The last year has been a very exciting and successful one for qooxdoo. Many of you already follow the project closely, for instance by reading the weekly status reports, being an active member on the mailing list or in bugzilla, providing and maintaining contributions, and in many other ways. Thanks to everyone for the ongoing support and to make it possible to ship qooxdoo 1.0 end of last year.

This major 1.0 release has been well-received and got some good press and attention. If you are a new user or returning to qooxdoo for migrating or continuing with existing apps, we hope you enjoy all the built-in features of this comprehensive and practical package. If you have questions or suggestions, let us know.

If you have some good user experience with developing qooxdoo apps, let others know as well (personal blog, twitter, etc.). Particularly the more experienced qooxdoo users are also asked to add to our own activities and keep promoting qooxdoo on various channels (real-life examples, blogs, magazines, conferences). Please get in touch with us to get some input, help or heads-up for those activities, just don't forget to let us know about it to coordinate some efforts.

We are looking forward to working with you on making 2010 a great year for qooxdoo, its wide-spread adoption and its ongoing progress.

Categories: Open Source

qooxdoo 1.0 released

Thu, 12/17/2009 - 20:18

One of the most comprehensive JavaScript frameworks is finally available in version 1.0. qooxdoo is a mature and popular solution for creating desktop-style web applications. It has a successful track record after almost five years of development that includes a number of important milestone releases. Backed by 1&1, the world's largest web host, the professional development team and an active open source community established a framework that is feature-rich, well-tested and fast.

The brand new Showcase application provides a perfect introduction to qooxdoo 1.0 as it highlights many of its GUI features: advanced widgets like virtual tables or trees, an advanced data binding layer, full internationalization support, a brand new html editing component and custom theming:

qooxdoo Showcase

Developers can fully concentrate on creating their apps by leveraging object-oriented JavaScript in a very elegant, yet familiar way. No HTML, CSS or DOM knowledge is required. qooxdoo applications run in all major browsers (Internet Explorer, Firefox, Safari, Opera, Chrome) without any difficulty with cross-platform issues. To get an idea of what it's like to work with typical qooxdoo code, an interactive Playground lets you experiment with various live demos.

There is much more offered in qooxdoo, however, than just a large set of widgets, powerful layout managers and virtually unlimited theming capabilities. As a full-fledged application framework, it comes with an integrated, platform-independent tool chain that covers the entire range of app development and deployment - code validation, JS compiling and linking, compression and optimization, just to name a few. Other built-in tools allow for easy unit testing, automated GUI testing, searchable API reference, or cross-browser debugging a la Firebug. Mastering large-scale JavaScript applications is greatly facilitated by build process features such as automatically combined images ("sprites") or transparently breaking up an app into various parts that are loaded on-demand.

Feature set, design and quality of qooxdoo also make it a popular foundation for other frameworks. If you are interested in Java-based programming models that use qooxdoo internally, you may want to check out the Eclipse Rich Ajax Platform (RAP) or the new QxWT project, which integrates qooxdoo 1.0 with the Google Web Toolkit (GWT), and has been officially released today as well.

For more information about qooxdoo 1.0 please see the detailed release notes. See the online demos for qooxdoo in action. Download the qooxdoo SDK, get started and have fun creating desktop-style apps for all browsers and platforms.

Thanks to all the people involved, the core team, fellow committers and contributors, testers, users, partners and 1&1 for their fantastic job and great support!

Categories: Open Source