The uploader has been transitioned over from YUI2 to YUI3
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.
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!
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!
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
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.
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:
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:
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:
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.
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'.
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.
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:
document.addEventListener("click", {
handleEvent: function(evt){ // 1 shot callback event example switch(evt.target.nodeType){ case1: case9:
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.
// 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
;
// 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 returnfalse; });
// 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.
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!
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.
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).
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:
(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.
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.
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.
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(){return42 / 0},
'we get Infinity': function(topic){
assert.equal(topic, Infinity); } }, 'but when dividing zero by zero': {
topic: function(){return0 / 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:
{'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.
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.
<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…
… 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.