Skip to content

Ajaxian
Syndicate content
Cleaning up the web with Ajax
Updated: 1 hour 35 min ago

Canto.js: An Improved Canvas API

Thu, 07/29/2010 - 06:10

Javascript author extraordinaire David Flanagan released Canto.js recently, a lightweight wrapper API for canvas, introduced here and documented at the top of the source code. Example:

PLAIN TEXT JAVASCRIPT: canto("canvas_id").moveTo(100,100).lineTo(200,200,100,200).closePath().stroke();
 

Notice three things:

  • canto() returns an abstraction of the canvas - a "Canto" object.
  • As with jQuery and similar libraries, there's method chaining; each method called on a Canto also returns the Canto.
  • lineTo() has been extended to support multiple lines being drawn in a single call.

Instead of setting the ink properties and then painting it, you can do it all in one step:

PLAIN TEXT JAVASCRIPT: canto("canvas_id").moveTo(100,100).lineTo(200,200,100,200).closePath().stroke({lineWidth: 15, strokeStyle: "red"});
 

And plenty more syntactic sugar - check out the API in the source code comments. Sweet!

Thanks @pkeane.

Categories: Communities

YUI 3.2.0 preview release 1 – touch events support, transitions and browser-specific loading

Tue, 07/27/2010 - 20:34

Over at the the YUI blog the team just announced the preview release of YUI 3.2.0. YUI3 now has some interesting new features that the team wants you to try and tell them if they work out for you. The changes to the already very powerful library are quite ambitious:

So check out what is on offer and give the YUI team feedback on what would be nice to have and what is broken. In their own words:

The goal of a preview release is to make it as easy as possible for all of us in the community to evaluate progress of the upcoming release and provide feedback. Please take some time to test 3.2.0pr1 and let us know what you find by filing tickets in the YUI 3 bug database marked as “Observed in version” 3.2.0pr1. We’ll do our best to address preview-release questions on the YUI 3 Forums, too.

There are three ways to get started with the preview release: YUI 3.2.0pr1 is available on the CDN via the 3.2.0pr1 version tag — so you can reference preview-release files like http://yui.yahooapis.com/combo?3.2.0pr1/build/yui/yui-min.js. If you switch to this seed file for the preview release, all subsequent use() statements will continue to load YUI 3.2.0pr1. Or You can download the full YUI 3.2.0pr1 from YUILibrary.com, including source code and examples for all components. Or you can simply explore the functioning examples roster.

Categories: Communities

Canvas Color Cycling

Tue, 07/27/2010 - 02:21

Interest in Canvas, as well as mobile apps, has led to a renaissance of old-school 8-bit graphics. Joe Huckaby of Effect Games has been playing around with color cycling, leading to some stunning effects.

Anyone remember Color cycling from the 90s? This was a technology often used in 8-bit video games of the era, to achieve interesting visual effects by cycling (shifting) the color palette. Back then video cards could only render 256 colors at a time, so a palette of selected colors was used. But the programmer could change this palette at will, and all the onscreen colors would instantly change to match. It was fast, and took virtually no memory.

There's a neat optimization going on here too: instead of clearing and redrawing the entire scene with each frame, he only updates the pixels that change:

In order to achieve fast frame rates in the browser, I had to get a little crazy in the engine implementation. Rendering a 640x480 indexed image on a 32-bit RGB canvas means walking through and drawing 307,200 pixels per frame, in JavaScript. That's a very big array to traverse, and some browsers just couldn't keep up. To overcome this, I pre-process the images when they are first loaded, and grab the pixels that reference colors which are animated (i.e. are part of cycling sets in the palette). Those pixel X/Y offsets are stored in a separate, smaller array, and thus only the pixels that change are refreshed onscreen. This optimization trick works so well, that the thing actually runs at a pretty decent speed on my iPhone 3GS and iPad!

Categories: Communities

Looking at JS emulator core for GameBoy

Sun, 07/25/2010 - 05:29

JavaScript as a general-purpose "Turing-complete language" is illustrated - the example discussed in the first part of a series:  How a CPU can be emulated through JS, and how one might start building an emulation core for the GameBoy console. Looking forward:  How a game image can be loaded into the emulator over the Web. For now: Hello, Z80! Check out Ice Station ImRannazar!

Categories: Communities

Dojo 1.5 is Out and it’s Feature Packed!

Thu, 07/22/2010 - 20:06

The Dojo project continues to pump out goodness announcing version 1.5 of the Dojo Toolkit with a number of new and exciting features.

Dylan Schiemann had this to say about the release:

The JavaScript world is evolving at an intense pace. We're very pleased with this release of Dojo, which offers the stability needed for existing apps and browsers, while introducing some of the capabilities of building great apps of the future.

Some of the biggest updates came to the Dijit UI library with the addition of the new Claro theme which helps provide a nice desktop look-and-feel to web applications as well as improvements to the charting and drawing components of the library.

And Dojo team lead Pete Higgins added:

If you haven't seen the new theme Claro, you should. Julie Santilli and her awesome design team at IBM put some incredible design and style on top of an already stable and accessible UI library

The theme is incredibly clean. Check out some of the controls styled using Claro:




Other important updates include:

In addition, new initiatives are underway to provide solutions for the ever-growing and important mobile space:

This release continues the project's philosophy of modularity allowing developers to leverage the library for anything from simple DOM manipulation to full-blown RIA development. Dojo 1.5 is immediately available for download and sports impressive, updated documentation to get you started quickly.

Categories: Communities

A Little PIE with that CSS3?

Mon, 07/19/2010 - 17:51

Everyone's chomping at the bit to leverage new HTML5 and CSS3 features but with some older browsers not supporting them, hacks are still needed to make things work in a cross-browser fashion. We've seen libs that make things easier such as Remy Sharp's html5shiv and Modernizr and now we can add another one.

Jason Johnston's new PIE library makes it easy to rendering several of the most useful CSS3 decoration features within Internet Explorer versions 6 through 8. He took an interesting approach by using IE DHTML Behaviors to style the elements and provide the necessary functionality to emulate the CSS3 functionality. So to add rounded corners to an element, your CSS code might look like this in plain 'ole CSS:

PLAIN TEXT CSS: #myElement {
    background: #EEE;
    padding: 2em;
    -moz-border-radius: 1em;
    -webkit-border-radius: 1em;
    border-radius: 1em;
}
 

To add support in IE 6-8 using PIE, you'd add this:

PLAIN TEXT CSS: #myElement {
    ...
    behavior: url(PIE.htc);
}
 

PIE currently has full or partial support for:

  • border-radius
  • box-shadow
  • border-image
  • multiple background images
  • linear-gradient background images

Unfortunately, there seems to only be one demo at the moment, which is border-radius rendering via the home page, but it's still seems like a good start with a lot of future potential.

I've never personally used IE DHTML Behaviors or HTML Components so I looked them up and found these intro links for those who might be interested in better understanding them:

Using HTML Components to Implement DHTML Behaviors in Script
Introduction to DHTML Behaviors

Categories: Communities

It’s Friday. Take the time to learn the Web with a splash of French, German, and Irish

Fri, 07/16/2010 - 19:34

The week has been long. Much code has been written. There is much more to do, but Friday is for relaxing a little. Take some time, sit back and watch, as three fantastic videos are available for you:

French: Paul Rouget of Mozilla, shows you the future

Paul builds the best demos. ever. At the Mozilla Summit in Whistler, he shows off what you can do when you remix HTML5, CSS3, SVG, WebGL, and WebSockets. A must see.

German: Building an awesome social HTML5 engine

Paul Bakaus of Dextrose (and jQuery UI fame) recently launched the Aves Engine, a social gaming engine in pure HTML! Dextrose also joined forces with Effect Games to bolster its Web gaming might. Paul gave a talk at Google explaining the technology, and it just went live:

"Irish": Paul shows you jQuery c0de

Ok, Irish by name, and maybe a touch by nature.... but not by nationality. Paul Irish has been doing an amazing talk at conferences where he walks through the jQuery source code to teach you fun and frolics of JavaScript. He picked up ScreenFlow and did it again to reach you all. Paul is a gem in our community, and at 52 minutes.... you will still want more:

Have a great weekend!

Categories: Communities

Synthetic Event Library Syn Aims to Make Testing Easier

Wed, 07/14/2010 - 18:54

The team at Jupiter IT have release Syn, a library which allows you to create synthetic events for use in testing. This standalone library is meant to assist in testing complex UI behavior by simulating user actions such as typing, clicking, dragging the mouse.

Testing rich, dynamic web applications sucks. At Jupiter, we've tried almost every testing solution available (qUnit, Quick Test Pro, Selenium, JsUnit, Env.js, TestCase) and all of them suffer from some fatal flaw.

Problems:

  • Manual - A tester has to run the tests manually on every supported browser.  People are lazy. 
  • Unit Tests Only - We need to test the app as a whole and complex UI behavior like drag-drop.
  • Low fidelity - We need to make sure the tests are reporting accurate results.
  • Difficult to write - We sling JS like a ninja monkey throws poo.  We want to write tests in a nice JS API.
  • Expensive - A QTP license is 5k a person!  I'd rather buy a vacation.
  • Support - We want to test Mac and Linux browsers.

We've solved all of these problems in our upcoming FuncUnit testing framework. It's a mashup of qUnit, Selenium, Rhino, and Env.js. But its core library, Syn, which does the work of simulating user actions with very high fidelity, is what we are releasing today.

So by using code like this:

PLAIN TEXT JAVASCRIPT: Syn.click( {},'hello' )
   .type( 'Hello World' )
   .drag( $('#trash') );
 

you can simulate clicking an element with id='hello', typing "Hello World", and then dragging your mouse from that element to an element with id='trash'.

Pretty cool stuff. Check out their demo to see how playback occurs.

Categories: Communities

An alternative way to addEventListener

Tue, 07/13/2010 - 15:00

I can't believe none of us knew DOM2

This is how a tweet from @SubtleGradient, re-tweeted by @jdalton, has been able to steal my rest tonight ... and this post is the consequence ...

What's new in a nutshell

There is a W3C Recommendation about addEventListener behavior, which clearly specify the second argument as an EventListener.
The new part is that no library I know has ever used a proper EventListener interface, preferring the classic attached callback instead.

PLAIN TEXT JAVASCRIPT:

// this is how it is
document.addEventListener(
    "click",
    function (evt) { /* stuff */ },
    false
);
 
// this is how it could be as well
var listener = {
    handleEvent: function (evt) {

        this === listener; // true

        // and evt === classic event object

    }
};
 
document.addEventListener("click", listener, false); Benefits

The most common case that may disappear is well explained in this MDC addEventListener page.
Rather than bind inline or add anonymous functions to make our object call context preserved, we can simply add an handleEvent method to whatever object and pass it as EventListener.
Moreover, being close to full ES5 support and "use strict" directive where arguments.callee disappears, it may be more than handy to be able to perform such operation:

PLAIN TEXT JAVASCRIPT: document.addEventListener("click", {
    handleEvent: function (evt) {
        // 1 shot callback event example
        switch (evt.target.nodeType) {
            case 1:
            case 9:
                evt.target.removeEventListener(
                    evt.type,
                    this, // here we are!
                    false
                );
                break;
        }
    }
}, false);
  An opened door for custom listeners

As I have recently posted, custom listeners implementation can be truly handy when we are dealing with events driven applications, but as soon as I have read the tweet, I had to rewrite a fresh new way to create a listener. Please note that following code is assuming that the browser supports both DOM Level 2 and Array extras, which is true for all modern browsers, mobile oriented included.

PLAIN TEXT JAVASCRIPT: function createEventListener() {

    /*! Andrea Giammarchi for Ajaxian - Mit Style */

    // a function declaration reused internally
    function notifyEvent(callback, i, stack) {
        // use DOM Level 0 events strategy
        //  to stop the loop if necessary
        // checking if the result is exactly false
        if (callback.call(
            // the curent object as context
            this,
            // the classic event as first argument
            event,
            // the called callback (life easier)
            callback,
            // again the current context
            // if the callback has been bound
            this
        ) === false) {
            // if false, reassign the current stack ...
            eventListener["@"+event.type] = stack.slice();
            // ... and break the current forEach loop
            // (or, for the record, whatever Array.extras)
            stack.length = 0;
        }
    }

    var
        // local scoped object, reachable internally
        // usable as mixin so instances won't be polluted
        // with all possible event types
        // the type is prefixed in any case
        // so that name clashes should be
        // really rare however we use the object
        eventListener = {

            // we attach to a proper stack
            addEvent: function (type, callback) {
                var
                    // try to retrieve the stack ...
                    stack = (
                        // if already there ...
                        eventListener["@" + type] ||
                        // otherwise we create it once
                        (eventListener["@" + type] = [])
                    ),
                    // as addEventListener, don't attach
                    // the same event twice
                    i = stack.indexOf(callback)
                ;
                // so if it was not there ...
                if (-1 === i) {
                    // FIFO order via stack
                    stack.push(callback);
                }
            },

            // called via addEventListener
            // the "this" reference will be
            // the eventListener object,
            // or the current instance
            // if used as "class" mixin
            // or via Object.create / clone / merge
            handleEvent: function (e) {
                // retrieve the stack
                var stack = eventListener["@" + e.type];
                // and if present ...
                if (stack) {
                    // set temporarily the local event var
                    event = e;
                    // notify all registered callbacks
                    // using current this reference
                    // as forEach context
                    stack.forEach(notifyEvent, this);
                    // let the GC handle the memory later
                    event = null;
                }
            },

            // how we remove the event, if any ...
            removeEvent: function (type, callback) {
                var
                    // try to retrieve the stack ...
                    stack = eventListener["@" + type],
                    // find the index ...
                    i
                ;
                // if the stack is present
                if (stack && ~(
                    i = stack.indexOf(callback)
                )) {
                    // remove it
                    stack.splice(i, 1);
                }
            }
        },

        // I could have called this variable tmp
        // but it's actually the current event
        // once assigned ... so ...
        event
    ;

    // ready to go!
    return eventListener;

}

Here a usage example:

PLAIN TEXT JAVASCRIPT: var lst = createEventListener();

/** mixin example (add a slash before this line to test)

function MyEventListener() {}
MyEventListener.prototype.addEvent = lst.addEvent;
MyEventListener.prototype.handleEvent = lst.handleEvent;
MyEventListener.prototype.removeEvent = lst.removeEvent;

lst = new MyEventListener;

// */

document.addEventListener("click", lst, false);

lst.addEvent("click", function click(e, callback, object){

    alert([
        callback === click, // true
        this === lst,       // true
        this === object,    // true
        e.type === "click"  // true
    ]);

    // test that furthermore this
    // callback won't be fired again
    this.removeEvent("click", callback);

    // add delayed a callback
    // without any valid reason :-)
    setTimeout(function (self) {
        // test addEvent again
        self.addEvent("click", function () {
            alert(2);
        });
    }, 0, this);

    // block the current notification
    return false;
});

// the event fired only the second click
lst.addEvent("click", function () {
    alert(1);
});

/** de-comment the mixin example to test
//   that no @click is attached ;-)
for (var key in lst) {
    alert(key);
}
// */
  Advantages

  • both evt.stopPropagation() and evt.preventDefault() are not able to break the current notification of all attached listeners, if added to the same node, and while the FIFO order gives to the node "owner" or creator the ability to pollute the event object with some flag such evt.pleaseDontDoAnyOtherActionHere = true, not every library, script, or framework, may respect or understand this flag. With custom events we can adopt better strategies to actually avoid any other operation if this is what we meant, because we arrived before over the node and we may like to be that privileged
  • being custom, we can also decide which argument should be passed for each callback, simplifying most common problems we may have when dealing with listeners
  • we can better decouple DOM and listeners, being able to remove whatever amount of callbacks simply calling once node.removeEventListener(evt.type, this, false); inside any kind of notification
  • being based on standard and modern browsers, we can use native power, in this case provided by forEach and indexOf operations, so that performances will be best possible
  • thanks to automatic context injection, we can still reuse callbacks for different listeners, through bind, or simply considering the current context once called (or in this case the third argument by reference, if the context is different)

Last but not least, if we would like to fire an event we can bypass DOM initialization using handleEvent directly, e.g.

PLAIN TEXT JAVASCRIPT: lst.handleEvent({
    target: document.querySelector("#myid"),
    type: "click",
 
    // custom properties
    pageX: 0,
    pageY: 0,
 
    // stubbed methods
    preventDefault: function () {},
    stopPropagation: function () {}
});
  Compatibility ?

Apparently both W3C behavior and provided examples are compatible with every modern browser with DOM Level 2 support, and I believe this is great.
The only one behind here is IE9 pre 3, but again @jdalton has acted at speed light, thanks!

Categories: Communities

Quilt: Stitching Your JavaScript Modules Together

Tue, 07/13/2010 - 14:00

It floors me what young, talented developers are building these days. Kit Goncharov, who only recently turned 17, just cranked out Quilt, a JavaScript preprocessor written in JavaScript.

Quilt is very similar to the Sprockets JS preprocessor in that it allows you to improve code organization by logically separating your code into multiple modules within their own specific directories. Instead of having one massive JavaScript file with all your source code in it (increasing the potential for errors and complications), you can break out your code into separate physical files and at build time, allow Quilt to roll it all up, line by line, into a single file, ready for deployment. Via support for directives, you can tell Quilt about dependencies to ensure your builds are structured the right way.

In addition, if you use third-party frameworks in your code, Quilt allows you to specify a "load path" or "search path" which tells the preprocessor where to look for your specific lib. Then, when you build the final concatenated output, the library is included right in the source code.

Although Quilt was heavily inspired by Sprockets, it does have several significant differences. Perhaps the most obvious is that it's written in pure JavaScript (as opposed to Ruby) and runs on Rhino. This means it's very portable and easy for JS developers to understand. Quilt also uses a slightly different syntax than Sprockets for including files (for instance, it allows single-quoted pathnames, and uses backticks instead of angle brackets for specifying third-party code), and can strip multi-line comments as well as single-line ones.

As our client-side applications continue to grow, these types of solutions are becoming increasingly important for having a well-structured and maintainable codebase and it's great to see that the future development leaders are taking that into consideration. Be sure to check out Quilt along with Kit's other projects on GitHub.

Categories: Communities

Strobe; A hot new HTML5-touch startup founded by Charles Jolley

Mon, 07/12/2010 - 14:03

Charles Jolley: "I started working in SproutCore almost 5 years ago because I believe the future of software development lies in native-style apps in the web browser. It is the platform of the future and when that shift change happens, I want to be there with the technology. Now, I believe that time is almost finally upon us. It’s time to double down, and that is why I am leaving Apple."

Congrats to Charles as he starts a new adventure. At Apple, he lead the charge on the open source SproutCore framework which powers Mobile Me and a bunch more.

He recently showed off SproutCore Touch and with it a killer demo. Instead of just saying "the Web can do as good a job as 'native' apps for some purposes" he showed it. He and SproutCore folk were there with two iPads. One had the native iPad NPR app, and the other had a *week long* port to SproutCore Touch. The funny thing.... the touch version performed better and even had a nice hidden feature. If you are listening to NPR and go to another app, it kept playing! Who knew!

For anyone wondering what the new company means for SproutCore, Charles makes it clear:

First, SproutCore is now and will always be totally free and open source. I think this business of charging for a commercial license is not an effective way to grow a project. Sure you make a little cash, but at what expense to the community? My goal is to make SproutCore and all of the developer tools that surround it totally free to everyone. All I ask is that you participate in the community somehow to make things a little better for those who come after you.

Second, now that I am no longer held back by big-company legal restrictions, I am going to be much more involved with the platform. Very soon I will post some new example code. Some others are working on new documentation and build tools to ease that pain as well. Starting this fall, my new company will also start to offer online and in person training and mentoring courses to your team get up to speed quickly. We can also finally get started in that book.

My goal is that by the end of the year, any average developer can pick up SproutCore, build, and deploy a basic app without feeling lost. This is open source and I can’t usually guarantee timelines but at least now we can do what we need to make it happen.

With Strobe he wants to revolutionize "digital publishing". Put your thinking hats on to noodle on that one. One thing is for clear... it isn't just about making SproutCore Inc (as he discusses above).

Congrats Charles!

Categories: Communities

Ben and Dion Step Down as Editors of Ajaxian.com

Wed, 07/07/2010 - 22:48

In the spring of 2005, the two of us gave our first Ajax talk together. The subject of the talk was DHTML, but Jesse James Garrett had just coined "Ajax" a few days previous, so we sprinkled the term throughout the slide deck. We needed a place to put some source code that accompanied the talk--an RSS reader was called "RSS Bling". Ajaxian.com was born.

Here's a random picture someone took of us right before we gave that first talk:

Ben and Dion hacking away on their talk

(Surely we're just reviewing the slides in this pic, not hurriedly hacking together something at the last minute.)

Because the Ajax space was moving so quickly, we wanted a place to track the fun hacks, great libraries, and fantastic showcases that were coming out daily, so we started using Ajaxian to post Ajax news and very occasionally, an editorial. It's fun to think back to those early times; the web world was drunk with new possibilities and no one was really quite sure how the draw the boundaries.

After a few months, things were moving so fast we thought it would be great to get the emerging Ajax community together. With help from Jay Zimmerman of No Fluff Just Stuff and Chris Haven, we put together the first Ajax Experience show in San Francisco. It was incredibly fun seeing so many of the folks in person we'd been covering on the site, and sharing with the broader developer community what was now possible.

Dion blesses the crowd at the first Ajax Experience

Our little Ajaxian blog grew over time--we still remember with awe when someone compared the traffic Ajaxian sent them to Slashdot--and we've gone on to co-produce several more Ajax Experience shows. It's been a thrilling ride.

Now, years later, it's time for us to formally hang up our Ajaxian hats. We've always juggled the site with our full-time jobs (various start-ups, Google for Dion, Mozilla, Palm, and now HP), and posting daily while balancing families and work can wear on you after a while--we can't do it all anymore. TechTarget (the company that has owned Ajaxian.com for some time) will take on editorial ownership of the site. We will still carry on posting every so often--it's in our blood--but it won't be on a regular schedule.

This transition comes at an important time for us. Palm was an opportunity to show the world that an OS based on the Web can be fantastic, but now, with HP's resources behind Palm, there's an even bigger opportunity ahead that will require all of our focus and energy. Oh, and it's summer, too. :-)

Thanks for being there for us over the years. We look forward to the next series of adventures. With HTML5 continuing to build steam and browser innovation hotter than ever, it is going to be a great time for us Web folk.

As always, you can keep up with us on Twitter: Ben and Dion.

All the best,

Ben and Dion

Categories: Communities

Firefox 4 with lots of speed improvements and inline SVG

Thu, 07/01/2010 - 17:26

Mozilla went to London, England yesterday night to give a workshop about Mozilla Add-Ons and show some of the cool new stuff coming in Firefox 4.

Probably the most impressive thing (next to the new Add-Ons Builder based on Bespin) was the upcoming Features of Firefox 4:

  • HTML5 Video display
  • Painting with Canvas
  • Image manipulation with Canvas – pixel testing, face detection with opencivitas
  • Green screen technologies in images and video by detecting pixel colours.
  • HTML5 embedded inside SVG (yes!)
  • SVG as an IMG
  • SVG as a CSS background
  • SVG filter/mask/clip
  • SVG animations
  • Inline SVG inside HTML5
  • CSS3 (selectors, @font-face, 2D Transforms, Transitions, Shadow, Gradients ,calculations – calc(2em-10px) )
  • APIs: Geolocation, Offline (IndexDB, localStorage, AppCache, FileAPI – binary content of a file input, file drag and drop, web workers, websockets)
  • Websockets controller running the presentation from the mobile.
  • WebGL

They proved some of the points with demos:

CSS3 filters and SVG masking on HTML5 Video:

Highly interactive video interface with SVG masking and transitions:

WebGL in Firefox 4 and on Android:

After this, Tristan Nitot covered some of the other features of Firefox 4, especially the upcoming speed improvements:

As to upcoming features to the core of Firefox, we heard about:

  • TraceMonkey (a new Javascript engine)
  • Lazy Frame Construction
  • Reducing I/O from the main thread
  • Improved startup Time
  • Hardware accelleration
  • GPU text/graphics/video rendering
  • Using GPU for text rendering
  • JavaScript JIT (JaegerMonkey)
  • HTML5 parser running own thread
  • slicker interface
  • no more modal dialogs
  • no startup interuptions
  • updates in the background

For an in-depth report on all the things shown, check out this live blog post.

Categories: Communities

Keep your vows; Keeping wed to Node

Thu, 07/01/2010 - 13:14

Vows can be a beautiful thing. Alexis Sellier of LESS fame, is becoming an open source star. This time around he brings us Vows an asynchronous-friendly behavior driven development framework for Node.js.

Write you BBD specs like this:

PLAIN TEXT JAVASCRIPT: // division-by-zero-test.js

var vows = require('vows'),
    assert = require('assert');

// Create a Test Suite
vows.describe('Division by Zero').addBatch({
    'when dividing a number by zero': {
        topic: function () { return 42 / 0 },

        'we get Infinity': function (topic) {
            assert.equal (topic, Infinity);
        }
    },
    'but when dividing zero by zero': {
        topic: function () { return 0 / 0 },

        'we get a value which': {
            'is not a number': function (topic) {
                assert.isNaN (topic);
            },
            'is not equal to itself': function (topic) {
                assert.notEqual (topic, topic);
            }
        }
    }
}).run(); // Run it
 

and you get a very nice report card out of the other end:

With macros you end up with very nice DSL syntax such as:

PLAIN TEXT JAVASCRIPT: {   'GET /': {
        topic: api.get('/'),
        'shoud respond with a 200 OK': assertStatus(200)
    },
    'POST /': {
        topic: api.post('/'),
        'shoud respond with a 405 Method not allowed': assertStatus(405)
    },
    'GET /resources (no api-key)': {
        topic: api.get('/resources'),
        'shoud respond with a 403 Forbidden': assertStatus(403)
    },
    'GET /resources?apikey=af816e859c249fe'
        topic: api.get('/resources?apikey=af816e859c249fe'),
        'shoud return a 200 OK': assertStatus(200),
        'should return a list of resources': function (res) {
            assert.isArray (res.body);
        }
    }
}

// or even
{
  'GET  /':                   respondsWith(200),
  'POST /':                   respondsWith(405),
  'GET  /resources (no key)': respondsWith(403)
}
 

The website itself goes into exquisite detail on the install process, sample usage, and more. The website also happens to be beautiful itself, and full of HTML5 markup to boot.

Categories: Communities

The death of the pixel as we know it; The new DPI web

Wed, 06/30/2010 - 18:17

The Web used to be so simple. Browser request goes to server, where you do some work, and return some HTML. Then we got Ajax and finally web apps could have some semblance of UI responsiveness. Now we have richer HTML5 technologies to change expectations of our users once again.

The Web is getting some new DPI love, and the new iPhone 4 display personifies this fact. The new display is fantastic for the consumer, and an opportunity for the design enlightened to build truly beautiful web sites. There is a big difference:

However, how do we as developers deal with this new world?

Aral Balkan has a nice post that goes into detail on the new opportunity and shares samples and ideas.

As with so many things on the Web, some of this has been thought of a loooong time ago. Dave Hyatt wrote about this back in 2006.

Walt Dickinson put together a guide to the retina display and using CSS3 media queries:

PLAIN TEXT CSS: <link rel="stylesheet"
    type="text/css"
    href="/css/retina.css"
    media="only screen and (-webkit-min-device-pixel-ratio: 2)"
/>
 

Aral explains that "in the Retina-specific CSS, he loads in 32x32 icons as background images and specifies their dimensions in CSS pixels as 16x16 using the background-size CSS property."

It is interesting to see a device pixel ratio used rather than specifying a DPI itself.

What else can be done to help folks in this new world?

Aral talks about how the browser could natively help via convention:

I'd like to suggest that browsers adopt the same naming convention that Cocoa Touch uses to find and load high-DPI versions of image and video assets. That is, if I embed an image using the following code…

PLAIN TEXT HTML: <img src="flower.jpg" alt="A beautiful rose"/>
 

… it should load in flower.jpg when the device-pixel-ratio is 1 but it should attempt to find an image called flower@2x.jpg at the same relative path if device-pixel-ratio is 2 (and so on, for higher pixel-ratios), falling back to the original graphic if it can't find a high-resolution version.

(And the same convention could be used to load video assets.)

Maybe there are server side techniques that could be put in place to automatically serve up the most optimized image for a given DPI. This would stop a bunch of 404s, but requires more work on the part of the server monkey.

This is good news for SVG and libraries like Raphael, who are well suited for scaling. When playing with an iPhone 4 it was amazing how quickly you noticed the bitmaps that were too low res... they stick out like a sore thumb. Expectations have changed.

What else can we do?

Categories: Communities

jQuery.fn.webkitTransform: bananas on the skew-whiff

Wed, 06/30/2010 - 14:01

Franz Enzenhofer has created a nice new webkitTransform plugin that helps you manage transforms and state.

Franz tells us more:

With jQuery.css you can't easily change the webkitTransform CSS because webkitTransform is not your average CSS.

If in one step you add .css('-webkit-transform', "rotate(20deg)") and in the next step .css('-webkit-transform', "scale(2.0)") the rotate value gets reset, as you have rewritten the complete -webkit-transform CSS value.

You could use the WebKitCSSMatrix javascript element, but it's currently buggy, not consistently implemented and a pain to use.

Additionally you can't just retrieve the '-webkit-transform' css with .css('-webkit-transform') as this just gives a matrix code.

Our goal with webkitTransform() was to fix this problem. With it, every element you assign webkit-transform css with can be edited in a simple way, without resetting every other -webkit-transform values.

Categories: Communities

HTML5 Video; YouTube Perspective

Wed, 06/30/2010 - 13:16

The YouTube API blog put their point of view on HTML5 video on the table. I would love to know why they felt like this was the right time, and what their angle is. I find myself often confused with the Google strategy. On one hand they are doing amazing things for the Open Web (Chrome, tools, Steve Souders and Web performance work), but on the other we see an alignment with Adobe and Flash (a differentiator to Apple).

Man, I am torn. The pragmatist totally gets it. But the guy who realizes that it was the Web openness that allowed the likes of Google come from nothing to the powerhouse that it is today in a decade, gets confused.

If you are a Flash fan you see this as "see! Flash is here to stay!" As someone who wants to see the Web standards get better fast, we see some of the momentum (fact that we have audio and video, and the WebM codec) and features that we need to get in:

Robust video streaming

Closely related to the need for a standard format is the need for an effective and reliable means of delivering the video to the browser. Simply pointing the browser at a URL is not good enough, as that doesn't allow users to easily get to the part of the video they want. As we’ve been expanding into serving full-length movies and live events, it also becomes important to have fine control over buffering and dynamic quality control. Flash Player addresses these needs by letting applications manage the downloading and playback of video via Actionscript in conjunction with either HTTP or the RTMP video streaming protocol. The HTML5 standard itself does not address video streaming protocols, but a number of vendors and organizations are working to improve the experience of delivering video over HTTP. We are beginning to contribute to these efforts and hope to see a single standard emerge.

Content Protection

YouTube doesn't own the videos that you watch - they're owned by their respective creators, who control how those videos are distributed through YouTube. For YouTube Rentals, video owners require us to use secure streaming technology, such as the Flash Platform's RTMPE protocol, to ensure their videos are not redistributed. Without content protection, we would not be able to offer videos like this.

Encapsulation + Embedding

Flash Player's ability to combine application code and resources into a secure, efficient package has been instrumental in allowing YouTube videos to be embedded in other web sites. Web site owners need to ensure that embedded content is not able to access private user information on the containing page, and we need to ensure that our video player logic travels with the video (for features like captions, annotations, and advertising). While HTML5 adds sandboxing and message-passing functionality, Flash is the only mechanism most web sites allow for embedded content from other sites.

Fullscreen Video

HD video begs to be watched in full screen, but that has not historically been possible with pure HTML. While most browsers have a fullscreen mode, they do not allow javascript to initiate it, nor do they allow a small part of the page (such as a video player) to fill the screen. Flash Player provides robust, secure controls for enabling hardware-accelerated fullscreen displays. While WebKit has recently taken some steps forward on fullscreen support, it's not yet sufficient for video usage (particularly the ability to continue displaying content on top of the video).

Camera and Microphone access

Video is not just a one-way medium. Every day, thousands of users record videos directly to YouTube from within their browser using webcams, which would not be possible without Flash technology. Camera access is also needed for features like video chat and live broadcasting - extremely important on mobile phones which practically all have a built-in camera. Flash Player has provided rich camera and microphone access for several years now, while HTML5 is just getting started.

Time to knuckle down and deliver great new video features in the browsers!

Categories: Communities

IE9 gets a Web Timing API to measure performance

Wed, 06/30/2010 - 10:15

Web site performance is a very important topic. We should not let our end users wait for our sites and optimizing them for load time and rendering can save us thousands of dollars in traffic. There is a lot of great content out there on performance (spearheaded by Yahoo a few years back). When it comes to testing the performance after the page has loaded though there is a lot of things you can do wrong as you need to test things with timers and hope nothing else happening to your test machine interferes with your results.

The IE9 team wants to make it easier for developers and added a new Web Timing API in the browser. Web Timing is a W3C working draft and the API implemented the NavigationTiming part of the spec in window.msPerformance.timing and offers you a few sets of information without having to hack your own solution:

PLAIN TEXT JAVASCRIPT: interface MSPerformanceTiming{
     readonly attribute unsigned longlong navigationStart;
     readonly attribute unsigned longlong fetchStart;
     readonly attribute unsigned longlong unloadStart;
     readonly attribute unsigned longlong unloadEnd;
     readonly attribute unsigned longlong domainLookupStart;
     readonly attribute unsigned longlong domainLookupEnd;
     readonly attribute unsigned longlong connectStart;
     readonly attribute unsigned longlong connectEnd;
     readonly attribute unsigned longlong requestStart;
     readonly attribute unsigned longlong requestEnd;
     readonly attribute unsigned longlong responseStart;
     readonly attribute unsigned longlong responseEnd;
     readonly attribute unsigned longlong domLoading;
     readonly attribute unsigned longlong domInteractive;
     readonly attribute unsigned longlong domContentLoaded;
     readonly attribute unsigned longlong domComplete;
     readonly attribute unsigned longlong loadStart;
     readonly attribute unsigned longlong loadEnd;
     readonly attribute unsigned longlong firstPaint;
     readonly attribute unsigned longlong fullyLoaded;
}

You have even more granular control in timingMeasures

PLAIN TEXT JAVASCRIPT: interface MSPerformanceTimingMeasures{
     readonly attribute unsigned longlong navigation;
     readonly attribute unsigned longlong fetch;
     readonly attribute unsigned longlong unload;
     readonly attribute unsigned longlong domainLookup;
     readonly attribute unsigned longlong connect;
     readonly attribute unsigned longlong request;
     readonly attribute unsigned longlong response;
     readonly attribute unsigned longlong domLoading;
     readonly attribute unsigned longlong domInteractive;
     readonly attribute unsigned longlong domContentLoaded;
     readonly attribute unsigned longlong domComplete;
     readonly attribute unsigned longlong load;
     readonly attribute unsigned longlong firstPaint;
     readonly attribute unsigned longlong fullyLoaded;
}

Read the original post on MSDN and check out the demo on IE Test Drive

Categories: Communities

ChromeKit: Some folk love putting windows in browsers

Tue, 06/29/2010 - 13:10

The awesome Guillermo Rauch and Nathan White have taken one of the Web code katas and played with it. Before the Web we had [wW]indows. Maybe that is why developers are keen to implement windows within the Web page, mainly to see if it can be done. We had the great Emil and Erik building desktops on the Web before we were in Web nappies. Now we have Ext Desktop, and many more.

The latest fun from Guillermo and Nathan is ChromeKit, which gives you windows that look like Google Chrome.

The one tweak to the code kata this time around, is their use of CSS3 goodness to show off skewing windows as they are tiled together.

Categories: Communities