A Fine Coffee Bug (Random Coding Note). And jsConsole.

This is a bug that took so long to track down, I had to write it somewhere.

The wrong code was:

radio('new-page').subscribe = -> # handle new pages

It should have been

radio('new-page').subscribe -> # handle new pages

The first call was actually over-writing the radio subscribe() function, so no further handlers were actually getting registered.

This does happen quite a bit with CoffeeScript. By wiping out all the parentheses and other junk, it leaves just a few symbols which sometimes are necessary and sometimes not. e.g. with jQuery onclick registration ($('button').on 'click', -> ....), one has to stop and think if there’s a comma or not. Everything else is natural it flows staight from the lizard brain and onto the screen, but not the damn comma. Hopefully there will be some nicer syntax highlighters and run-time diagnostics to catch this kind of thing in the future.

What phased me about this was it was working on desktop, but not Android. Thought it might be some Android quirk. But it’s because I’ve customised the basic player for android, so this code was only actually executed for Android.

Anyway, if there’s one useful thing I can say about this: Remy’s jsConsole tool rocks! Seriously. It helped me get Player FM working on Windows Phone IE the other day and it got me out of this fine Android pickle today. With Android Browser, you can get a basic console with about:debug, but it’s rubbish. Silently fails a lot of the time, only shows the first console log argument, no command-line history or completion so you’re typing like it’s a 2003 SMS. jsConsole makes it real easy. Just put something like this in your HTML layout (for Rails/Haml):

 -if Rails.env.development?
<script src="http://jsconsole.com/remote.js?myawesomeapp"></script>

Then visit jsConsole and type :listen myawesomeapp. Now you have a grown-up’s console.

Graceful Degradation of Links

I made a bit of rookie error on a recent update. Suggestions for best practices are usually presented as fait accompli, but actually come from iterations in many cases. So I’d like to share how this one evolved. The actual refactorings were small, but it took a day of background thinking before the light bulb went off.

The feature “ajaxes in” some content when the user requests it.

I call this component a “midi” (bigger than a simple button or line of content, smaller than a full page.) It acts as a kind of preview, where the user can open the full page by clicking on the “tablet” title on the top-left.

Just a span

I begin thinking about the request controls as simple spans, like etc, because I’m getting away from the usual channel “tablet” control. Tecnically, the Ajax handler could just parse the title of the using the span’s innerHTML, but that would be error-prone and inflexible. For one thing, it would have to infer the owner as “featured”, and that would make the component less general-purpose. So I embed the path as a data attribute:

<span data-path=’/featured/comics/midi’>comics</span>

Not bad. Now we just need to Ajax-request /featured/comics/midi and drop the content into this div. A one-liner using jQuery replaceAll() or similar.

A real link

I don’t deploy yet. I go to bed and test on iPad and realise this sucks for touch. With a real link, tablets will confirm it’s a link when you press down on it. iPad, for example, will show a grey background and if you long-hold, open options to Open In New Tab, etc. I could try faking it with hover styles, etc., but it’s unnecessary when I could just make this thing a link. So I do this:

<a href=’/featured/comics/midi’>comics</a>

Much better on touch devices now.

No, a real, real, link

Okay, but wait a sec. What if the user actually clicked on the link, or a search engine bot followed it? The link would take them to an unstyled block of content that’s supposed to appear on a page. Well, I could try to detect XHR and format it nicely. But there’s a better way:

<a href=’/featured/comics’>comics</a>

Just link to the actual thing the user is trying to preview. The JavaScript now adds “/midi” manually when performing the hijack. So the “/midi” link never appears on the site. Just as it shouldn’t.

Eeedjit. Why didn’t I do this from the start?!!

On the one hand, I made a basic error by not doing it from the start. On the other hand, I think it’s a good example where the solution changes over time as you re-conceptualise the problem. I simply wasn’t thinking about the “request controls” as links, and I was thinking if the user wants to open up a link in a new window, they can request a preview first, and then open it. But of course, users will indeed want to open in new window, right-click to copy the link, etc. That’s really one of the great benefits of a HTML5 history architecture like this, where the links are real and not Ajax-era hashbangs. It’s just that I didn’t see it that way from the start.

Abstraction Begets Fragmentation

Christian Heilmann raises the ugly issue of offline storage. LocalStorage’s synchronous nature makes it slow, WebSQL is deprecated, and IndexedDB’s API induces headaches as well as being unsupported on many browsers. He asks whether the LocalStorage standard should be improved.

One of the predictable responses is “just use a wrapper library”. We could use a fancy wrapper library that gives us the key-value simplicity of LocalStorage, but with an asynchronous API, and backed by those more beastly SQL-based solutions if they should exist on the device.

Now “a wrapper library” has all the usual concerns of abstractions. Does the common-denominator stance remove useful functionality from the underlying APIs? Does it separate the programmer so much from the bare metal that they can’t get their head around performance issues? And so on. All true. But on the web, where open-source is so heavily used, wrapper libraries have an additional cost: Fragmentation.

So we end up with a dozen storage libraries on GitHub. BackStorage, SpineStorage, OrthopedicStorage, you name it. That’s great, now we can use a nice API that works everywhere. Fast forward, and every programmer and their canine is writing offline single-page apps, so now we need libraries to cache, spool, and throttle messaging back to the server. Those libraries rely on underlying storage. Do they talk straight to the raw storage APIs? But then they’ll spend all their time worrying about those APIs. So maybe they reuse one of those storage libraries. One of them uses BackStorage, another one uses SpineStorage, and a couple more use OrthopedicStorage. Yes, a whole plugin ecosystem gathers around each storage solution.

So which are you? Do you consider yourself a BackStorage man/woman? Card-carrying SpineStorage-head? Certified OrthopedicStorage practitioner? You’ll need to pick one, because each is its own community with its own set of plugins and conferences. Not to mention the learning curve involved in adapting to something new. And the conflicts that arise if you try to use two wrappers in the same app. Wait, did SpineStorage.Login just stomp on that username I was trying to retain with BackStorage.Cache?

Choice is good and evolving faster than standards is good too. Which is why we do benefit enormously from wrapper libraries. But the cost of fragmentation is high. It can be justified if you’re reaping the benefits of magic conferred by a highly opinionated framework. But if it’s just there to cover up for a standard with an unnecessarily confusing API, I’d rather the browsers work on simplifying said API. Because I don’t want to identify myself as a developer skilled in the arts of BackStorage/SpineStorage/OrthopedicStorage.

I’d rather just be a “web programmer”.

Login Best Practices for Mobile Web Apps

Walking home, I thought I’d venture to make a meal order via my phone…and without making a phone call. It shouldn’t be an ordeal to do so in 2011, but frankly a sense of learned helplessness means I haven’t even tried before. I know, #FirstWorldProblems, but let’s learn something from it.

Anyway, I pull up my favourite meal delivery service, Hungry House (highly recommended! At least in London.) I simultaneously launch a Market search for a Hungry House app – right or wrong, we know mobile app experience is almost always smoother. Well, no app, but the web page loads…and a bunch of antipatterns emerge.

Instead of documenting login antipatterns, I’ll make this post more useful by turning them around and proposing best practices for mobile web login. Beware it’s all speculative and subjective.

Zen Login Form

Make a simple, mobile-optimised, login form. Make sure it’s easy to click on each field to focus them (there’s only two of them!). Make sure any links (“forgot password”, “sign up”) are far enough away they won’t accidentally be licked.

This is true of all mobile web forms, not just login one. But if your app only works behind a login form, this would be the first one to optimise.

“Keep Me Logged In” should default to On

It’s a mobile phone, not an internet cafe, so yeah. Admittedly, this is trickier in the case of a tablet, but still it’s only a default, I’m not saying “hide the option altogether”. Also, form factor detection ftw.

Don’t Expire the Login Cookie

Okay, this will be controversial. But if mobile web apps are to be a viable alternative to mobile-native apps, they should provide the same login experience. Right now, a majorly overlooked distinction is login expiry. I find myself having to login to Twitter all the time, when trying to tweet from some other web app. But with the Twitter mobile app, I’m always logged in. Basically, mobile-native apps never expire the session. Most of them probably don’t even bother with a session/token, they probably just store the user’s credentials in plain text on the device (just some speculation on my part, based on the “see no evil” principle, given that this data is fairly invisible, being stuck in the app’s data storage.) At least a cookie, if found by someone else, doesn’t compromise the entire account, and can easily be expired.

Keep it Light

Needless to say, don’t load so much that the browser crashes. Repeated browser launches makes users hungry.

Marcin Wichary: You Gotta Do What You gotta Do [Full Frontal Live Blog]

Marcin explains the hacks that went into the Atari 2600, moving from a crappy “tennis” game in 1978 to a somewhat less-crappy Pitfall in 1982, doing things the Atari architects never anticipated. (Covered in “Racing the Beam”) Which would be the same if you showed 1990 TBL the web today.

Google Doodles have gotten bigger over the years … lines of code: 2009: 1, 2010: 5000, 2011: 13000 (thx @suhajdab)

Marcin shows various iterations of the underwater doodle:

On the theme of pragmatism, it went through a bunch of iterations, to get to the point where people would know they can control the water flow, ultimately leading to an explicit handle control. And degrades gracefully to IE6 (choppy, but works) and no-JavaScript (nice image).

We haven’t gone beyond the IE6 graceful degradation…we still have this in HTML5, so it’s not going to go away. WebSocket keeps changing, different audio support, etc. Which means you sometimes have to do what it takes.

Rality of JavaScript is if you don’t do anything that feels a bit nasty, you’re a bit behind. So you have to embrace some of these nasty hacks. With doodles, the endpoint is about doing something with a sense of purpose, not being infatuated with the technology, or, for that matter, the art.

Nicholas Zakas: Scalable Web Architecture [Full Frontal Live Blog]

Nicholas Zakas is talking about scalable JS architecture.

He begins with a straw poll. Turns out half of the Full Frontal room is working on a Single Page App, right now.

Framework != Library. jQuery? Not a framework. It’s a library you call to perform some limited functionality.

What’s a “module”? Very overloaded term, but Nicholas wants us to think about a module as a block of HTML, CSS, and JavaScript together. Like a widget on the Yahoo! homepage. Modules should be loosely coupled, and this can be achieved with the modules living in a sandbox.

Nicholas identifies a layered architecture, where an application core mediates between independent modules, which use a base library (jQuery etc).

Think of modules as little kids – they can do lots of cool stuff, but need strict supervision: * Hands to yourself (limiting what they can access) * Ask, don’t take * Don’t leave your toys around * Don’t talk to strangers

The Application core manages module lifecycles and mediates between them. There’s also an error handling role, and Nicholas gave a talk about this previously: JS Error Handling.

People are usually too coupled to their base libraries, like jQuery. As Joe Smarr pointed out in a 2007 talk, you’re better off using them as scaffolding, and building modules around them.

img

Jeremy Ashkenas: CoffeeScript [Full Frontal 2011 Live Blog]

Live blogging at Full Frontal 2011, where Jeremy Ashkenas is first up, presenting on CoffeScript.

Motivation

Good work is being done inside and outside of the TC39 committee. The next version of JavaScript is an open process, a working mailing list you can get involved with, and there’s a chance to experiment and shape it.

“It’s just JavaScript”: CoffeeScript is not about creating a new language or letting us apply an existing language in a browser.

Bootstrapping

Original version of CoffeeScript was written in Ruby, but as v0.5, it became significant enough to bootstrap it: Ruby builds an initial CoffeeScript compiler, which then compiles the real CoffeeScript compiler. Slightly more complicated, but you get the idea: CoffeeScript is basically written in CoffeeScript.

Language Features

  • No “var”
  • No “function”
  • Significant whitespace
  • Comprehensions:

    1. for stooge in list
    2.     console.log 'hi ' + stooge

  • Block strings and interpolation (works for regex’s too):

    1. """
    2. An old pond
    3. a #{animal} jumps in
    4. the sound of water
    5. """

  • Object-oriented, and unlike normal prototype stuff, you get to call super.
  • Binding “this” to the actual object with =>

How it happens

Instead of waiting for a standards body or a browser to give you the language, you can roll your own today. CoffeeScript uses Jison for parsing, there’s also Pegs if you prefer. A nice tip is “it’s okay to cheat”! CoffeeScript uses a strict tokeniser to disambiguate, making the parsing much easier than if it allowed all sorts of ambiguities.

Comparing CoffeeScript and Kaffeine

I’ve recently been Node web programming and as a long-time proponent of DRY, I’m more than happy about the Alt-JS movement that has taken the webdev community by storm over the past six months, along with alt-HTML and alt-CSS.

We used CoffeeScript and Less for HN Reader. Faviconist is built on Jade for HTML, Stylus for CSS, and Kaffeine for JavaScript. I’m now doing a project in CoffeeScript for comparison, and because I found Kaffeine wasn’t as much of a finger-typing saver as I’d hoped for. Also, CoffeeScript has a huge ecosystem at this point. There are definitely great things about both, and indeed they are more similar to each other than either is to JavaScript, and they both make JavaScript a lot more DRY and pleasant to deal with. But let’s look at the differences:

Kaffeine pros:

  • Kaffeine has the major benefit of maintaining line numbers. With CoffeeScript, any error messages require a little thinking in order to track down the bug. Sometimes I even have to manually compile the CoffeeScript to track down the errant code (some of the various ways I’m using CoffeeScript only ever serve the JS, or keep it in memory, rather than ever saving it).
  • Retains ternaries, which, being symbolic, are more to my liking than the “if then else” CoffeeScript idioms. (I like symbols for code structures because what words remain are those that matter, i.e. those related to business and application concepts.)
  • Has a number of nice “coding in the small” idioms which aren’t present in CoffeeScript, especially the pipe and async. The latter lets you create a traditional “sleep 1000″ on its own line, giving the illusion of synchrony.
  • Doesn’t impose Python-like significant whitespace. Actually, I’ve come to like this about CoffeeScript (see below), but there’s certainly a learning curve until you get how to handle the various situations, which doesn’t need to happen with Kaffeine.
  • Truly JS++. The Kaffeine compiler will compile a regular JavaScript file just fine. With CoffeeScript, although the language aspires to be “it’s just JavaScript”, standard features like “function” keyword are simply not part of the syntax.

CoffeeScript pros:

  • There’s one extremely compelling reason to choose CoffeeScript right now, above all other dialects: The ecosystem. There’s exponentially more docs (the core docs themselves are great), more existing code, and more tools in CoffeeScript, than any other dialect. (Just as the ecosystem of JavaScript is in turn exponentially bigger than that of CoffeeScript.) Don’t get me wrong. It’s great that other dialects like Kaffeine are out there pushing the barrier, and even the less JavaScripty tools like ClojureScript and Dart which treat JavaScript more like a virtual machine. And because they all compile down to JavaScript, you can use them today. But if you want to ship code fast, CoffeeScript is the sweet spot right now: The benefits you’d want in a “JavaScript++”, with best support and minimal effort to integrate it into projects. There are already several CoffeeScript books in the making, for example. StackOverflow registers 600+ questions about CoffeeScript, while other dialects are in the single or low double digits. (And 130K questions about JavaScript, to prove my point about CoffeeScript still being a minnow in the big JS sea!) There are also an increasing array of tools where CoffeeScript support comes out of the box, e.g. connect-assets.
  • For a related reason, CoffeeScript may be the most future-proof dialect out there. Though we can expect JS.Next to learn from all the dialects, it’s clear Brendan Eich is paying close attention to CS:

  • The syntax is best described as relaxing! (With apololgies to CouchDB.) I initially balked at the significant whitespace, but now I appreciate its ability to wipe out curly braces and parentheses. It’s just nice to define hash literals without commas and braces, for example.
  • Operators like “isnt” and “unless” make the code much more literate. Why add extra baggage? Because to a computer “5==count” is the same as “count==5″, but to a human, there’s always a context which makes one more natural. See Yoda Conditions. These kinds of expressions help avoid double negatives too.
  • Class construct, which like everything, “de-sugars” to regular JavaScript.
  • There’s a reverse compiler. Nice if you want to fork an existing JS library or code example.

I’m still not done yet. While these are “just” dialects of JavaScript, each has a sufficiently large feature set that it takes a while to get the hang of everything, when you’re using them in real-world projects. So I’m still jumping back and forth between my code and the doco to make sure I’m getting full benefit of both.

A few caveats about JavaScript dialects:

  • As I’ve already pointed out, JavaScript is still vastly more standard than any dialect. While Dart may come to Chrome in the future, and various features will morph into JS.Next, you’re always going to be doing more tool integration and working with less docs. If releasing open source, you’ll want to distribute the JS or at least make it easy for someone to generate it. What’s good though is you don’t have to learn something completely different, so it doesn’t become a maintenance issue. You could easily hire a JS developer to maintain a CS app, they’ll be up and running in a few.
  • All create extra overhead in terms of tooling. Whether you’re dealing with a browser or Node, both of those deal in the currency of JavaScript, and some conversion must take place.
  • There are many situations where you still have to use plain old JavaScript. For example, working with legacy code or other people’s JavaScript. Writing inline script tags or dynamic code which will be eval’d in the browser (unless you also want users to download the CS compiler). You’ll need to get used to switching between the two, and that’s painful because once you start working with them, trust me, you WILL NOT want to go back. (This has been true for Jade vs HTML and Stylus vs CSS as well.) So I’m often having to consciously ask myself what I’m coding in right now.

Keeping “require” modules DRY in Node

Update: See the follow-up on StackOverflow. I agree with those who rallied against use of global, but no need to throw the baby out with the bathwater; as shown in that thread, we can instead use “eval” to keep it DRY.

You see a lot of NodeJS code like this:

javascript
< view plain text >
  1. connect = require 'connect'
  2. express = require 'express'
  3. redis = require 'redis'
  4. sys = require 'sys'
  5. coffee = require 'coffee-script'
  6. fs = require 'fs'

BTW this is CoffeeScript, not pure JavaScript, but the same logic applies.

The point is, Node’s module system gives you a layer of abstraction you probably don’t need. 9 times out of 10, people just assign a module to a variable by the same name. You would, wouldn’t you?!! You don’t have to think about alternatives, and you can easily cut and paste other people’s code. And it’s now just an industry convention.

So why not practice convention over configuration, and keep things DRY with the following idiom:

javascript
< view plain text >
  1. "underscore,connect,express,redis,sys,coffee-script,fs"
  2.   .split(',').forEach (lib) -> global[lib] = require lib

Thanks to the “global” object, which is like the “window” object in the browser, we can easily require new libraries without unnecessary clutter.

And – as with any decent convention-over-configuration setup – we can still override the convention if we desire:

javascript
< view plain text >
  1. _ = underscore

Mark Miller on Securing JavaScript: More Qcon Live Blogging

Google Research’s Mark Miller is presenting a talk on Caja and web security. He emphasises that this is all bleeding-edge; no current browser fully supports this yet.

There are a ton of attack vectors for browsers, as shown on the Caja wiki. There are spec vulnerabilities, implementation vulnerabilities, and an ongoing arms race emerges. Mark shows a table of numerous variables for each browser, where the variation is not just wild but more or less random. The attacker only need to find one vulnerability here.

Perhaps the ongoing cat-and-mouse game means there’s something wrong with the whole identity-centric paradigm. Instead, maybe we can look at access control – don’t worry about who’s sending the request, worry about if the request has the correct level of access.

Mark walks us through the history of web kludges – JSON and Comet for cross-domain calls and streaming, respectively. HTML5 gets us towards a truer web of distributed objects, which all leads towards a symmetric network.

Safe Mobile Messages: Uniform XHR

Uniform as in “Uniform Resource Location”.

The proposal is for the server to ignore browser’s “helpful” extras.

Authorise based on payload. HTTPS URL or request body – info the requestor knows.

HTML5 allows servers to waive response protection using “Access-Control-Allow-Origin: *”.

Mobile Code

How do you mix coded from multiple untrusted sources into the same frame?

To solve this problem, we bring other security models to the world of JavaScript. With EcmaScript 3, Caja had to perform complex, server-side, translation with a runtime overhead.

The lessons of this effort were taken to the Ecmascript committee, and accordingly, EcmaScript 5 is one of the easiest OO languages to secure, instead of one of the hardest, as was the case previously.

Security as Extreme Modularity

This view treats security as an extreme form of modularity (ie the mutually suspicious components are seen as modules). Vulnerability is a form of dependency…so improving security also helps in other aspects, ie. makes the architecture cleaner.

So we marry up these closely related principles: * Software Engineering Principle of info hiding: Need to know. * Security Engineering Principle of least authority: Need to do.

These are the rules enforced: * Memory safety and encapsulation * Effects only by using held references * No powerful references by default

Objects as Closures

javascript
< view plain text >
  1. function makeCounter() {
  2.   var count=0;
  3.   return {
  4.     incr: function() { return ++count; }
  5.     decr: function() { return --count; }
  6.   };
  7. }

A record of closures hiding state is a fine representation of an object of methods hiding instance variables.

With “use strict”, we can enforce freezing of values. So if you have object A which depends on object B, object A can freeze properties of object “B” to make sure the reference doesn’t change. An important aspect of this is the ability to feeze a prototype.

For now, we have the “initSES.js” library. It monkey patches away bad non-standard behaviours, freezes whitelisted global variables…among other measures.

There’s a concept of membranes (wrappers) to encapsulate/secure message passing. e.g. if you don’t trust object X, you can make a read-only version of its return value. It’s also possible to wipe out what’s inside the membrane at some later stage, if desired. Even if that thing had references to external objects, only what was inside the membrane will be wiped.