Archive for the ‘Libraries’ Category

jQuery Profile Plugin

Thursday, May 1st, 2008

Yesterday I was profiling a page that used jQuery. The page took a long time to initialize. Firebug Profile (a great tool) told me that the time was in jQuery, but that wasn’t much help – the page initialization code had a lot of calls to jQuery, to bind functions to various page elements, and most of them were harmless.

Hence, jQuery.profile. Stick this in your page, call $.profile.start() to start profiling calls to $(selector), and then $.profile.done() to stop profiling and print out something like this:


Read the rest of this entry »

Minimizing Code Paths in Asychronous Code

Sunday, April 20th, 2008

Have you ever written a function that looks like this?

[code language=”javascript”]
function requestProductDetails(id, k) {

var value = gProductDetailsCache[id]; if (value) k(value) else ajax.get(’/product/’+id, function(data) { gProductDetailsCache[id] = data; k(data); });
}
[/code] requestProductDetails calls its callback with the product details, which are stored in a cache. Since it might need to request this information from the server, it has to “return” it by passing it to a callback; in order to present a uniform API whether or not the product is cached, it “returns” the data this way whether it came from the cache or not.
Read the rest of this entry »

A Mock for {set,clear}{Timeout,Interval}

Sunday, April 20th, 2008

Here’s a potential JSSpec spec for Sequentially.trickle.map:

[code language=”javascript”]
describe(‘Sequentially.trickle.map’, {

‘should apply to all the elements’: function() { Sequentially.trickle.map( [‘a’, ‘b’, ‘c’], function(x) { return x + 1 }, 1, function(result) { value_of(result.join(’,’)).should_be(‘a1,b1,c1’); }); }); }
});
[/code]

This doesn’t work. The problem is that Sequentially.trickle.map is asynchronous (it defers most of its computation – including the invocation of the callback – via setTimeout). This means that should_be isn’t called until after the spec has returned. If it succeeds, this isn’t a problem, but if it fails, JSSpec can’t associate it with the failing spec – worse, JSSpec will have already have marked it successful.


Read the rest of this entry »

Conquering the Busy Cursor with Sequentially

Sunday, April 20th, 2008

What’s wrong with this function? (Hint: it’s meant to execute periodically on a JavaScript page.)

[code language=”javascript”]
function updateExpirationText() {

var now = new Date; products.forEach(function(item) { var expiresDate = item.expiresDate || Date.parse(item.expires), remaining = expiresDate - now, text = remaining < 0 ? ‘expired’ : msToDuration(remaining); $(‘item-’ + item.id + ’ .time-remaining’).text(remaining); });
}
[/code]

It’s a trick question. Maybe nothing’s wrong. But if products can get very long, or if the msToDuration is very slow, you’ve locked up the UI for a long time. At best, this makes for sluggish response; at worst, the page that contains this will trigger a “script running slowly” error, and the user will likely abort all the JavaScript on the page.


Read the rest of this entry »

DB Content Rails Plugin

Thursday, April 17th, 2008

The DB Content Rails plugin adds tasks to save and restore database content.

Usage

[code]

– dump the development database to db/archive/development-content.sql.gz
rake db:content:dump – load the dumped database, and apply any necessary migrations
$ rake db:content:load – dump the production database to db/archive/production-content.sql.gz
$ RAILS_ENV=production rake db:content:dump – save the development database to db/archive/{timestamp}.sql.gz
$ rake db:content:save – save the (compressed) database to my-data.sql.gz
$ rake db:content:save FILE=my-data.sql.gz
Read the rest of this entry »

JCON: Ruby Gem for JSON type conformance

Thursday, April 17th, 2008

JCON (the JavaScript Conformance gem) tests JSON values against ECMAScript 4.0-style type definitions
(PDF) such as string?, (int, boolean), or [string, (int, boolean), {x:double, y:double}?].

Usage

[code language=”ruby”]
type = JCON::parse ”[string, int]”
type.contains?([‘a’, 1]) # => true
type.contains?([‘a’, ‘b’]) # => false
type.contains?([‘a’, 1, 2]) # => true
[/code]

JCON also defines an RSpec matcher, conforms_to_js:


Read the rest of this entry »

Three Small JavaScript Libraries

Tuesday, April 15th, 2008

Three small libraries, that I carry with me from project to project:

Fluently – Construction Kit for Chainable Methods

With Fluently, you can do this:

[code language=”javascript”]

var o = Fluently.make(function(define) { define(‘fn1’, function() {console.info(‘called fn1’)}); define(‘fn2’, function() {console.info(‘called fn2’)}); define(‘fn3’, function() {return 3}); });
[/code]

to define an object with chained methods, that can be invoked thus:

[code language=”javascript”]

o.fn1().fn2() // calls fn1 and then fn2 o.fn2().fn1() // calls fn2 and then fn1
Read the rest of this entry »

JavaScript Fu Rails Plugin

Monday, April 14th, 2008

JavaScript Fu extends Rails with a few facilities to better integrate JavaScript into Rails development:

1. The notes and statistics rake tasks compass JavaScript files in the public/javascript directory:

[code language=”bash”]
$ rake notes
public/javascripts/controls.js:

* [782] [TODO] improve sanity check
[/code]

[code language=”bash”]
$ rake stats

| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
[...]

| JavaScript | 7287 | 6322 | 0 | 0 | 0 | 0 |
[...]
[/code]

2. The call_js RSpec matcher asserts that a string or response contains a script tag, that contains JavaScript that calls the named function or method:


Read the rest of this entry »

FlashBridge: proxying Flash <-> OpenLaszlo

Sunday, April 13th, 2008

I’ve updated my OpenLaszlo utility grab-bag to make browser <-> applet communication even easier. How easy?

Proxies

Put this in your browser JavaScript:

[code language=”javascript”]
var gObject = {

f: function() { console.info(‘gObject.f’, arguments) }, g: function() { console.info(‘gObject.g’, arguments) }
};
[/code]

And this in an OpenLaszlo applet:

[code language=”javascript”]
var gObject = FlashBridge.createRemoteProxy(‘gObject’, [‘f’, ‘g’]);
gObject.f(1, 2);
gObject.g(3);
[/code]

When you run the applet code, it prints this to the browser console:


Read the rest of this entry »

What I didn’t get to

Monday, December 31st, 2007

Here are some of the weekend projects that I didn’t finish this year. These aren’t good enough to put on my project list or my sources page. Some of these aren’t even working, and some of them I might not finish at all (most of my weekends are spoken for). And some of them I can’t bear to look at (I’m not proud of the code, and don’t want to be judged by it…), but I’m making myself put them out there anyway. I feel bad for the neglected little things, trapped on my hard drive, and I’d like to let them see the sun, even if just briefly before they flicker out and die.


Read the rest of this entry »