Thursday, May 29, 2008

Yahoo! User Interface Library (YUI)

As I previously posted, I've switched to the Yahoo! User Interface Library (YUI).

Some key links:

I think YUI is a great library for many of the same reasons I had liked Ext JS:

YUI includes a number of useful and versatile UI components. The ones I use the most are DataTable and Calendar.

A non-UI component that I've been quite pleased with is the YUI Loader Utility. Instead of including the entire YUI library across an entire web site, it allows for safe, easy, and relatively efficient partial loading, including reliable, sorted loading of dependencies.

Unlike Ext JS, there is excellent, comprehensive documentation available by component. Not only the API docs, but "getting started" pages complete with numerous examples and notes as well. In addition to all this, there is also the forum and blog.

There are a few bugs and feature requests that I've submitted on YUI's SourceForge trackers that may be of interest.

I have some additional YUI-related notes to share that will follow as future posts. Just watch for the "Yahoo UI Library" label.

Ubuntu Hardy Heron under VMware

I just got the latest Ubuntu Linux distribution (8.04, "Hardy Heron") working quite well under VMware.

I found a few issues during the process specific to running under VMware that required some attention. Google helped me find the solution for the first two both on Peter Cooper's blog:

Mouse scroll wheel

First, the scroll wheel on the mouse wasn't working. Not so surprising, as I've typically had various mouse problems in the past working with Linux versions under VMware. The solution Peter found was to add the following highlighted three lines in "/etc/X11/xorg.conf":

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
Option "CorePointer"
Option "Device" "/dev/input/mice"
Option "Protocol" "ImPS/2"
Option "Buttons" "5"
Option "ZAxisMapping" "4 5"
EndSection

For the original with full details, see How To Enable Mouse Wheel Scrolling in Ubuntu Hardy on VMware Fusion (Peter Cooper, 2008-04-26). While written for VMware Fusion, the solution works equally well for the free VMware Server.

VMware Tools

Next were some issues getting the VMware tools to install properly. The basic GUI vmware-toolbox worked, but no precompiled modules for the file sharing or network driver could be found for the current kernel. When it attempted to compile appropriate ones, gcc would error out with "conflicting types" messages.

This solution is a little more lengthy. Peter's instructions work quite well: How to Install VMware Tools on Ubuntu Hardy 8.04 under VMware Fusion (Peter Cooper, 2008-04-26).

The only alteration I made is using the most recent version of open-vm-tools from SourceForge - 2008.05.15 as of this writing. Again, this works just as well for VMware Server as for VMware Fusion, other than that VMware Server doesn't have support for the "Shared Folders" feature.

Unnecessary Services

Another optimization that can be made under VMware is disabling a number of services that don't function / simply don't exist under VMware.

Services can quickly be disabled using the "Services" applet under the System / Administration menu. The services I disabled:

  • Bluetooth device management (bluetooth)
  • CPU Frequency manager (powernowd)
  • Power management (acpid)
  • Power management (apmd)

Boot Details

Another non-VMware related change I wanted was to see more details during the boot process, which I was used to from previous versions.

Part of the challenge was finding the proper search terms. Ubuntu uses "Usplash" (see also USplash on help.ubuntu.com, and somewhat related to "Splashy") as the default "Bootsplash".

The best write-up I found related to this is Quickzi: Get rid of the Ubuntu splash screen during boot (author unknown, 2007-10-27, foogazi.com).

Essentially, to adjust the process permanently (at least until the next kernel upgrade), the file to edit is "/boot/grub/menu.lst". Find the "kernel" line in the config you are booting with and remove the "quiet" and/or "splash" options. My preference is to leave "splash" and just remove the "quiet", which scrolls the boot progress on the lower portion of the splash. (I wouldn't recommend removing "splash" and leaving "quiet".)

"Open Terminal" on desktop/context menu

Previous Linux distributions I had included a "Open Terminal" option on the desktop/context menu, and I found myself using it quite frequently and missing it in Ubuntu. To obtain this functionality, install "nautilus-open-terminal".

Monday, May 12, 2008

JavaScript namespace function

As a follow-up to my "Respecting the JavaScript global namespace" post, here's a function that can be used to quickly and easily create namespaces:

(Updated to use a global function instead of extending the String prototype.)

var namespace = function(name, separator, container){
  var ns = name.split(separator || '.'),
    o = container || window,
    i,
    len;
  for(i = 0, len = ns.length; i < len; i++){
    o = o[ns[i]] = o[ns[i]] || {};
  }
  return o;
};

Here's the same code, compressed using YUI Compressor:

var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};

Ideally, this function would be assigned to some other object (to respect the global namespace), unless accepted as a standard function as mentioned above.

See also:

Unlike the "Namespacing made easy" post, this solution doesn't require Prototype. This solution also prevents overwriting existing objects and returns the created "namespace".

Example of use:

namespace("com.example.namespace");
com.example.namespace.test = function(){
  alert("In namespaced function.");
};

Or, as one statement:

namespace("com.example.namespace").test = function(){
  alert("In namespaced function.");
};

Either is then executed as:

com.example.namespace.test();

Update (2008-05-13):

The concern was raised that the "len" variable in my for-loop is being created in the global scope / "namespace", which would contradict the entire purpose of this post! :-)

Fortunately, according to developer.mozilla.org, all variables declared after "var" are created within the same scope - and if declared within a function, the scope is that current function.

Here's my "test case". Use Firebug. First check that neither the "i" nor "len" variables already exist. Then run the following code, and note that neither variable is created in the global scope.

(function(){
  for(var i=0, len=0;false;){};
})();

Compared to this version, which does populate "len" into the global scope:

(function(){
  len = 0;
  for(var i=0;false;){};
})();

Maybe surprisingly, this makes "len" local again, even though it is assigned to before being declared with "var". This is because JavaScript does not have block scope.

(function(){
  len = 0;
  for(var i=0, len=0;false;){};
})();

This general practice is documented at http://www.prototypejs.org/api/array, where it is also explained how caching the length property is an aid to performance. (Though for the stated purpose of creating namespaces, which will probably only be handling single-digit lengths for the majority of the cases, the savings will be practically zero.)

Farewell, Ext JS

Though I was previously impressed with the Ext JavaScript library, it's time to move on.

Everything I previously wrote about Ext JS is still true. It is a very capable, comprehensive, well-written JavaScript library. Unfortunately, the management of the project doesn't at all seem to live up to the same standards.

There were always a few minor ongoing issues, which still exist as of this posting. One is the lack of bug / feature request trackers, e.g. Bugzilla. Another is the restriction of read-only access to the Subversion source code repository to only premium (paying) members.

The main issue, however, is the license change that was announced with the release of Ext JS 2.1 on 2008-04-21. Ext JS was always dual licensed under both the LGPL license as well as a commercial license. This meant that anyone was free to do almost anything with the library. The only recognized restriction was using Ext JS in a "software development library or toolkit", when the commercial license would have been required.

Introducing the GPL

With the license change, the dual licensing model still exists, but uses GPL instead of LGPL. I and many other users didn't see this as an issue for our uses. Unfortunately, there was little more than confusion on Ext's "License Change?" forum, which as of this writing topped 650 posts and 61,000 views.

I generally support open source. Even corporate development commonly makes uses of open source software, licensed under either LGPL, GPL, or dozens of other "open source / free" licenses. The one restriction with using GPL-licensed software is that if the parent application is to be redistributed, the source code usually has to be redistributed as well. I don't have a problem with this for any of my personal applications.

While many businesses work with proprietary applications that simply are not meant to be shared, they can even utilize GPL-licensed software as long as their application is not "redistributed". For companies who only develop and host a web site rather than developing and selling software, it would seem that there would be not redistribution and no GPL requirements. Even Microsoft uses a GPL-licensed JavaScript library on their web site, and they don't appear to be under any requirement to release any source code.

The GPL license makes a distinction between propagate and convey:

To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

From all definitions / explanations I've seen, simply hosting a web site (utilizing Ext or whatever) would be classified as propagation, not conveying. To convey, one would have to do something similar to zipping up the web site and redistributing it for others to host as well (regardless of terms).

Ext Indecisions

This is where everything gets muddy really fast with Ext.

On 2007-03-27, one of the lead Ext developers agreed with the statement that "For the purposes of Ext, hosting an application is not considered distribution, so the license does not apply".

Less than a month later, the Ext team then claims that by simply hosting an Ext-enabled web application, the application is being conveyed as well as propagated. They claim that all the source for all related JavaScript code in the application would then also be covered by the GPL, and must have the source code be made available. Since JavaScript is an interpreted rather than a compiled language, the argument could be made that this requirement is already fulfilled - by running the application, the source is already provided. However, the same lead developer further stretches a claim that not only must the sources be made available for the client-side code, but portions of any server-side code as well.

Please understand - the Ext authors probably have the right to distribute Ext JS under whatever license they choose. The issue is that they are claiming the GPL license, but requiring different terms. As I and others have suggested, it seems what the Ext team really wants is the AGPL license. From http://www.fsf.org/licensing/licenses/:

Its (the AGPL) terms effectively consist of the terms of GPLv3, with an additional paragraph in section 13 to allow users who interact with the licensed software over a network to receive the source for that program. We recommend that developers consider using the GNU AGPL for any software which will commonly be run over a network.

Again, if Ext, LLC does not wish to license Ext JS under either the LGPL, the GPL, or the AGPL, they are free to create their own license. Just don't claim to honor the GPL and then dispute the terms.

To clarify, I don't see any issues using Ext JS in an "open source", GPL'd application. However, there is so much confusion over the license terms that I don't see how any business could risk playing this license game, short of paying for the commercial license (which still leaves unanswered questions and concerns). Additionally, why choose the commercial license when other genuinely-free alternatives are readily available?

Related Posts

Here are a few other related posts on this subject:

Switching to YUI

As I posted to the Ext "License Change?" forum, I've since switched to the Yahoo! User Interface Library (YUI). Beyond being BSD licensed, YUI has:

  • equally capable event listeners/management,
  • official & structured bug / feature request / patch trackers on SourceForge,
  • no forum threads restricted to premium/paying members,
  • commitment to make the SVN repository publicly available,
  • and fixes / inclusions of many of the bugs / enhancement requests reported here against Ext JS without action.

I was using Ext JS only for 2-3 odd bits of functionality I found in it almost a year ago. I didn't see them in YUI at the time, either because they've since been added, or that I just missed them the first time around (more likely).

Over the past few weeks, I've found that working with YUI performs better, and is actually easier and faster to work with. (Yahoo! User Interface Library (YUI))

YUI isn't the only alternative out there. The Dojo Toolkit is one other that I've been considering.