Fleegix.org

WTF, global "item" symbol in IE

about 1 month ago / 0 Comments

Like any self-respecting Web UI developer, I have a lovingly cultivated hatred of Internet Explorer.

IE and I go way back -- I've been developing for IE since version 3, and I have a fairly well evolved sense of sense of what breaks there. So it's always an occasion for rejoicing when I trip over something strange and new.

Some recent code-refactoring breakage (I moved a code loop and left a variable undeclared, sweet!) unearthed this little gem: IE (both 6 and 7) seems to have a built-in global symbol called item.

It reports its type as 'string', but appears to be an invokable function -- calling it with a random param passed yields the error: "Member not found":

alert(typeof item); // Alerts 'string', expected 'undefined'
item('foo'); // Throws 'Member not found' error

I'd love it if someone could enlighten me -- WTF is this 'item' thing?

It looks like some kind of vestigial Active Scripting organ -- I did find a reference to a default item method of WshArguments in Windows Script Host, but nothing to explain, what, if anything it actually does in IE.

As a side note, IE6 is older than all my kids. And they're about to graduate college. Okay, not really -- the oldest is in first grade. But still.

0 Comments

Kerblooey accessing DOMException location property

about 1 month ago / 0 Comments

This past week I ran afoul of an interesting bug in Firefox 3 trying to serialize some stuff with fleegix.json.serialize.

Iterating over the properties of the DOMException (which for some inexplicable reason isn't an instance of a generic Error, but that's another rant) reveals the existence of a a location property. But sadly, much like Nigel Tufnel's Fender Bass VI, this property is not to be touched, or even looked at -- if you actually attempt to access the property directly, you get the wonderfully intuitive error, "Permission denied to create wrapper for object of class UnnamedClass."

As it turns out, this bug has already been reported -- it's Firefox bug 436953.

0 Comments

Fleegix.js 0.5.0 released

3 months ago / 0 Comments

Okay, so the docs are all polished up, and tarballs/zips are freshly cooked, piping hot from the oven, so here it is, Fleegix.js 0.5.0. Mmm, tasty JavaScript.

The code name for this release is "Palace of ECMA Supremacy." Any questions or concerns regarding this release must include the code phrase, or they will not be responded to. Just kidding. Probably.

New features in this release include:

In addition to the new features, a vast number of bugs lost their lives in this latest release. As Hernando says, "The bugs are enormous. There are an infinity of bugs." Feel free to peruse the ChangeLog for a roll call of the deceased, and details on the new-feature work.

0 Comments

Fleegix.js, the tip of the JavaScript long tail

4 months ago / 0 Comments

In a surprising recent development, Fleegix.js appears in the Six Revisions article, 10 Promising JavaScript Frameworks, showcasing "10 alternative and capable JavaScript frameworks/libraries to explore."

Fleegix.js came in at number 10 on the list -- and frankly given its status (er, lack of status?) as a bit player on the grand Ajaxy-toolkit stage, it's pretty cool to see it showing up on any lists at all.

The Six Revisions article has gotten a mention on Ajaxian, in a post called The JavaScript Long Tail -- very nice to see Ajaxian giving some love to what they describe as "new/up-and-coming frameworks."

Actually, Fleegix.js is not new -- some of the code has been around since about 2002 -- but "up-and-coming"? Yeah, I like the sound of that.

In reality, I think biggest value proposition in Fleegix.js for JavaScript developers is in its plugins -- like the Olson-timezone-enabled Date in fleegix.date.Date, the sortable Hash in fleegix.hash.Hash, or even the new embbeded JavaScript templates in fleegix.ejs -- all of which can be easily plugged into existing frameworks.

I would love to see more people using the code, and hacking on it as well. There is a Lighthouse app for bug reports. If you're interested in pitching in, the Fleegix.js site has a page on how to contribute.

Be looking for a new release in the coming week. But for now, anyway, I'm happy to see Fleegix.js occupying a spot at the "tip of the JavaScript long tail."

0 Comments

JSLint in Vim through Lynx

4 months ago / 0 Comments

I recently saw a nice blog post by Mike Cantelon on integrating JSLint with Vim, and since I spend most of my days hacking JavaScript in Vim, it was a no-brainer for me to want that integrated-JSLint awesomeness, and right now, dammit.

Of course I already had SpiderMonkey (sudo apt-get install spidermonkey-bin for you Ubuntu/Debian types), and quickly downloaded the needed fulljslint.js file. (I stuck it in /usr/lib.)

However, once I started going through the steps to set it up, a couple of improvements occurred to me.

First of all, when I got to the point of calling JSLint from SpiderMonkey (a la Ian Bicking's post, I saved myself a step of indirection by making the script an actual executable, rather than passing it to the js executable. I just added the usual shebang) line, and the path to the js executable at the top.

Here's my whole runjslint script, that I stuck in /usr/bin:

#!/usr/bin/js
load('/usr/lib/fulljslint.js');

var body = arguments[0];

var result = JSLINT(body, {
  browser: true,
  forin: true
});
if (result) {
 print('How are you gentlemen. :)');
} else {
 print('Somebody set up us the bomb! :/');
}
print(JSLINT.report());

Next, being a JavaScript guy, the idea of using a Python script to format the JSLint HTML output into plaintext seemed somehow less-than-satisfying.

I actually started to add a quick inline formatting step directly in the js command-line script, but I quickly realized that the JSLint output had a pretty complicated structure, and simple splitting/removing-tags just wasn't going to cut it for me anyhow. I wanted something a little nicer.

Using Lynx (sudo apt-get install lynx) seemed to me an obvious approach -- and as it turns out, at least under Linux it's easy to use Lynx as a filter to convert HTML output to plaintext in a shell command. (I'm not sure how you'd do it under OSX or one of the other BSDish OS's, but I'd assume there's a way to make it work.)

Here's what I added to my .exrc, including the piping through lynx, to create the filter:

cabbr jslint !runjslint "`cat %`" \
  \| lynx --force-html /dev/fd/5 -dump 5<&0 \| less

It was really cool to see how easily this could be done, and with these small improvements, it's even nicer.

I find myself JSLinting now pretty regularly throughout the day -- especially once I got JSLint to shut up about one-shot constructor functions for namespace objects. And I guess that's a pretty specific tweak that might be worth another post.

0 Comments

Windmill revolution!

4 months ago / 0 Comments

It's a Windmill revolution! (Get it? You see, Windmills are these things that go around and around -- they revolve, you see, so, um .... Yeah, that's terrible, I'll stop.) Actually there really are some revolutionary changes going with Windmill, the Web-UI testing framework birthed at OSAF.

First of all they recently released version 0.8.2, with some great new features:

  • Integrated Firebug Lite support
  • wxWindmill contrib application
  • Enhanced 'smart' recorder
  • Auto element-scroll-into-view to simulate actual use more closely

The Windmill project has also moved to brand-new infrastructure, including a shiny new Web site at http://getwindmill.com/

The core team is hard at work on more new-feature goodness, as well as relentlessly squashing bugs as they crop up. You can usually find them in IRC (#windmill on Freenode.net), or follow their progress on the developer mailing list.

If you haven't checked out Windmill lately, you'll be pretty amazed to see how fast the improvements are piling up. Check out their introductory screencast to see the newest Windmill release in action. You'll also find a handy side-by-side comparison on the Windmill site which gives you an idea of Windmill's feature set compared with other testing solutions.

In short, the Windmill core team is kicking serious ass, and I'm really looking forward to seeing more Windmill awesomeness in the coming months.

0 Comments

Painless publish/subscribe with YUI custom events

5 months ago / 1 Comment

We're using YUI now at Seesmic. We were using my Fleegix.js library, but as more developers come on board I think it's better to use something mainstream. YUI also has a large array of well-tested UI elements (Overlay, TabView, etc.) that make rapid development easier.

So far the transition has been relatively painless. YUI is massively frameworky and kind of ponderous -- but it is well documented, and it's pretty easy to get it to do what you need it to.

The glaring exception so far has been their implementation of publish/subscribe. Sure, YUI has custom events. Any toolkit for building real apps (as opposed to Ajaxy pages or sites) needs it for keeping UI components decoupled.

Sadly, in the case of YUI, pub/sub is a bit of a mess -- custom events is a weird mish-mosh of function, scope, and params flying around, with no over-arching design that I can discern.

I keep thinking that the Yahoo (no, I won't put that fucking exclamation mark on the end -- that's! completely! stupid!) JS guys have to be smart, but when I see something like this I can't help but wonder what drugs they were on. The over-the-top ad-hoc-ness bears a strong resemblance to a good old-fashioned game of Fizzbin.

I have used other pub/sub systems that don't suck. Dojo, for all its other imperfections, has a really uber eventing system with really nice pub/sub -- which is of course why I cloned its API for Fleegix.js's event.publish and event.subscribe.

Thankfully, JavaScript's meta-programming facilities make it pretty easy to consign YUI's Bizarro World custom-events API to code-purgatory. A simple wrapper around the CustomEvent stuff gives you a simple and sane pub/sub interface.

Here's the code:

YAHOO.util.Event.channels = {}; 
YAHOO.util.Event.subscribe = function (channelName, obj, listenMethod) {
  var getSubscriberMethod = function () {
    return function (type, args, scopeObj) {
      scopeObj[listenMethod].apply(scopeObj, args);
    }   
  }
  if (!this.channels[channelName]) {
    this.createChannel(channelName);
  }
  // Create a subscription for the passed object
  this.channels[channelName].subscribe(getSubscriberMethod(), obj);
};
YAHOO.util.Event.publish = function (channelName, paramObj) {
  if (!this.channels[channelName]) {
    this.createChannel(channelName);
  }
  this.channels[channelName].fire(paramObj);
};
YAHOO.util.Event.createChannel = function (channelName) {
  this.channels[channelName] =
    new YAHOO.util.CustomEvent(channelName, this);
};

This creates two methods you can use in the YAHOO.util.Event namespace -- publish, and subscribe. Calling either one of these will automatically create the specified channel if it doesn't exist.

You use it like this:

var subscriber = new function () {
  YAHOO.util.Event.subscribe('someChannelName',
    this, 'handlePublish');
  this.handlePublish = function (obj) {
    alert(obj.message);
  };  
}

var publisher = new function () {
  this.sendMessage = function (msg) {
    YAHOO.util.Event.publish('someChannelName',
      {message: msg});
  }
};

publisher.sendMessage('foo'); // Alerts 'foo'

This is a really minimal example, but you get the idea.

Basically this just lets you send an arbitrary package of stuff (data, functions -- anything you can stick in a JavaScript object) to a named channel, and all the interested objects listening on that channel will receive it. Nice, simple pub/sub -- easy as pie.

I haven't really banged on this very heavily, so there may be some bumps in the road, but so far it's working like a champ -- publishing messages across the app, and staying out of the way.

Obviously too, there's a tiny bit of overhead added working through this wrapper -- but pub/sub is for macro-level events that function across your entire app, not micro-eventing within single components. The performance implications of using this wrapper should be pretty negligible.

It's a small price to pay for avoiding a game of Fizzbin.

1 Comments

Format-specific server errors for your Ajax app using Merb

6 months ago / 0 Comments

Handling server-side errors in Ajaxy Web apps has always been annoying. There is a raft of articles on the subject, and I've seen it brought up in numerous conference talks, too.

In lots of articles, the idea of 'handling' the error is limited to printing some scrap of text for the user (often in our favorite Philip-Glass-mimimalist piece of 'user interface,' the alert box). Super-cool, you're trying to cram something that usually occupies an entire Web page into a postage-stamp-sized square.

It's just not helpful getting back a bunch of formatted HTML instead of the data your Ajax UI is expecting.

What flavor of FAIL?

When something goes south on your server, you need to tell your clients a bit more than "oh, shit." Server-side FAIL comes in multiple flavors, just like 'Cokes' here in Texas. ("What kind of Coke do you want?" Yeah, it's silly, but I still giggle anytime I hear someone say 'pop' or 'soda.')

And as more Web clients begin to implement more RESTful interfaces, and implement them in more depth, this question of what kind of failure starts to be even more important, because there's a broader range of errors to consider, and they don't always mean there's been some kind of catastrophic breakage.

Looking at the XHR object status (or however you can get at the HTTP status code), that's a good start, but that doesn't really tell you that much about what exactly screwed up, or why -- so there's no real way to know what to do about it, or what to show to the end-users.

Hammered error-detail doo-doo

Your next problem then is how to hammer the error details into something usable for your app, and worthwhile for the end-user.

If your Ajax app requests some data, and the request succeeds, you get a nice string of parsable JSON data your code can consume -- but if something goes wrong on the server and you get back ... a big page of HTML markup. To quote Miracle Max: "While you're at it, why don't you give me a nice paper cut and pour lemon juice on it?"

In the early Ajax days, one method I used a lot for debugging was popping up an entirely new browser window and dumping the responseText into it. It's a pretty reasonable approach for development (until Firefox's new-window-in-a-tab breaks it, thanks, guys) but it's not really helpful for end-users in a production app.

Another fun 'solution' involves doing string comparisons or regex checks against that massive HTML hairball. Kind of like groping around incoherently for where you dropped your car keys at the party after your fifth beer. Not just sub-optimal -- more like anti-optimal.

Nice work if you can get it

If your client is really integrated with your server, you can tailor your error responses and client-side handling to work together. Nothing like writing everything yourself on both sides to make sure your shit actually works.

Chandler server returns errors in Atom format, so when I worked at OSAF I could count on JavaScript having access to a nice, brief message to display to end-users -- as well as more detailed info (a big ol' Java stack trace) that we could give the user a link to in the error dialog.

Unfortunately we're out of 'zardoz.xml'

What if you're not so lucky? What if you have to support different, disparate clients, and multiple data formats? Shouldn't your app provide error data in those same formats?

If your local Vietnamese restaurant can take your order in English, then it's pretty reasonble to expect they can tell you in English that they're out of Sriracha sauce or whatever. (Like that would ever happen at any self-respecting Vietnamese place, right -- anyhow, you get the point.)

So if I ask for an XML file that turns out not to exist, it'd be pretty kick-ass to get back some XML that tells me so.

Doing it with Merb

I've been doing a lot of work lately with Merb, the Ruby Web-app development framework. It has pretty smart content-negotiation support, which makes it super-easy to provide data in multiple formats. It's also really customizable, so it turns out to be a snap in Merb to do format-specific error handling.

All you have to do is make some changes to the Exceptions controller in /app/controllers/exceptions.rb, and you can return errors to the client in whatever format the original request was in.

Here's the code:

class Exceptions < Application
  include Merb::ResponderMixin
  provides :json, :xml

  # handle NotFound exceptions (404)
  def not_found
    render_for_format
  end

  # handle NotAcceptable exceptions (406)
  def not_acceptable
    render_for_format
  end

  def render_for_format
    format = content_type
    if format == :html
      render :format => :html
    else
      except = params[:exception]
      # Status code, e.g., 404
      stat = except.class::STATUS
      # Status text, e.g., "Not Found"
      words = except.name.split('_')
      words.each do |w|
        w.capitalize!
      end
      stat_text = words.join(' ')
      # Error message, e.g., "Controller 'Zardoz' not found"
      msg = except.message
      data = { :status => stat,
        :status_text => stat_text,
        :message => msg }
      begin
        display data
      # Handle formats the error-handler doesn't know about
      rescue NotAcceptable
        render :format => :html
      end
    end
  end
end

A few examples

So a client making requests for a non-existent endpoint of "zardoz," in various formats, would see something like these:

/zardoz.json

{"status":404,"message":"Controller 'Zardoz' not found","status_text":"Not Found"}

/zardoz.xml

<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <status type="integer">404</status>
  <message>Controller 'Zardoz' not found</message>
  <status-text>Not Found</status-text>
</hash>

Content-negotiation goodies

First of all, you have to include ResponderMixin so you can get access to Merb's content-negotiation goodies. Then it's pretty simple to pull together the data you want to include in the response, and spit it out in the desired format.

"I'm sorry, I don't speak FOAF"

The rescue for the NotAcceptable exception is kind of important. I guess it's a bit meta, but if your exception controller itself doesn't provide the requested format, you need to be able to fall back to a plain HTML-format error page.

You might wonder why you'd even bother trying to provide format-specific errors for the not_acceptable action (this is where you end up when the client requests a format that's not supported). Well, there may be cases where your app speaks a particular format, but the requested controller/action does not. In that case, you can tell the client -- in the requested format -- that the requested format isn't supported. Fun.

It's a bit like the French dude I met in Thailand who responded to my question with "I'm sorry, I don't speak English" -- in what seemed to me to be perfect English. At least with the server-side error messages you know it's nothing personal -- and it's probably not because you're an ugly American.

Caveats

By default Merb doesn't actually bother parsing requests when they don't match any routes. This makes perfect sense of course -- but it means there's no content_type for those requests, so you can't serve up your format-specific NotFound errors for those.

If you want to have format-specific errors for all 404s, even for those that don't match any known routes, you can enable the default routes in /config/router.rb.

Okay, wrap it up, buddy ...

Format-specific errors are a nice tool in the toolchest -- getting data in the format you asked for, even when something goes wrong, is kind of nice. Dealing with errors in your Ajaxy Web apps is annoying enough without having to trawl through a big pile of markup in an error HTML page.

As you can see from the code above, Merb makes this super-simple to do, but I'm sure there are all kinds of good ways to accomplish it in your language/framework of choice.

0 Comments

Kicking the tires on SproutCore, not keen on the object literals

6 months ago / 2 Comments

Started kicking the tires this evening on SproutCore, Apple's "Cocoa-inspired" JavaScript framework for buildling Web applications.

It looks pretty solid so far, although not nearly as far along as some of the older frameworks like Dojo, YUI, or even JQuery. The docs look pretty good, and rather than trying to take a server-language-agnostic approach, it integrates tightly with Ruby, which is personally appealing for me -- I like Ruby a lot, and my job at Seesmic has me doing a lot of server-side stuff in Ruby.

The Hello World tutorial is nicely done -- it does a good job of demonstrating how easily you can get a dynamic Web UI using some Ruby helpers in Erubis rhtml templates.

SproutCore works hard to provide some MVC-sanity for your Ajaxy Web app project, so files are organized logically into separate directories. Your JavaScript controller logic is kept in .js files in a controllers directory.

The only thing I've found remotely disagreeable so far with SproutCore is that, like the other Ruby-friendly library, Prototype, the syntax leans heavily toward JavaScript object literals for pseudo-class definitions.

You create your controller by passing an object containing the properties and methods desired to SC.Object.create, like so:

HelloWorld.appController = SC.Object.create(
/** @scope HelloWorld.appController */ {
  greeting: "Hello World!",
  toggleGreeting: function() {
    var currentGreeting = this.get('greeting');
    var newGreeting = (currentGreeting === 'Hello World!') ?
      'I am on SproutCore!' : 'Hello World!';
    this.set('greeting', newGreeting);
  }
});

I'm not keen on this syntax for creating objects for a couple of reasons.

One is the small-but-irritating trailing-comma problem with object literals. Some browsers, like Firefox, don't really mind them. Internet Explorer's JScript parser chokes on them like a fraternity pledge on his eighth shot of tequila.

When I lived in Japan, there was this local pub with a door that was ridiculously short -- the top of it hit me right around chest-level (I'm not a tall man), and you had to remember when entering and exiting to bend down to get through the door. I bumped my head on that thing time after time (as did all the locals -- it wasn't just a gaijin thing), cursing every time because I knew to duck my head.

The trailing-comma-separator problem in JavaScript is the same kind of problem as that goofy door -- you keep banging your head on it, even though you should know to be careful with it. Avoiding those object literals for something as ubiquitous as declaring your pseudo-classes makes it a lot less likely you'll be smacking your head on it over and over.

The other big downside of the object-literal syntax for pseudo-classes is that you don't get any local scoping, so you're reduced to using the underscore-propery-name convention to fake private variables. They're still public members, but you just pretend they're private. It's not unworkable, but it's much nicer to have access to actual private variables in your code.

There are a couple of alternatives to the object literal. You can use function objects in a couple of ways:

var foo;
// 1. Object literal
foo = {}; 
// 2. Execute a function that returns an object
foo = function () { return {}; }();
// 3. Use the 'new' keyword, return an obj by default
foo = new function () {};

All of those will return an object. Number two gives you private variables, but the final object you pass back still has to use the annoying object-literal syntax. Not much of a win.

Number three gives you private variables, and lets you use the normal idiomatic "this" syntax you're used to from writing plain old OO JavaScript.

Let's see how SproutCore's Hello World tutorial might turn out using the inline constructor function syntax from number three:

HelloWorld.appController = SC.Object.create(
/** @scope HelloWorld.appController */ new function () {
  var _strings = { 
    HELLO: "Hello World!",
    SPROUT: "I am on SproutCore!"
  };  
  this.greeting = _strings.HELLO; 
  this.toggleGreeting = function () {
    var currentGreeting = this.get('greeting');
    var newGreeting = (currentGreeting === _strings.HELLO) ?
      _strings.SPROUT : _strings.HELLO;
    this.set('greeting', newGreeting);
  };
});

Notice I added a private variable, _strings, to the controller pseudo-class. (I name private vars with a leading underscore to make it clear in my code that it's not a plain local variable -- but it's a real private variable.)

This also looks a lot better to me -- it's a wee bit more verbose with the repeated "this," but it looks to me more like the plain idiomatic JavaScript I'm used to, and there's no worry about smacking your head on that trailing-comma-separator problem.

SproutCore looks pretty reasonable so far. I hope to post more as I get more familiar with it.

2 Comments

Comments are back -- die, spammer asshats

6 months ago / 2 Comments

Just added a bit of anti-spam fu to the comments field. Not sure how well it will work, but I'll give 'er a go and see.

Comments are back, as long as the spammers stay gone.

2 Comments

Subscribe

About

This is the Weblog of Matthew Eernisse. I'm a Web developer, and work primarily with Ruby and JavaScript. I'm currently employed at Seesmic. The thoughts and opinions expressed here are entirely my own.

Yep, It's My Book

Recent Articles