Development and UX from Michael Mahemoff. Maker of Player FM. Previously: Google, BT, O'Reilly author.

Menu

Monthly Archives: November 2011

I wanted to default a field to the epoch, i.e. some decades ago, or older. That’s because a batch process will work on the records with the oldest such field, so setting the field to epoch guarantees they’ll get priority initially.

Note it’s DateTime.new for epoch, not DateTime.now, which will be the present time. (And you probably wouldn’t want that, because it would be the time you run the migration, not the time a given record is actually created. If you want creation time, use a before_create callback.)

Share this:

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.

Share this:

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.

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.

Share this:

Glenn Jones has a wicked talk showing his drag-and-drop and web intent adventures. A lot of this is very tricky and not well documented.

He kicks off with an impressive demo. Pure client-side, he drags elements from one window to another. Once dropped, the element fills with online IDs of the contact, by querying their homepage against the Open Graph API.

It gets even better when he drags a zipfile from explorer to Chrome, and expands it…and then drags from Firefox to Chrome. He also drags a vcard out from the contact to the desktop.

He mentions the drag-and-drop
nightmare
and walks though the various scenarios: Dragging to desktop, dragging between
browsers, etc. You’ll be able to see his code in the slides, but suffice to
say,there’s a lot of ninja here. All the APIs are different and the browsers
there’s a lot of ninja here. All the APIs are different and browsers vary widely.

One hack worth noting is the rarely used “type” attribute on the “a” link. By programmatically creating
a type=’text/vcard’, you can make Firefox download just like Chrome’s new download feature.

On to Web Intents. Glenn has a demo using Web
Intents to pick a profile or a list of friends.

For perspective, he goes way back to Lotus 1-2-3 days…these early DBs and spreadsheets succeeded because accountants suddenly had creative independence, data ownership, and portability. Something the later enterprise movement forgot about.

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.

Share this:

Next is Rik Arends, founder/CEO of Cloud 9. (I met Mike and Lieke at Full
Frontal 2 years ago, when they were Ajax.org, and subsequently hosted Rik and
Ruben at Osmosoft, then worked with them on the Cloud 9 Chrome Web Store app
and their Google IO sandbox demo.)

Why Cloud 9?

A lot of editors treated JS as an afterthought, so we needed a proper
JavaScript editor. We wanted one that wasn’t overwhelming, but still did more
than just basic syntax highlighting and formatting, e.g. refactorings. Rik felt
it was important to write a JS IDE in JavaScript; was painful to do something
like this in Eclipse.

Also, IDEs don’t need to be ugly or cluttered – they should have a designer feel to
it.

Cloud 9 a year ago was not yet as polished, but the initial version was
received well and there was enough validation to move ahead and bet the company
on it. The team raised venture capital and is setting up in San Francisco.

Demo

Rik live-demoes a Node “Hello World”. Running up the server, checkin to GitHub,
deploy to Heroku.

Javascript in the Client …

APF – high performance UI library

ACE – source code editor in JS, adapted from Bespin

Socket.io – real-time socket networking

jsDAV – file system layer

Connect – HTTP middleware

… And JavaScript in the Server

Structured exceptions do NOT fit in NodeJS. A single exception for a single
user, if it bubbles up, will blow up the whole server! So can’t use exception in
Node the way you use them in JavaScript.

Beware of globals too, for the same reason. A single global created for a
single user/request will linger. So “use strict” and avoid “closure globals” –
even though they’re not truly global, they’ll still linger and are best avoided
if possible.

Avoid state, preferably have none. The thick client makes this real.

Monitoring Node process with “forever”.

Log everything to reconstruct bugs. You should be able to work out what state
your server was in when the bug occurred.

Don’t blindly trust a library or module right now.

Where’s Cloud 9 Going?

The vision is to have the whole thing online; should never have to revert back
to the local system to deploy.

ACE – formerly Bespin – was faster and more portable, making CodeMirror look
bad! So CodeMirror 2 is a rewrite based on some of those techniques.

Some performance tricks:
* Indexes both by line number and by vertical offset.
* Only renders the portion of the DOM you can see, plus a little on either side
in case you scroll just a few lines.
* Selections are passed back to the original text area.

Phil talks about the power of standards, with a nod to Paul Downey’s The Web Is
Agreement and The URL is the Thing.

“The seductive power of the possible”. Phil compares the original, raw,
Macdonalds site to the recent beetle.de site. Yes, it’s HTML5, not Flash, BUT:

11mb of images

251 http requests

no caching

“As you scroll, it lazily loads some images, the next 4MB of uncached images”

The beetle site arguably doesn’t really provide any more information than the
original Macdonalds site. The URLs can’t be bookmarked and it takes an age
to load!

Twitter is the next subject of Phil’s scorn! No Javascript? No love.

Now we get to Phil’s main point: Interface shizzle doesn’t have to break the
web. His example is GitHub’s use of HTML5 history, with the animated slide effect.
He notes you can use Levi Routes as a simple way to manage history (it’s the
framework Paul Kinlan developed for our Google IO
Talk).

Lots of great slides here, too many to post here, but he’ll be putting up the
slideshow later on.

Share this:

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.

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.

Share this:

G’Day

Welcome to Michael Mahemoff's blog, soapboxing on software and the web since 2004. I'm presently using HTML5 and the web to make podcasts easier to share, play, and discover at Player FM. I've previously worked at Google and Osmosoft, and built the Ajax Patterns wiki and corresponding book, "Ajax Design Patterns" (O'Reilly 2006).
For avoidance of doubt, I'm not a female, nor ever have been to my knowledge. The title of this blog alludes to English As She Is Spoke, a book so profoundly flawed it reminded me of the maturity of the software industry when this blog began in 2004. I believe the industry has become more sophisticated since then, particularly the importance of UX.
Follow @mahemoff