Aug 22

TraceMonkey: DOM, Canvas, Opensource and more

Ajax, JavaScript, Tech with tags: 6 Comments »

Brendan Eich promised that trace based JIT’s will give us killer JavaScript speed and now we have seen the fruit of his labour with TraceMonkey (adds trace smarts to Tamarin-tracing).

A lot has been said already, but I am really excited about much more than the “look at how we run Sun Spider”.

The DOM matters

Although it may not sure in todays code drop, Brendan gets that you have to care about the DOM and not running while(1) { cheasyTest(); }:

  • He gets it: “As we trace more of the DOM and our other native code, we increase the memory-safe codebase that must be trusted not to have an exploitable bug.”
  • If DOM code comes out of native code and into JavaScript, it matters: “TraceMonkey advances us toward the Mozilla 2 future where even more Firefox code is written in JS. Firefox gets faster and safer as this process unfolds.”

Canvas

You know Canvas? It’s days are coming… fast, as John Resig mentions:

One area that I’m especially excited about is in relation to Canvas. The primary thing holding back most extensive Canvas development hasn’t been rendering – but the processor limitations of the language (performing the challenging mathematical operations related to vectors, matrices, or collision detection). I expect this area to absolutely explode after the release of Firefox 3.1 as we start to see this work take hold.

Opensource matters

None of this could be accomplished without the great side of opensource. TraceMonkey uses Tamarin-tracing, which enables it to build on amazing code.

TraceMonkey itself is opensource, which enables the SquirrelFish team say, to check it out. And, vice versa. This will keep the competition going along nicely.

This kind of competition is phenomenal for us, the consumers of the Web. Performance is key in 2008, and Web developers get to laugh all the way to the bank.

Thanks guys!

Aug 22

Where are you? Using the new Ajax ClientLocation API

Ajax, Gears, Google, Mobile, Tech with tags: , 22 Comments »

We just announced two new ways to get location info from a browser client.

The Gears GeoLocation API is very detailed. It is able to use GPS, cell towers, WiFi, and ip addresses to work out the location, and you get an “accuracy” parameter to see what was available. As well as getting a position, you can watch a position so you are updated when a change happens. This is perfect for mobile devices that have Gears installed, and since the community is working on the W3C Geolocation spec it should be in many more places soon.

To go with the Gears API, we also have an API that goes along with the AJAX APIs, called ClientLocation.

This is an ip based geocoder that we have made available, and is very simple.

I put together a trivial example called Where Are You? that ties together this API with the Maps API:

You get access to the data from google.loader.ClientLocation, which is null if it can’t be calculated.

Here is a bit of JavaScript that ties it together:

google.load("maps", "2.x");
 
google.setOnLoadCallback(function() {
    if (google.loader.ClientLocation) {
        var cl = google.loader.ClientLocation;
        var location = [cl.address.city, cl.address.region, cl.address.country].join(', ');
 
        createMap(cl.latitude, cl.longitude, location);
    } else {
        document.getElementById('cantfindyou').innerHTML = "Crap, I don't know. Good hiding!";
    }
});
 
function createMap(lat, lng, location) {
    var mapElement = document.getElementById("map");
    mapElement.style.display = 'block';
    var map = new google.maps.Map2(mapElement);
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new google.maps.LatLng(lat, lng), 13);
    map.openInfoWindow(map.getCenter(), document.createTextNode(location));
}
Aug 08

JavaScript 2: A Perl 6 disaster, that matters so much more, but wait…

Ajax, JavaScript, Tech with tags: 10 Comments »

I had a post in my queue relating JavaScript 2 to Perl 6. They are both in very rough spots indeed, yet JavaScript 2 has a couple of features that have me a lot more worried than I am about Perl 6:

  • No offense to Perl (a language I really love, and I have code in CPAN) but JavaScript is an immensely important tool on the Web
  • Unlike Perl, there are no dictator groups who can clean up. The politics are politics. If a certain someone doesn’t implement, you are in big trouble.

I have been hacking more and more on JavaScript (1.0, Brendans toy!) recently, and the more I do so, the more I like it. I worked out some years ago that it was the DOM and cross browser issues that I didn’t like, not the language.

I do wish that there was a standard library for JavaScript (Dojo does a good job). I do find myself reinventing the wheel a lot when it comes to the Object world. This week I will be in a Class.create() kinda mood. Other times I would fancy some new function() magic, and other times a bit of (function() { functions; return { ... } })(). Now I try to use the right tool for the job, but the problem is reading other peoples code.

Take a peek at the Firebug source and you will see the following at the top of each module:

FBL.ns(function() { with (FBL) {

Joe Hewitt likes with() :)

This is where it starts to feel a lot like Perl. Many ways to do one thing, and when that one thing is so core as packaging and modularization, it shows through. This is also a reason why we are in pain with components. If someone writes a great component for Dojo but you are using Prototype, you curse. What is the real difference? The darn packaging! dojo.hitch() versus function.bind(). These changes go so deep though, that it would be quicker to write from scratch.

I would love an import/include statement. Finding myself dynamically creating script elements to do a script src is starting to get a little silly. The language itself should just support that.

JavaScript 2 is helping us with packaging, but in my opinion, it used to have too much in it. Programming units, packages, namespaces, that is just too much to wrap your head around.

I am also not a fan of the optional static typing. That is fine for ActionScript, but I don’t think JavaScript needs it. This is a scripting language, something that can fit in a onclick="..." and I think the world is moving more towards the dynamic world (there is still a place for static). How about just allowing ActionScript to be written in the browser? Why try to boil the ocean with JavaScript, as Java has tried to do in the past. Work on the runtime, and allow multiple languages. This is already being done with IronMonkey and the like…. and Microsoft is doing a great job with that tactic in Silverlight. Work on an object model that can be shared, and then we can all go to town.

var self = this;

I see that too much too, even with the binders and the hitchers. The magic of var foo jumping to the top of the scope is weird too. But, all in all, JavaScript is pretty damn good! In fact, JavaScript 1.8, and what I hear about 1.9 is really nice too. I am all for cleaning up what needs to be cleaned up, and working on other stuff.

At this point in my draft I sat in the corner and cried, as I thought JS2 was in epic trouble, and that the walls were going to fall down. I didn’t know what to do. We had Brendan++ on one side, and Doug/Microsoft on the other (simplified version). I sit in between. Without some Harmony, what would happen to the Web?

Well, the reason that I can post this is because I heard that the ECMAScript meeting in Oslo was very promising indeed, and some Harmony may come out of it. Hopefully the news will get through the official process, and out in public as soon as possible, as there is new hope for us. I am sure there is still a long road, but with great people working together, we’ll get ‘er done.

Aug 06

Enjoying the Observer pattern with custom events

Ajax, Tech with tags: , , 26 Comments »

I created an introductory example discussing custom events as an implementation of the Observer pattern.

The example dynamically adds functionality based on checkboxes to simulate events that could change processing and uses the fire() and observe() methods from Prototype.

I strap on behaviour to a list of names. When you click on the name, something can happen. To do this I could have done the following:

$$('ul#leftchoices li').each(function(el) {
    el.observe('click', function(e) {
        if ($('colorchange').checked) {
           changeColor();
        }

        if ($('contentchange').checked) {
           changeContent(el.id);
        }
    });
});

In the click event itself, I do various checks and kick off behaviour. That can be fine for small actions, but what if you want to do more? This is when I prefer to abstract out the action and just fire an event:

$$('ul#leftchoices li').each(function(el) {
    el.observe('click', function(e) {
        el.fire('selected:choice');
    });
});

At this point, this bit of code becomes dumb. It doesn’t know what to do when you select the item, and it just hopes that somewhere, someone is listening. That is where the observers come in, such as this one that changes the main content based on the selected name:

$('contentchange').onchange = function(e) {
    if (e.target.checked) {
        document.observe('selected:choice', changeContent);
    } else {
        document.stopObserving('selected:choice', changeContent);
    }
}

When someone clicks on the checkbox, this method is fired and an observer is either added, or taken away.

Once you start building applications with this in mind, you may find a bit of a sea change. You start to think about the various events as a public API that you can easily expose to observers. Gone is the simple ability to look at one method and see what is happening, but the loose coupling gives you the ability to easily layer in your architecture. Based on some settings, behaviour can be dynamically added. You could even expose these events in a way that makes it easier for Greasemonkey hackers to come in and work with your application. All in all, a win-win for anything more than a simple example.

Although this example uses Prototype, you could do the same with the other top class JavaScript libraries. In fact, if someone wants to port this example to Dojo, jQuery, Mootools, YUI, or anything else, send me the files and I will put them up so we can all compare how custom events are done in the various toolkits.

UPDATE: We now have Prototype, jQuery, DOMAssistant, and Appcelerator versions. Thanks Malte!

Jul 04

Dealing with W3C Events; A story of running around in circles

Ajax, Tech with tags: , , 3 Comments »

I am working on an interesting pet project that has a fairly rich UI. A rich UI means dealing with events, and I had a wake up call on what a pain it can be to deal with in the browser world.

I ended up on a wild goose chase that ended up having a simple solution.

Imagine one section of an application that is a canvas element, and another piece that is a input type="text". I wanted a way to jump between the two with a keystroke, e.g. Ctrl-J for jump.

Jumping from the canvas element to textbox was fine, but it wouldn’t work on the way back. I was trying to $('canvas').focus() but it wouldn’t work.

initMouseEvent

I stupidly thought that I should just simulate the click on the canvas element, since that was working just fine for me.

We are pretty fortunate that the ability to kick off true events programatically is bound into the event model itself.

This means that I could:

if (document.createEvent) {
   var evt = document.createEvent('MouseEvents');
   evt.initMouseEvent('click',
            true,     // Click events bubble
            true,     // and they can be cancelled
            document.defaultView,  // Use the default view
            1,        // Just a single click
            0,        // Don't bother with coordinates
            0,
            0,
            0,
            false,    // Don't apply any key modifiers
            false,
            false,
            false,
            0,        // 0 - left, 1 - middle, 2 - right
            null);    // Click events don't have any targets other than
                      // the recipient of the click
 $('canvas').dispatchEvent(evt);
}

This only slightly worked. I could test that the click was going through. I would add an onclick handler to canvas and it would fire just fine. However, something weird was happening. The focus was still in the textbox even with this click happening (which didn’t happen when I actually clicked on the darn thing).

Events from within events

Since the click was working, why not just force the blur on the textbox?

var events = document.createEvent('HTMLEvents');
var blur = events.initEvent('blur', false, false);
his.dispatchEvent(blur);

But that got me:

Component returned failure code: 0×80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMEventTarget.dispatchEvent.....]

Hmm, on wait. This was happening from within an onkeypress handler and it appears that you can’t do this in a nested way. A setTimeout(..) to push it off until later didn’t make it any happier either.

tabindex=0

As I looked at this mess, I quickly realised that I had been unravelling a string, and I should take a step back.

I talked to Alex Russell, and he immediately said “erm, and you made sure that tabindex was set on the canvas element?”

Doh, it wasn’t. This is why the focus method (which did exist) didn’t do anything. I quickly added tabindex=-1 and now I could simply $('canvas').focus() and lo-and-behold it would focus!

Event.stop(e)

Great, the home stretch. I took the test and put it on the live code and it… still didn’t quite work. God damn it.

I took another step back.

A global key handler was set via document.onkeydown that was handling the world. When it saw a Ctrl-J it would short circuit and give focus to the textbox. The textbox has its own onkeydown that would do the opposite. A global flag held the state of global/textbox.

This is the problem. I had mucked up the event propogation, so in the case of jumping from textbox to canvas it would first go through the textbox handler, but after it was done it would STILL run the global handler which would kick it right back!

I just needed to e.stopProgagation(), or even better Event.stop(e) to stop any default action too.

Phew, all that running around to get back to square one. Now it works, and it reminded me of how the simplest things can be tricky.

Jun 17

Addressbook History goes into the cloud with App Engine

Ajax, JavaScript, Python, Tech with tags: 1 Comment »

I recently built an example of the Form History Pattern using an Addressbook case study.

I found myself talking about App Engine on the On Air tour, so I decided to change the example to not store the data locally with Gears, but instead to save it away into the cloud via App Engine.

RIBs

Why did people want to hear about App Engine at an Adobe conference? I think that Jonathan Schwartz got it when he mentioned rich internet back-ends. As you build rich clients, you suddenly realise that the promised benefits of web services can kick into gear nicely.

Addressbook Services

Back to the sample. The architecture change was quite simple. Where I was doing a local DB save, I would call a back-end service such as /loadcontacts or /savecontact depending on the task.

You can view and download the full App Engine project code for this sample, and you can see it running live on App Engine

Check out the video below, or view the high quality version (recommended) to see the code walk through, and the various tools that App Engine gives you to develop, debug, and monitor your application running at a few thousand feet.

Jun 11

I <3 YUI; When people take your comments the wrong way

Ajax, Tech with tags: 3 Comments »

Ben and I gave a talk on the “State of Ajax” at Google I/O a couple of weeks ago.

In there we had a couple of slides that talked about the prolification of Ajax frameworks. Our key points were:

  • There are so many freaking frameworks
  • We used to be able to separate the frameworks into camps. If you sterotype you have: Dojo as the standard lib for JavaScript; Prototype as the simple Ajax/JS wrapper; jQuery as the first CSS driven approach; GWT as the “Want to do Ajax without learning JavaScript and worrying about cross browser?”. These days we have seen normalization. Dojo Core is just as small as the other guys. Prototype and jQuery have plugin communities too. We have jQuery UI, Dijit/dojo.gfx to give you graphics effects a la Script.aculo.us.
  • At some point, depending on your requirements, pick one and get running with it.

We show the dart board morphing to just show a few frameworks. The major point there is to just get one and get going, not that we are blessing certain frameworks.

I started to get emails after the presentation that would say something like:

  • I use YUI. Should I switch to one of the frameworks you mention?
  • Why isn’t ExtJS on this short list?

When I met some of the YUI team last week they said that they had heard some of the same comments. I wanted to make it clear that YUI is a great framework, and based on learning about where they are going next, you are in good hands.

Alex Russell wrote a post on Gears De-Branding which took one (valid) shot at YUI, calling it a “source-available-but-not-open projects”. YUI currently doesn’t score as high as Dojo and the like and I think the YUI team gets that, and we will be seeing a change there in the near future.

Here is the entire presentation, which makes next to no sense without us talkng… but hey, pretty pictures!

Jun 09

Finding the right abstraction; Not repeating the same mistakes

Ajax, Tech with tags: No Comments »

Abstract Art

I got to meet (and interview) the crew behind 280 Slides, the beginning of “Keynote on the Web.”

The application looks like an Apple.app for a reason. Two of the crew jumped from USC to Apple, and drank the Steve-aid of compelling user experience, the Mac-way.

Francisco built the beginnings of Objective-J at school, and then resurrected it later.

When they wanted to build rich Ajax applications, they wanted to use the toolchain they were used too, and thus they continued the work of porting Objective-C to Objective-J, and Cocoa to Cappuccino.

The podcast talks about how the runtime itself loads .j files and on the fly munges to JavaScript and runs. There isn’t a compilation step (e.g. like GWT generating JavaScript from Java).

280 Slides is the first application built on the framework, and people are talking about it. It seems like we have two differing views:

  • “Why would you go to ALL of that work to build a framework that complicated instead of just building the darn application on a good Ajax framework like jQuery/Dojo/Prototype/…”
  • “Wow, I can’t wait to see this open sourced so I can build Mac-like software too”

I can see the allure of Objective-J / Cappuccino for building desktop-like Web applications. It gives you a very high level abstraction over the browser. No more DOM. No more CSS layouts, which can be the bane of your existence for a complicated and dynamic layout. If done correctly, it can allow you to not keep making the same mistakes.

Do you sometimes feel like you are fixing the same bugs again and again? If you do, then maybe you aren’t at the right abstraction?

Then, think about how hard it is to get copy and paste working across objects. Cappuccino gives this to you, and certain Web applications will love this.

Francisco Tolmasky had a good response to some concerns on the Ajaxian thread:

Let me first lessen your concerns by telling you that can *still* do string = “Today” + date. That’s the beauty of Objective-J, it’s both languages, which means you get all the benefits of JS, while still getting to have real classes and so forth.

Now, completely separate from this, is that no *language* truly makes writing applications easier. Sure, little pet peeves may come up here and there, but 90% of what happens in an application deals with the frameworks you use. I’m sure all the iPhone “problems” you’re having with Objective-C are more than compensated by all the amazing power you get from things like CoreAnimation, which is precisely why we wrote Cappuccino.

JavaScript does not have any way of writing applications today in the same way mature platforms like Cocoa do. Cappuccino provides you with very high level features like copy-paste (of anything), undo and redo, document management and archiving, vector graphics and animation, etc etc. when you write an application for Mac OS X or iPhone, you can truly focus *just* on your application, not whether it will work on some obscure browser or how to get something as simple as undo working, and that’s precisely what we are trying to provide.

Again, Cappuccino is not for everyone. There is an incredibly wide spectrum of web content out there, from completely static pages, to dynamic pages, to full blown applications. We *only* serve the latter. It would not make sense to put Cappuccino on something like Amazon.com, but 280slides would have been an incredibly more difficult task for a 3 person team like ours without having all of the foundation already complete.

Of course, if the high level abstraction is your muse, then you should make sure that you stay in that land. Gone are the days of mashing up other JavaScript code.

Trying to find the right level can be tough, depends on what you are doing, and more importantly…. the mojo that feels right.

Jun 05

IE Wishes; Time for a “Best Viewed In Any of These..” day?

Ajax, Tech, Web Browsing 6 Comments »

IE Wishes

I have been hearing the same tune recently, and it escalates: “Man, if we could just not worry about IE 6.” It sounds familar. Every few years, we get another popular but lagging usage that holds us back.

Imagine if the majority of people were still using phones from 2001 too:

Oh wait, sometimes it does feel that way doesn’t it?

We shouldn’t be blaming IE 6 itself of course. When it was released it was a great browser. We can’t forget how Microsoft had a large part to play in pushing the Web back in the day, bringing us DHTML itself, and offering up features that never caught on as people saw them as proprietary (behaviours are awesome for example).

So, we can’t blame the IE 6 engineers. We can get a little frustrated with the fact that new machines still come with IE 6 installed on them, even though IE 7 is out there, and IE 8 is making us all feel like Microsoft could care again.

Frank, Microsoft needs to push the button. The last four times I have had to do tech support for family or friends (I need the “just because I work for Google doesn’t mean that I can fix your computer” t-shirt) they were running IE 6. I couldn’t believe it. Some of these were fairly savvy folks too.

Say we get Microsoft, and IT folk, to push the button and push out IE 7 to the masses, we will still be short on a large part of the users. Namely, the folks across the world that are running Windows illegally. Will this ever end?

Maybe it is time for large sites to start a trend. On the first Monday of the month, when user comes to your site for the first time with a browser that isn’t Grade A you show them some kind of notice that “If you like this site running Browser X, you would like it so much more if you download any of these browsers”.

This isn’t about IE 6. This is about all browsers that are low on the pack. IE 6 happens to be the one that is talked about the most as it has the huge market share as well as being painful. This also isn’t about picking one browser. We aren’t saying “Download Firefox!” We are talking about downloading ANY grade A browser. Firefox, WebKit, or even IE 7!!!!

I never liked seeing the “Better viewed in IE/FF” images, but I think this is different. At some point we need to rev our platform. It is like the cars on the road. It isn’t enough to just improve fuel efficiencies in cars. We then need to get people to get rid of their gas guzzlers and buy the responsible one!

Jun 02

Finally a chance to reflect on the Ajax Libraries API / Google CDN JavaScript library hosting

Ajax, Google, Tech with tags: , 9 Comments »

I was really excited to launch the AJAX Libraries API (I know, I know, I hate typing “AJAX” too…. haven’t you seen the rotating header on Ajaxian? ;) at Google I/O this week.

The only problem with the timing was that at the same time that it was getting picked up by the trade rags, Wired, reddit, Slashdot, Ars Technica, etc…. I was busy getting prepared and working Google I/O! This made it hard to stay up on what was being said and really being there to comment etc.

All in all I was shocked at the level of response. I knew that developers would get it, but seeing tech journalists see value in something that isn’t flashy or even provide something “new” surprised me.

There have also been some really good comments, and tips such as this one showing a nice way to use the API side of the house (google.load vs. script src) and load your other libraries after.

I also like the Wordpress plugin that seamlessly mixes local development and “production”.

Steve Souders also had some good thoughts and stats.

The key though is what happens next. To get something out of the door for a version 1 release, you sometimes cut features and just get it out. We have some great libraries out there now, but I want to aggressively get more out. We are not trying to be king makers here. Ideally I would love a system where anyone can add their scripts, but this isn’t as easy as you would think. For one, how do you stop people from putting bad stuff on there (if you could upload anything, you could put god knows what there). One of the core goals is to have stable releases on the system only. We have to make sure that we have the rights to do this, which means that the libraries are open source in a way that we feel safe.

That being said, we want to do a better job at getting feedback on the libraries that you want to see up there, so I am hoping to do something about that soon.

Lastly, there is room to do so much more. Steve Souders can help us with the performance side of things and has great ideas on how a loader could really add a lot of value here (e.g. choose how to add a script to the page depending on the use case). Then we can work with the browser vendors and see if there is a way to aggressively cache these libraries even more. Gears itself could also have a cache module that could do this. We need to think hard about how a hashing algorithm could work here, and make sure that it couldn’t be hijacked. Brendan has me scared there.

So, overall I am excited to see how we can build on this first release, and help the community further. Please let me know what you would like to see.

Check out more coverage in the news and across blogs.