Debugging JavaScript in Adobe AIR apps
Several months back I switched from using Notepad++ to Eclipse-based Aptana Studio to develop an Adobe AIR desktop client for work & have been pretty happy with Aptana other than for the huge amount of memory it gobbles up. Late last week the Adobe AIR Development Plug-In for Aptana came out of beta & is great news for anyone developing HTML/JavaScript-based AIR apps (as opposed to Flash/Flex-based).
One of the drawbacks in developing HTML/JavaScript-based Adobe AIR applications is the lack of debugging tools. It doesn't help that AIR's error exception will often output an "undefined at undefined" error message in the system console when a JS error occurs, without any stack trace, leaving you to guess where it actually occurred. This is fine for a small application, but when you have tens of thousands of lines of JavaScript code you'll often be left banging your head on the desk trying to trace down the error in the code.
This screencast from Aptana better illustrates the new features. Be sure to check it out if you're using Aptana Studio and/or were looking to give it a try!
jQuery tips, migrating from jQuery’s tablesorter to Ext JS’ GridPanel
I ran across this post which has some good jQuery tips.
Speaking of JavaScript frameworks, I've been spending the last couple weeks ramping up on Ext JS since it comes with a very slick grid component (actually all of the components it comes with are very, very slick). I've been using the jQuery tablesorter plugin for a grid layout used in one of my projects, but it's missing a couple of features I need such as grouping & resizable columns, which the Ext JS grid component has.
Migrating to the Ext JS grid has been interesting since I've had a chance to see the pros and cons of each framework and the different approaches taken to build a grid. The jQuery tablesorter plugin operates on an existing HTML table (or one you create in JavaScript and append to the DOM, which is my case) and converts it to a sortable grid, whereas the Ext JS grid uses a datasource such as a JavaScript array, JSON or XML file, etc. and uses that to build the grid.
Ext JS is quite verbose unlike jQuery (unless you want the verbosity -- note: if it's not obvious, that is a April Fool's joke
), but I do like how Ext JS is a complete framework with a lot of included widgets that all work well together, no doubt because they all are part of the distribution.
jQuery on the other hand is very compact and the syntax is similarly compact (which I love). The core distribution is kept as tiny as possible, and additional functionality is added via plugins such as tablesorter.
The existing implementation of my grid uses jQuery's tablesorter, contextmenu, blockui, cluetip, and metadata plugins, whereas to achieve the same functionality in Ext JS and to add new features such as grouping & resizable columns, I am using the following Ext JS objects: Ext.grid.GridPanel, Ext.grid.GroupingView, Ext.data.GroupingStore, Ext.data.JsonReader, Ext.QuickTip, Ext.menu.Menu, Ext.MessageBox, Ext.Viewport.
It's not an apples to apples comparison since some of the Ext JS objects I listed above are used to load the JSON data into something the grid can use, whereas the JSON data was a JS object literal previously and I manually iterated over it to create my table which tablesorter then coverted into a grid. Others like grouping (via Ext.grid.GroupingView) is a new feature that I wanted to implement & wasn't available in tablesorter or any other jQuery plugin that I could find at the time. If I was to break it down to replicating my grid's functionality in jQuery over to Ext JS, it'd be the following objects: Ext.grid.GridPanel, Ext.QuickTip, Ext.menu.Menu, Ext.Messagebox.
Each framwork has its pros and cons, but I am glad though that they both work well together (both were designed with this in mind). That's a good thing, as I am using both: I've migrated the grid to use Ext JS' GridPanel, but am still using jQuery to do a couple manipulations to the grid. I can have my cake and eat it, too (though I will see if I can migrate all of the grid functionality over to Ext JS to keep things simpler)!
Preventing xulrunner from caching browser files
Leap day post!
The xulrunner app I developed hits a web server running on localhost to serve up its main interface, via XUL's <browser> tag (similar to HTML's IFRAME tag). There are instances where the pages & their dependencies should not be cached. Adding the various HTML <meta> tags (expires, pragma, cache-control) prevents the HTML pages from caching, but we really wanted to prevent .js files from being cached since we change the content dynamically in some of them so we didn't want to return stale data. If we were running Apache, we could just set some HTTP expires headers via mod_expires but since we needed to keep the app installer as small as possible, we were using a much more lightweight web server.
I first tried the following xul prefs:
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true);
which didn't work. I was seeing .js files being saved to xulrunner's cache (on WinXP, it was in the C:\Documents and Settings\[User name]\Local Settings\Application Data\[App Vendor]\[App Name]\Profiles\* folder)
Then it dawned on me that since we were using the XUL <browser> tag, it essentially loads up a web browser to display the content. Since that meant it was essentially Firefox 2 loading up, I looked in Firefox's about:config for caching-related preferences and voila:
pref("browser.cache.disk.enable", false);
I added that to xulrunner's prefs.js & no more caching
upgrading from apache 2.0.x to 2.2.x
Upgraded apache from 2.0.59 to 2.2.8 yesterday and my htaccess rules broke. I searched around & discovered that one of the things that changed with 2.2.x was a renaming of the various apache auth modules. Had to put in the following to my httpd.conf to get things to work again
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_user_module modules/mod_authz_user.so
Other than that, everything else was easy breezy.



