Matt RaibleMatt Raible is a Web Architecture Consultant specializing in open source frameworks.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Core HTML5 Canvas Book Review

Core HTML5 Canvas I've known David Geary for quite some time, from our original meeting in the blogosphere to speaking on the No Fluff Tour. At first, I had trouble respecting the guy because he was such a JSF Fanboy. However, over the years, he's switched to Ruby on Rails, GWT and now he's all about HTML5. Specifically, HTML5's <canvas> element. When David asked me if I'd like a copy of his lastest book, I jumped at the opportunity.

I received it in the mail shortly before heading to Hawaii this summer. I started reading it by the pool the next day.

I was immediately impressed that the book was printed in color. The first copy I ever saw of my Spring Primer was in color and it really popped. Geary's book does the same and I'm glad the publisher decided the extra cost of printing was worth it. In the preface (and in a recent blog post), David explains how he wrote the book code-first in the Zen tradition, so you can read it without reading. I saw him write somewhere that he spent 2 years, 60 hours per week writing it. It really shows - the sheer amount of code and knowledge in this book is amazing.

Looking back at the Table of Contents, I remember getting overwhelmed early on. Not overwhelmed in that I didn't understand how things were working, but more like "there's too much in here to try and remember it all". I haven't used algebra since high school, and right there on page 53 it says:

To do anything interesting with Canvas, you need a good basic understanding of basic mathematics, especially working with algebraic equations, trigonometry, and vectors.

Reading the book poolside wasn't a huge motivator to refresh my algebraic knowledge, but I did enjoy David's brief 10-page refresher. In Chapter 2 on Drawing, the book dives into the low-level API that canvas offers for drawing rectangles, circles and polygons. It also goes on to show you how to do gradients, patterns and shadows as well as all there is to know about paths, stroking and filling. This is when it hits you that <canvas> is more about JavaScript than HTML. In fact, it's usually only a couple lines of HTML and a whole lotta JavaScript.

In Chapter 3, you learn about text and how to work with fonts and paragraphs. David even spends 10 pages showing you how to implement a Paragraph, complete with positioning the cursor, adding new lines and working with backspace. It really makes you appreciate what HTML offers you with the good ol' <p> and <input type="text">.

Chapter 4 is where you learn about working with images and video, using offscreen canvases and working with a canvas within a canvas. I believe I was back in Colorado when I started reading this chapter. It's also where I succumbed to the fact that this was an excellent reference book and not something I was going to read, learn from and start using the next week. It feels like a book I'll refer back to many times when using <canvas> on a project. The amount of knowledge in the book seems akin to Rod Johnson's J2EE Development without EJB. I remember getting the general gist of Rod's ideas while reading the book, but not knowing how to put them into use. Then the Spring Framework was introduced and everything became clear. As I read Geary's book, I thought the same thing - someone really needs to develop a simpler API for Canvas.

As I read on, through chapters on Animations, Sprites, Physics, Collision Detection and Game Development, it hit me - maybe that's what David is doing!

Throughout the book, David builds a framework for working with Shapes, animating them and finally, for putting them to work in a gaming environment. The Ungame is nice in that it shows you how to use a game engine for building your own games. Then he goes on to show you a Pinball game that looks overly complex, but breaks it down into terms you can understand.

The last chapter is on Mobile development. It explains in detail about the viewport metatag, media queries for CSS and touch events. The section on iOS5 is good, but does make the book seem slightly outdated with iOS6 coming out next week. I'm sure all of the content is still relevant, but it almost seems like labeling it iOS5+ would've been better. In the final pages of the book, you learn how using a canvas that requires typing on a touch device might suck. David shows you how to implement a Virtual Keyboard to handle these situations, since the native keyboard won't pop up unless you're typing into HTML controls like <input> and <textarea>.

I read this book to learn more about Canvas and what it was capable of. I learned all it can do and much, much more. I learned how animations and timing can be different between browsers and how you might need to create a polyfill for requestAnimationFrame for it to work consistently.

More than anything, I recognized that this is one of the few technical books I've read in a long time that's become an instant valuable resource. With other books, the information is often available online. Not so with Geary's book. To me, it seems like the best resource available for learning and using HTML5 Canvas.

Well done, David, well done.

Posted in The Web at Sep 14 2012, 09:21:56 AM MDT 2 Comments

Refreshing Taleo's UI with HTML5, Twitter Bootstrap and CSS3

Back in December, I wrote about what I've been working on at Taleo. Shortly after finishing up the Profile Picture, Talent Card and Org Chart features for TBE, I spent two weeks doing page speed optimization. By following Web Performance Best Practices, I was able to make the TBE application twice as fast and improve its score into the low 90s.

Next, I started working on a new project - refreshing the UI. Nick, the Lead UX Designer at Taleo (at the time), had developed a number of mockups and presented it to the developers and product folks in early November. I listened to a WebEx of that meeting and learned that everyone thought it'd take 6-9 months to complete the work. They figured they could release the new design in Q3 2012.

Since I like to provide high-value for my clients, I offered to help with the redesign and do a spike to help estimate. They agreed it'd be a good use of my time and I started working on it the week before Christmas. Since I'd used Twitter Bootstrap for my Play More! app, I recommended we use it as a foundation of the redesign. They agreed and I went to work. By the end of the week, I'd made good progress and told them I thought the redesign was possible in 2-3 months (including QA and cross-browser compatibility).

When I came back to work in January, we decided to split the redesign into two phases. Rather than moving elements around and introducing new features, we decided to do that in the 2nd phase. The 1st phase would entail simply re-skinning the existing UI, with minimal HTML changes. I spent a week refining my spike and integrating it into a branch. The next week, I switched images from individual images to CSS sprites. Next, I implemented a new theming system with different colors/icons and got everything looking good in Chrome, Safari and IE8/9.

The result is something I'm quite proud of. IE8 doesn't have the rounded corners (via border-radius), but it still looks good. Forms look much better thanks to Bootstrap's styling and even jQuery UI's widgets look good thanks to jQuery UI Bootstrap. I did have to override quite a few Bootstrap styles in the process, but the result is something that doesn't look too bootstrappy.

One technique I found to be extremely useful during this process was to pair with Nick (the designer) as mentioned in Building Twitter Bootstrap. At one point, when we were trying to refine slight nuances and spacing in the UI, I paired with the Product Manager and found this to be a real time-saving effort as well.

Taleo's UI Refresh project has been a great experience for me in sharpening my CSS skills. I used quite a bit of child and sibling selectors, which work great in all the browser's we're supporting. Also, by using CSS sprites and colors (vs. images), I was able to get the manual theme-creation process down to around 15 minutes. After getting the manual process greatly reduced, I wrote a Theme Generator (based on Ant, LESS and wro4j) and got it down to mere minutes. I found Sprite Cow to be an invaluable resources for working with CSS sprites.

Below are some before and after shots of what we've been able to accomplish in the first quarter of this year.

Old UI - My View Old UI - New Employee

New UI - My View New UI - New Employee

I originally wrote this post at the end of January. We ran into some stumbling blocks shorty after its original composition: Nick (the designer) moved onto greener pastures and Oracle bought Taleo. What I didn't expect when I wrote this was to spend the next two months fixing slight bugs that occurred with spacing, alignment and dependent applications I didn't know about at the time. And then there was IE7. We didn't realize we needed to support it until mid-March. Then it took us around a month to make it all work good enough.

The good news is the UI Refresh was released a few months ago and seems to be humming along just fine. Sure, there were slight nuances and customizations we had conflicts with (clashing CSS classes), but overall it seems to have gone well. I can't thank the Bootstrap developers enough for motivating us to move to HTML5 and CSS3. Also, cheers to the excellent co-workers that helped make this happen: Murray Newton (Product Manager) and Vladimir Bazarsky. I couldn't have done it without you guys.

Posted in The Web at Aug 20 2012, 12:27:21 PM MDT 3 Comments

Twitter's Open Source Summit: Bootstrap 2.0 Edition

Every few months, Twitter hosts an Open Source Summit to talk about tools they're using. Since I happened to be near San Fransisco, I happily attended their latest #ossummit to learn about Bootstrap 2.0. Below are my notes from last night's event.

95% of Twitter's infrastructure is powered by open source. They hope to contributing back to open source by doing 2-3 summits per year. Without open source, there would be no Twitter. You can find a bunch of Twitter's open source contributions at twitter.github.com. They're also big fans of Apache and commit to a wide variety of projects there.

Bootstrap
Bootstrap is developed by two main guys: @mdo and @fat. Mark (@mdo) has been a designer at Twitter for 2 years. He started on the Revenue Team with ads, but has been working on redesign for last 4 months. Has been doing HTML and CSS for about 11 years. He used Notepad on Windows to build his GeoCities site.

boot·strap: simple and flexible HTML, CSS, and JavaScript for popular user interface components and interactions.

Work on Bootstrap started about a 1.5 years ago. Internal tools didn't get the proper attention they needed. They figured out there was a lot of people that wanted good looking UIs and interactions. It became Twitter Blueprint and was mostly used internally. Jacob (@fat) started shortly after first release and decided to add some JavaScript on top of it. The JavaScript for Bootstrap was originally the "Twitter Internal Toolkit" or "TIT" and was built on Moo Tools. Jacob was like "we gotta open source this, it's gonna be huge!" (he was right).

The 1.0 release supported Chrome, Safari and Firefox (everyone at Twitter was on Macs). 1.3 added cross-browser support and JavaScript plugins.

Now there's Bootstrap 2 (just released!). They rewrote all the documentation and components and removed legacy code.

So, what's new? The biggest thing is the docs. Previously had live examples, now shows live examples and why you would do something, as well as additional options. The "topbar" has been renamed to "navbar", but it's still got all the hotness. It's responsive with CSS media queries for small devices, tablets, small desktops and large desktops. This means the layout breaks at certain points and stacks elements to fit on smaller screens.

CSS: smarter defaults, better classes. In 1.4, all forms were stacked. Now they can flow horizontally. Tables are now namespaced so Bootstrap's styles don't apply to all tables. The available table, form and navigation classes are as follows:

// Tables
.table { ... }
.table-striped { ... }
.table-bordered { ... }
.table-condensed { ... }

// Forms
.form-inline { ... }
.form-search { ... }
.form-horizontal { ... }

// Nav
.nav { ... }
.nav-tabs { ... }
.nav-pills { ... }

The goals with 2.0 are consistency, simplification and future-proofing styles. With 1.4, buttons used "btn primary" and it caused problems if you wanted to have a "primary" class in your project. With 2.0, buttons and all elements are namespaced to avoid collisions (now it's .btn-primary).

After Mark finished talking about the design of Bootstrap, Jacob (@fat) started talking about Bootstrap's JavaScript. Jacob works on The Platform Team at Twitter and claims he made a lot of mistakes with 1.x. However, thanks to semantic versioning, 2.0 is a new version and he got to start over!

The biggest change in 2.0 is the use of data attributes (a.k.a. data-*). They were using them in 1.x, but not to the full potential of what they can be and should be. The first class API for Bootstrap JavaScript is data attributes (or HTML), not JavaScript.

With 1.x, you could add an anchor to close modals and alerts.

// 1.x closing modal/alerts
<a class="close" href="#">×</a>

However, if you put your alerts in your modals, you close them all when you likely only wanted to close one. 2.0 uses a "data-dismiss" attribute.

<a class="close" data-dismiss="model">×</a>

This allows you to target what you want closed (modals or alerts, etc.). You know exactly what's going to happen just by reading the code. Another example is the "href" attribute of an anchor. Rather than using "href", you can now use "data-target".

// 1.x href = target
<a href="#myModal" data-toggle="modal">Launch</a>

// 2.x data-target = target
<a data-target=".fat" data-toggle="modal">Launch</a>

If you'd rather turn off the data attribute API, or just part of it, you can do so by using the following:

// Turn off all data-api
$('body').off('.data-api')

// Turn off alert data-api
$('body).off('.alert.data-api')

2.0's JavaScript API has the same stuff, but better. You can turn off the data-api and do everything with JavaScript. They copied jQuery UI in a lot of ways (defaults, constructors, etc.). Bootstrap's JavaScript has 12 plugins. New ones include collapse, carousel and typeahead.

Customize - a new tab that lets you customize and download Bootstrap. It's basically an alternative to customizing .less files and allows you to choose components, select jQuery plugins, customize variables (colors, font-sizes, backgrounds) and download.

What does the future hold? Internationalization, improving responsiveness, more new features and bug fixes.

After both Mark and Jacob gave their talks, they talked together about Community and how great it's been. Even if you're not into writing CSS and JavaScript, they mentioned they still wanted to hear from you. To give an example of great community contributions, one guy opened 50 issues in the last 2 days.

Someone in the audience asked why they used LESS over SASS. Jacob said the main reason they use LESS is because they're good friends with the guy who invented it (Alexis). SASS turns CSS into a programming language, but they wanted to maintain the approachability of CSS, which LESS does. There's no plans to do an official SASS port, but there is talk of doing one. One advantage of the current LESS compiler is they rewrote it to have better output so it's far more readable.

NASA
After Mark and Jacob finished, there was a 5 minute break to grab beers and snacks. Then Sean Herron (@seanherron) (a.k.a. "NASA Bro") talked about Bootstrap at NASA. He actually didn't talk about Bootstrap much, except that they used it for code.NASA. He talked about NASA and how it's playing a key role in the movement towards open data, open source and open standards in our federal government. He mentioned how data.NASA was launched last August and that they helped develop OpenStack. Finally, he mentioned open.NASA, which is a collaborative approach to open, direct and transparent communication about our space program.

Hogan.js
Next up, Rob Sayre (@sayrer) talked about Hogan.js. Rob has been at Twitter for a few months, before that he wrote JavaScript at other places. Hogan.js is a compiler for Mustache templates.

Why Mustache? Because it's similar to HTML and easy to edit. You can mock data as JSON files and programmers are not required.

At Twitter, designers can do the CSS and Mustache without connecting to the backend. It has cross-language support in Ruby, Java and JavaScript. However, client-side template compilation has performance problems, especially in IE7 on a Windows XP box with 4 viruses.

So they had a few choices: work on mustache.js, or use Dust.js or Handlebars.js. The compilers are very nice for Dust.js and Handlebars.js, but they're huge. Handlebar's parser is 4000 lines. The entire Hogan.js file is 500 lines. They decided they were too large to send to the browser's of their users, so they chose to write a better compiler for Mustache.

Hogan.js's main features:

  • Compile on the server
  • Parser API
  • Performance

Performance is much better with Hogan.js than Mustache.js. On IE7 - Hogan is 5x faster than Mustache. On an iPhone, it's about the same (and an iPhone's browser is faster than IE7 on a decent computer). With modern browsers (Chrome 17, Safari 5 and Firefox 10), it's more than 10x faster.

Hogan.js is currently used at Twitter for Tweet embedding, the Bootstrap build process and soon, Twitter.com.

It's been awhile since I got excited about an open source project. Bootstrap has helped me a lot recently, in my Play More! mobile app, on some client projects and I'm in the process of refreshing AppFuse's UI to use it. I love how you can add a class or two to an element and all of a sudden they pop with good looks. The main problem with Bootstrap at this point is that a lot of Bootstrapped apps look the same. There's talk of adding themes in a future release to help alleviate this problem. In the meantime, there's a lot to get excited about with 2.0.

Thanks to Twitter for hosting this event and kudos to Mark and Jacob (and the community!) for such a fantastic project.

Posted in The Web at Feb 01 2012, 11:28:40 AM MST Add a Comment

PhoneGap for Hybrid App Development

This afternoon, I attended Brian LeRoux's talk on PhoneGap for Hybrid App Development at Devoxx. You might remember that I tried PhoneGap last week and really enjoyed my experience. Below are my notes from Brian's talk.

PhoneGap is a project for creating native applications using HTML, CSS and JavaScript. PhoneGap started out as a hack. In 2007, Apple shipped the iPhone and Steve Jobs told everyone they should develop webapps. PhoneGap started in 2008 as a lofty summertime hack and gained traction as a concept at Nitobi with Android and Blackberry implementations in the fall. In 2009, people started to pay attention when PhoneGap got rejected by Apple. They added Symbian and webOS support and Sony Ericsson started contributing to the project. They got rejected because all PhoneGap-developed apps were named "PhoneGap". This turned out to be good press for the project and Apple let them in shortly after.

In 2010, IBM began tag-teaming with Nitobi and added 5 developers to the project after meeting them at OSCON. In 2011, RIM started contributing as well as Microsoft. Then Adobe bought the company, so they're obviously contributing.

PhoneGaps Goals: the web is a first class platform, so let people create installable web apps. Their second goal is to cease to exist and get browsers to adopt their model.

PhoneGap is NOT a runtime or a compiler/transpiler. It's not an IDE or predefined framework or proprietary lockin. It's Apache, MIT and BSD licensed to guarantee it's as free as free software gets. You can do whatever you want to do with it. PhoneGap has recently been contributed to the Apache Software Foundation.

As far as Adobe vs. PhoneGap is concerned, the Nitobi team remains contributors to PhoneGap. Adobe is a software tools company and has Apache and WebKit contributors. PhoneGap/Build integration will be added to Creative Cloud.

The biggest issues with contributing PhoneGap to Apache is renaming the project and source control. I'm not sure why it needs to be renamed, but it's likely that Apache Callback is out. There seems to be some consensus on Apache Cordova. Apache likes SVN and the PhoneGap community currently uses Git. They're trying to find a medium road there, but would prefer to stay on Git.

The PhoneGap technique is colloquially called "the bridge". It's a 3 step process: they instantiate a WebView, then they call JavaScript from native code, then they call native code from JavaScript. Apparently, all device APIs are available via JavaScript in a WebView.

The primary platforms supported are iOS >= 3, Android >= 1.5 and BlackBerry >= 5.x. They also support webOS, Symbian, Samsung Bada and Windows Phone. No mobile dev platform supports as many deploy targets as PhoneGap. Primary contributors are Adobe, IBM, RIM and Microsoft.

Documentation for PhoneGap is available at http://docs.phonegap.com. Device APIs for PhoneGap 1.0 included sensors, data and outputs, which all devices have. Examples of sensors are geolocation and camera. Data examples are the filesystem, contacts and media. Outputs are screens, speakers and the speaker jack. All PhoneGap APIs are plugins, but any native API is permitted.

What about security? Brian recommends looking at the HTML5 Security Cheatsheet. PhoneGap has added a lot of security measures since they've found the native API pretty much opens up everything.

PhoneGap doesn't bundle a UI framework, but they support any JavaScript framework that works in the browser. PhoneGap is just a fancy browser, so your code run in less fancy web browsers too. This means you can develop and test your app in your desktop browser and only use PhoneGap to package and distribute your app.

Competition? PhoneGap has no competition.

PhoneGap/Build is for compiling your apps in the cloud and free for open source projects. The biggest reason they did this is because they couldn't redistribute all the SDKs and it was a pain for developers to download and install SDKs in training classes.

For mobile app development, you should have a singular goal. Do one thing really well if you want to be successful. Great UX happens iteratively. You know that the web works and has been widely successfully cross-platform. It's likely you've already invested in the web. Start by building a mobile web client and use PhoneGap as a progressive enhancement technique.

Shipping and unit testing should be a daily activity. Automate everything so you can have one-click builds (test/dev/release). For web client design, constraints are your ally in the battle against complexity and "clients who are not chill". Phones suck and consume a lot: cpu, ram, bandwidth, battery, network... everything! Start with a benchmark of app performance and monitor that benchmark. If you have tons and tons of features, consider splitting into multiple apps.

The mobile web is not WebKit! Opera is huge, Firefox is making strides and IE still happens. For layouts: use flex-box rules (anyone got a link to these?), css media queries and meta tags for viewport. You should try to develop your app without frameworks because they come with a ton of code and can effect the size of your app.

Looks can kill: aesthetics that can hurt performance: border-radius, box-shadow and gradients can slow down your apps. Chances are, you really don't need these features. Design your app for your brand, not for the device manufacturer. An app that looks like an iPhone app on Android doesn't give a positive impression.

For JavaScript libraries, start with your problem, not a generic solution like Sencha or jQuery Mobile. Zepto and its older brother XUI are all you need to start. Jo is a fantastic option. Backbone and Spine are worth watching.

For testing, QUnit and Jasmine are pretty popular. For deployment, concat, minify and obfuscate your JavaScript and CSS. Or you can inline everything into the markup to minimize HTTP chatter. Gmail inlines and comments all their JavaScript and then evals it.

From there, Brian recommended leveraging HTML5's AppCache and and using RESTful JSON endpoints for legacy systems. Next, he tried to show us a demo of a photo sharing application. Unfortunately, the Demo Gods were grumpy and Brian couldn't get his computer to recognize his Android phone. He did show us the client code and it's pretty impressive you can use 1 line of code to take a picture on a phone.

The last thing we looked at was debug.phonegap.com. This is an app that's powered by weinre. It lets you enter a line of JavaScript in your client and then remotely debug it in a tool that looks like Chrome's Web Inspector. Very cool stuff if you ask me.

Summary
I really enjoyed learning more about PhoneGap, particularly because Brain emphasized all my web development skills can be used. I don't have to learn Objective-C or Android to develop native apps and I don't even have to install an SDK if I use PhoneGap/Build. Of course, my mobile developer friends might disagree with this approach. In the meantime, I look forward to using PhoneGap to turn my mobile web clients into native apps and finding out if it's really as good as they say it is.

Posted in The Web at Nov 16 2011, 10:22:16 AM MST 2 Comments

My Everything You Ever Wanted To Know About Online Video Presentation

This week I've had the pleasure of speaking at The Rich Web Experience in Fort Lauderdale. I did two talks, one on Comparing JVM Web Frameworks and one titled Everything You Ever Wanted To Know About Online Video. Both talks had full rooms and very engaged audiences.

In the video talk, there were some audience members that knew way more than me about the topic. This made for a very interactive session and one of the most fun presentations I've ever done. It was also cool to talk about a lot of things I've learned over the last year (for more details on that, check out my team status or team hiring posts). If you don't have Flash installed, you can download a PDF of this presentation.

The first talk about Comparing JVM Web Frameworks was largely an extension of the one I presented at Devoxx two weeks ago. The main differences between this one and the last one is I extended it a bit and took into account some community feedback. However, this seemed to simply inspire anger, so I'll pass on embedding it here. You can view it on Slideshare or download the PDF.

My Comparing Web Frameworks slides often inspire harsh words, but folks really seem to like the presentation. I encourage you to watch my Devoxx presentation on Parleys.com to see for yourself.

This marks the end of 2010 conferences for me. I had a blast speaking at The Rich Web Experience, as well as TheServerSide Java Symposium, The Irish Software Show and Devoxx. Now it's time to sit back, relax, get some powder days in and find my next gig.

Hope y'all have a great holiday season!

Posted in The Web at Dec 03 2010, 10:16:44 AM MST 4 Comments

Scaling Flash Movies to match Browser Zoom Levels

Recently I was tasked with figuring out how to scale the Flash assets in the web application I'm working on. In the app, there's two different Flash assets: a Spotlight (cycles through images) and a Video Player. Before I started working on the issue, our assets would stay the same fixed size no matter what the browser zoom level. You can see this issue in action by going to Hulu or Fancast and zooming in/out (Command +/- on Mac, Control +/- on Windows). The Flash assets don't scale with the browser's text.

I found a lot of references for how to trap and handle resizing in JavaScript, so that's the initial path I took. I ended up having issues trapping the resize event in IE, as well as persisting the appropriate zoom level on page reload. Because of this, I ended up using a pure ActionScript solution that works much better. This article shows how I implemented both solutions.

Regardless of implementation, the first change I had to make was to move the height and width from the Flash asset (object/embed/JS) to its surrounding tag (<section> in our app). Then I changed the height/width to 100% on the Flash asset.

JavaScript Implementation
To allow zooming in ActionScript, I modified our main class to expose a "zoom" method to JavaScript:

ExternalInterface.addCallback("zoom", _zoom);

...

private function _zoom(scale:Number):void {
    _view.scaleX = _view.scaleX * scale;
    _view.scaleY = _view.scaleY * scale;
}
In the code above, _view refers to the container that holds all the items in the player. To call this method in JavaScript, I added the following code:

var windowHeight;
var documentHeight;

$(document).ready(function() { 
    ...
    windowHeight = $(window).height();
    documentHeight = $(document).height();

    $(window).resize(resizeWindow);
}

// Resize Flash assets when page is zoomed
function resizeWindow() {
    var newWindowHeight = $(window).height();
    var newDocumentHeight = $(document).height();
    // if document height hasn't changed, it's a browser window resize
    // event instead of a text zoom - don't change anything
    if (newDocumentHeight === documentHeight) {
        return;
    } else {
        documentHeight = newDocumentHeight;
    }
    var scale = (windowHeight / newWindowHeight); 

    var player = getFlashMovie('playerId');
    if (player && player.zoom) {
        player.zoom(scale);
    }
    var spotlight = getFlashMovie('spotlightId');
    if (spotlight && spotlight.zoom) {
        spotlight.zoom(scale);
    }

    windowHeight = newWindowHeight;
}

This seemed to work well in Firefox, Safari and Opera, but not in IE. I found this explanation about why it might not work, but I was unsuccessful in getting IE to recognize a resize/zoom event.

To fix scaling in our Spotlight asset, I used a similar solution. However, since the Spotlight didn't have all its elements in a container (they were being added directly to the stage), I had to refactor the code to add a SpotlightView (extends Sprite) that contains the bulk of the code.

Browsers persist the zoom level you've set for a site. The problem with the solution used here is it only scales up and down properly if you start from scale = 1 and revert to scale = 1 before leaving the site. If you zoom in and close your browser, when you come back the flash movies will be scale = 1 while the rest of the site is zoomed in. To solve this problem, I attempted to save the scale value in a cookie. This worked, and I was able to read the cookie in the *.as files to scale the movie correctly. However, I experienced some issues with this approach and didn't like having to delete cookies when I wanted the Flash assets to scale correctly.

ActionScript Implementation
After discovering issues with the JavaScript implementation, I did some research to see if it was possible to listen for the browser resize event in ActionScript. The Flash Fluid Layouts and Stage Resize in AS3 tutorial clued me in that the stage could listen for a resize event.

stage.addEventListener(Event.RESIZE, resizeListener); 

After adding the above line in the initialization, I added a resizeListener function that scales based on the default dimensions. It also ensures no scaling happens in full screen mode.

private function resizeListener(e:Event):void {
    // don't scale if entering full screen mode
    if (stage.displayState == StageDisplayState.FULL_SCREEN)  {
        _view.scaleX = 1;
        _view.scaleY = 1;
    } else {
        _view.scaleX = stage.stageWidth / 964;
        _view.scaleY = stage.stageHeight / 586;
    }
}

For the Spotlight asset, there are a number of different layouts (home, featured and news). The main class has a resizeListener function that scales accordingly to which layout type is being used.

private function resizeListener(e:Event):void {
    var type:String = _view.getLayoutType();

    if (type == "featured") { 
        _view.scaleX = stage.stageWidth / 958;
       _view.scaleY = stage.stageHeight / 180;
   } else if (type == "home") { 
        _view.scaleX = stage.stageWidth / 964;
        _view.scaleY = stage.stageHeight / 428;
    } else if (type == "news") {
        _view.scaleX = stage.stageWidth / 964;
        _view.scaleY = stage.stageHeight / 189;
    }
}

Because the layout type isn't set until the XML is loaded, I listen for that event in my URLLoader.

xmlLoader.addEventListener(Event.COMPLETE, resizeListener);

With the pure ActionScript implementation, the zoom level is automatically persisted. The Event.RESIZE event is fired by the Flash plugin when the page first loads if the dimensions are not the default.

That's it! Special thanks to James Ward for clueing me into scaleX and scaleY. Hopefully Hulu and Comcast can use this tutorial to scale their video players too. ;-)

Posted in The Web at Jul 13 2010, 12:18:42 PM MDT 9 Comments

Introduction to Objective-J and Cappuccino with Tom Robinson

This morning, I attended Tom Robinson's talk on Objective-J and Cappuccino. Tom is one of the founders of 280 North and creators of the Cappuccino framework and Objective-J language, so I was very interested in hearing about Cappuccino from the source. The text below are my notes, but they're also mostly Tom's words, not mine. I've added a "Thoughts" section at the end that are my words.

Tom's Team was Cocoa programmers before they started building Cappuccino. They wanted to focus on building Desktop Class Web Applications (for example, Google Maps, Meebo and 280 Slides). Tom showed a demo of 280 Slides and how it can rotate and scale images very easily, something you don't often see in web applications.

To build desktop class web applications, you can use Flash or Silverlight, but they're controlled by Adobe and Microsoft. Also, they have no iPhone support and poor Mac and Linux performance. The other option is JavaScript + DOM. They're open standards, available almost everywhere (including mobile devices) and its a very rich ecosystem with lots of competition. The downside to JavaScript is standards bodies, many incompatibilities, technical limitations (e.g. can't access web cam) and the DOM is very document-centric.

The bottom line is we can't fix Flash, but we can fix JavaScript.

This is what 280 North is trying to do with Objective-J. It's a proper superset of JavaScript, has a few syntax additions, has a powerful runtime and is implemented in JavaScript. Objective-J is analogous to Objective-C. It adds to JavaScript like Objective-C adds to C.

One of the first things Objective-J adds is Dependency Management. You can import from search paths:

@import <Foundation/CPObject.j>

Or from relative paths:

@import "ApplicationController.j"

@import prevents duplicate loads has asynchronous downloading and synchronous execution. That means all files are downloaded before evaluation begins, but to the programmer, it seems to happen synchronously.

The thing that sets Cappuccino apart from other libraries is its inheritance model. It uses classical OO inheritance (using Objective-C syntax).

@implementation Person : CPObject {
    String firstName @accessors;
    String lastName @accessors;
}

- (String) fullName {
    return firstName + lastName;
}

@end

The type definitions (String) are ignored for now and primarily used for documentation. In the future, they plan to add optional static typing, hence the reason for having them. Tom is unsure if you can leave off the String type or if the compiler requires it.

@implementation has proper support for super and language syntax support. One of the reasons they chose Objective-C is because classical inheritance works great for UI Frameworks.

Objective-J uses "send a message" syntax instead of "call a method" syntax. In the code snippets below, the first line is JavaScript, the second is Objective-J:

object.method()
[object method]

object.methodWithFoot(arg1)
[object methodWithFoo:arg1]

object.methodWithFooBar(arg1, arg2)
[object methodWithFoo:arg1 bar:arg2]

Dynamic Dispatch is one of the most interesting parts of Objective-J. forwardInvocation in Objective-C is like method_missing in Ruby. Methods can be used as references, for example:

var action = @selector(someMethod:);

Runtime mutability is important for KeyValueCoding (KVC) and KeyValueObserving (KVO). KVC allows you to swap classes at runtime and KVO allows you to listen for when property values change. At runtime, a $KVO_ClassName is generated. This class notifies any registered observers when values are changed and then calls the original class to change the property.

Cappuccino
Cappuccino is an application framework, not a library. It uses the Hollywood Principle: "Don't call us, we'll call you".

The Framework handles document management (open, save, revert), content editing (undo, redo, copy, paste) and graphics manipulation. The DOM is designed for documents (same is true for HTML and CSS). Tom doesn't like the DOM as its not a good API for building applications. Proof is all the JavaScript libraries built to make the DOM better.

Cappuccino has an MVC framework and CPView is its View. It's analogous to a <div> and represents a rectangle on the screen. Everything visible is a CPView or one of its subclasses. It defines resizing and layout behavior. CoreGraphics is Cappuccino's canvas-like drawing API. It uses VML on IE, canvas on everything else.

Very little of the code in Cappuccino talks to the DOM (less than 2%). It's not just about providing widgets that work in all browsers, it's a way to write platform independent display code.

Events are done very differently than most JavaScript libraries. Browser's dispatching is not used. A single event listener is registered for each type of event on the window. These events are captured and sent to the objects that need to know about them. This allows for consistent events across all browsers, even keyboard events. It also allows for creating custom event flows and easily creating custom events. Cappuccino events allow you to get around a common problem with DOM Events where you can't click on overlapping rectangles.

Notifications can be registered and sent very easily. Both "scoped" and private notifications can be created.

Undo Management is included in Cappuccino. It manages a stack of undos for you. Redos are "free" and undo functionality is part of the document architecture. This makes it easy to integrate with auto-save functionality.

Run loops (also called event loops) are an advanced feature of Cappuccino. They allow you to perform actions on every run loop. This enables complex optimizations for DOM/Graphic operations and undo grouping.

The final part of Cappuccino is Keyed Archiving. Keyed Archiving stores a graph of Objective-J objects. It handles reference cycles, conditional inclusions, has an efficient data format and works on the client and server (Objective-J can be run on the server). The data format is similar like binary, but it's UTF-8. Keyed Archiving is used for archiving views and used heavily in 280 Slides for storing, retrieving, and exporting presentations.

Other applications implemented with Cappuccino include almost.at and Mockingbird. EnStore uses it too, but only for its admin interface.

An interesting extension for Rails developers is CPActiveRecord, a reimplementation of Rails' ActiveRecord in Cappuccino.

There are several tools included with Cappuccino:

  • objj: command line Objective-J
  • objcc: "compile" ahead of time
  • press: optimize code and resources
  • nib2cib: convert Mac OS X nibs
  • capp: project creation

All these tools are built on Narwhal (which conforms to the CommonJS standard).

CommonJS
CommonJS is an effort among server-side JavaScript projects to standardize non-browser JavaScript APIs. There's numerous API specifications (so far):

  • Binary, File, IO
  • stdin, stdout, stderr, args, env
  • Web server gateway (JSGI) - similar to WSGI and Rack for Python and Ruby

To learn more about CommonJS, see CommonJS effort sets JavaScript on path for world domination.

Narwhal is 280 North's implementation of CommonJS APIs. It works with multiple JavaScript engines, including Rhino, JavaScriptCore (SquirrelFish) and XUL Runner. According to Tom, Rhino is an order of magnitude slower than JavaScriptCore and V8. Of course, Narwhal supports Objective-J too.

Aristo
Aristo is the new default theme in Cappuccino and was created by the Sofa design firm. It includes windows, tabs and menus and is open source so you can modify.

Atlas
Atlas is an IDE for Cappuccino, focused on building user interfaces graphically. Atlas is a downloadable application for OS X. It's written almost entirely in Cappuccino. The desktop version bridges Cappuccino windows to native windows. Tom did a demo of Atlas and showed how its layout feature allows you pin, center and align very easily. It's all done with JavaScript because doing layouts with CSS is often very painful. After that, he showed us how can you Atlas to very easily build a Web Application and then export it as a native OS X application without changing a line of code. Atlas includes Mozilla's Bespin for code editing.

To learn more about Aristo and Atlas, you might want to checkout Ajaxian's Big News from Cappuccino: Aristo and Atlas from earlier this year.

Atlas has a $20 Beta Program if you're interested in trying it out.

My Thoughts
Cappuccino looks like a very cool web framework. It reminds me of GWT in that you have to learn a new language to use it. However, Atlas takes a lot of that pain away. I particularly like how it has document and undo/redo support built-in. On my current GWT project, this would be very useful as we've had to build this functionality by hand.

Posted in The Web at Dec 03 2009, 11:21:59 AM MST 2 Comments

GWT OAuth and LinkedIn APIs

LinkedIn Logo When I worked at LinkedIn last year, I received a lot of inquiries from friends and developers about LinkedIn's APIs. After a while, I started sending the following canned response:

For API access to build LinkedIn features into your application, fill out the following form:

   http://www.linkedin.com/static?key=developers_apis

For requests to build an application, go to:

   http://www.linkedin.com/static?key=developers_opensocial

I talked with the API team and they did say they look at every request that's sent via these forms. They don't respond to all of them b/c they know that many people would be angry if they told them "no", so they'd rather not have that headache.

Yesterday, I was pumped to see that they've finally decided to open up their API to Developers.

Starting today, developers worldwide can integrate LinkedIn into their business applications and Web sites. Developer.linkedin.com is now live and open for business.

First of all, congratulations to the API team on finally making this happen! I know it's no small feat. Secondly, it's great to see them using Jive SBS for their API documentation and developer community. My current client uses this to facilitate development and I love how it integrates a wiki, JIRA, FishEye, Crucible and Bamboo into one central jumping off point.

I've always been a fan of LinkedIn, ever since I joined way back in May 2003. However, I've longed for a way to access my data. LinkedIn Widgets are nice, but there's something to be said for the full power of an API. Last night, I sat down for a couple hours and enhanced my Implementing OAuth with GWT example to support LinkedIn's API.

I'm happy to report my experiment was a success and you can download GWT OAuth 1.2 or view it online. For now, I'm simply authenticating with OAuth and accessing the Profile API.

OAuth with GWT

In the process, I learned a couple things:

// For LinkedIn's OAuth API, convert request parameters to an AuthorizationHeader
if (httpServletRequest.getRequestURL().toString().contains("linkedin-api")) {
    String[] parameters = httpServletRequest.getQueryString().split("&");
    StringBuilder sb = new StringBuilder("OAuth realm=\"http://api.linkedin.com/\",");
    for (int i = 0; i < parameters.length; i++) {
        sb.append(parameters[i]);
        if (i < parameters.length - 1) {
            sb.append(",");
        }
    }

    Header authorization = new Header("Authorization", sb.toString());
    httpMethodProxyRequest.setRequestHeader(authorization);
}

You might recall that my previous example had issues authenticating with Google, but worked well with Twitter. LinkedIn's authentication seems to work flawlessly. This leads me to believe that Twitter and LinkedIn have a much more mature OAuth implementation than Google.

Related OAuth News: Apache Roller 5 will be shipping with OAuth support. See Dave Johnson's What's New in Roller 5 presentation for more information.

Update December 6, 2009: I modified the gwt-oauth project to use GWT 1.7.1 and changed to the Maven GWT Plugin from Codehaus. Download GWT OAuth 1.3 or view it online.

Posted in The Web at Nov 24 2009, 03:46:05 PM MST 7 Comments

User Interface Schema Definitions

On my current project, we're developing a "designer" tool that allows users to build forms in their browser. These forms are displayed in various channels (e.g. web, mobile, sms) to capture data and make decisions based on user input.

When I joined the project, it was in a proof-of-concept phase and the form definitions created where serialized as XML (using JAXB) with element names that seemed logical. Now that we're moving the PoC to production mode, we're thinking it might be better to change our form definitions to leverage something that's more "industry standard". If nothing else, it'll help with marketing. ;-)

This week, I was tasked with doing research on "existing user interface schema definitions". I'm writing this post to see if there's any major specifications I'm missing. I plan on providing my recommendation to my team on Monday. Here's what I've found so far:

  • User Interface Markup Language (UIML): At 120 pages, the 4.0 spec seems very detailed. I'm not sure we'd use all of it, but it's interesting how the spec allows you to describe the initial tree structure (<structure>) and to dynamically modify its structure (<restructure>). It also has the notion of templates, which mirrors a similar concept we have in our application. Furthermore, it has VoiceXML support, which could be useful if we use call centers as a channel.
  • USer Interface eXtensible Markup Language (UsiXML): I admit that I haven't read much of this specification -- mostly because the UIML spec seemed to cover most of what we needed (especially since we're most interested in describing forms). As far as a I can tell, the major difference between UsiXML is its being submitted to the W3C for standardization (according to Wikipedia), while UIML is being standardized by OASIS. Beyond that, I find it strange that UIML's spec is 120 pages and UsiXML is 121. Neither project seems to have any activity this year.
  • Numerous others: including AAIML, AUIML, XIML, XUL, XAML and XForms. XForms seems like it may be the most logical if we're only interested in form layout and describing elements within them.

If all we're interested in is an XSD to define our forms, the most appealing specs have them: UIML, UsiXML and XForms. If activity is any sort of motivator for adoption, it's interesting to note that XForms 1.1 was submitted as a W3C recommendation a couple weeks ago (October 20, 2009).

If you've developed some sort of "form designer" tool that renders to multiple channels, I'd love to hear about your experience. Did you use some sort of industry standard to define your form elements, layout, etc. or did you come up with your own?

Posted in The Web at Nov 06 2009, 03:18:25 PM MST 4 Comments

Ajax: The State of the Art with Dion and Ben

This morning, I added Dion and Ben's talk titled Ajax: The State of the Art. Below are my notes from the event.

Ajax started out as a bunch of hacks. It showed that we could take our web interfaces and do a lot more with them. A hack isn't necessarily a bad thing. Often, they turn into something much more elegant over time. The new browsers have many amazing capabilities that we haven't taken advantage of yet. We've seen discussions on Ajax go from how to do XHR to frameworks and how rich and mature they are. Dojo is great for Enterprise Development (packing system, namespaces). jQuery is well-suited for lightweight developers (PHP). Prototype is fantastic for people who do a lot of JavaScript development and take it very seriously.

Today's Ajax landscape is mature, really rich, and really exciting. Today, Dion and Ben are going to talk about technologies they're really excited about for the future.

Canvas
The building blocks of the web are text, boxes and images. With canvas, it really makes a lot more things possible. You can do bitmap rendering and image manipulation. They're showing a slide with Doom and Mario Kart running. Canvas 3D does true 3D rendering. Firefox and Opera have done prototypes of this. Can you do canvas-type things today in a browser? Yes, if you use Flash or Curl. Dion and Ben are excited about canvas over plugins for the following reasons:

  • No start-up delay
  • Available on mobile devices today
  • Rendering fidelity with browser (especially important for typography)
  • No bridges necessary (no marshalling/unmarshalling)
  • Not a plug-in

The <canvas> tag originally came from Apple's Dashboard. Dashboard's programming model was in HTML and JavaScript. Dashboard is using WebKit under the covers. Today, canvas support exists in every major browser except for IE. The good news is there are Flash and Silverlight bridges to add support to IE. There's also an ActiveX component that wraps the Firefox implementation and allows it to run in IE.

SVG
Dion and Ben aren't that excited about SVG because it's such a huge spec. We've been struggling with the HTML standard for the last 10 years and the thought of another huge spec for the next 10 years isn't that appealing.

Fast JavaScript
Almost all major browsers have a Fast JavaScript implementation. Chrome has V8, Safari has SquirrelFish Extreme, Firefox has TraceMonkey and Opera has Carakan. This is exciting because of industry trends and how companies are trying to reduce computation cycles in data centers. The more computing that can be put on the client, the better. IE doesn't have anything, but Dion and Ben believe they are working on something.

Web Workers
Interface latency is awful for applications. Jakob Nielsen once said:

0.1 second is about the limit for having the user feel that the system is reacting instantaneously. 1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay.

Anything that takes longer than a tenth of a second should be pushed to a background thread. Unfortunately, there are no threads in the web. Maybe we can add threads to JavaScript? Brendan Eich has said that "Threads suck" and there's very little chance for threads getting into JavaScript. Gears brought Worker Pools and this is going into HTML 5 as Web Workers. You could also use Java applets to do this. With the latest Java Plugin, many of applets' long-standing issues have been solved.

Desktop Integration
The ability to build desktop apps as web apps is very exciting. There's a few technologies that demonstrate this: Fluid, Mozilla Prism, Adobe AIR, Appcelerator Titanium and Gears. The Palm Pre demonstrates the logical extension of this. The Palm Pre uses the web stack as its developer SDK. It's very cool that web developers don't have to learn anything new to become a Palm developer. Desktop integration is exciting especially if we can access desktop applications like email and address book.

The Ajax frameworks that are out there have done a lot to make web development simpler. However, there's still a lot of pain with CSS and cross-browser issues. What if you took canvas and combined it with a sophisticated grid-based layout in JavaScript?

There's a lot of platforms out there: Microsoft Silverlight, Adobe Flash, Apple Cocoa and Sun's JavaFX. The web often isn't considered a platform. Dion and Ben believe there should be an Open Web Platform. The problem right now is there is no central location to find out how to get stuff done. You have to search and find resources from many different locations. Mozilla is putting it's resources into creating an Open Web Platform. This site will consist of 4 different areas:

  • Home
  • Documentation (for different frameworks, browsers, quirks)
  • Dashboard (state of the open web)
  • Roadmap (what's going on)

This is not just Mozilla, it's very much a community effort. This is something that Ben and Dion have been working on. But there's something else they've been working on too. They've been talking about all these cool things, but what about an interesting application to test all these technologies?

Bespin
As they looked at code editors, most of them provide awful user experiences. Bespin is the Editor of Your Dreams and contains the following features:

  • Accessible from anywhere - any device in any location
  • Simple to use, like Textmate (not heavyweight like Eclipse) - an editor, not an IDE
  • Wicked Fast - performance, performance, performance
  • Rock-solid real-time collaboration, like SubEthaEdit - it just works
  • Integrated command-line, like vi - Fun like Quicksilver, social like Ubiquity
  • "Self-hosted" environment, like Emacs - For extreme extensibility, but with JavaScript!
Dion and Ben are showed a screen shot of Bespin and now they're doing a demo. The core editor has what you'd expect with syntax highlighting and line numbers. Canvas doesn't have text-selection by default, so they had to write it from scratch. The command line allows you to get help, run core command and also to subscribe to commands that others write. You can change your keybindings to emacs or vi as well as many other settings. Much of Bespin is event-driven, so you can easily plugin new behavior for different events.

For viewing files, they couldn't bring themselves to use a tree. Instead, they developed a file-browsing interface that looks very much like Apple's Finder. Personally, I like Finder, but wish it had Windows Explorer's path bar that allows you to simply type in the path without mouse clicks. Back to the command line. They've done a lot to make things more discoverable so users can easily find the power of the editor.

Bespin could be used to engage developers more with open source projects. Checking out projects, modifying code and creating patches can be a real pain. Bespin could be used to interface with open source projects in the cloud. You could login, modify code and easily patch/build with the click of a button. One other thing they want to do is to have the server do code-analysis as you're developing.

Is it OK to love a software tool? You must love your software tools. What we do as Software Developers is one of the most difficult jobs on the planet. Programmers, like poets, start with a blank slate and create something from nothing. If you don't love your tools, you'll start resenting what you do. If you don't love your tools, it shows in your work. -- Dave Thomas at RubyConf08

Thunderhead
A GUI Toolkit written with canvas and JavaScript. Allows you to do layouts with very little thought. It's a lab experiment that's in progress, stay tuned for more information.

All users care about is the user interface. Dion and Ben believe there's a key to creating compelling user experiences. It all has to do with managing expectations. It's not that different from how you manage relationships in your life. Expectations for movies and games have changes drastically over the years. What used to be the web (animated gifs and awful web pages) has also changed drastically (video of Apple's online store). What was cool with MapQuest got changed drastically with Google Maps. What we have today isn't the end of the game - expectations will continue to change. However, users have different expectations for software.

Alan Cooper has done some interesting work in this area. The software designer needs to focus in on a user's goals. There are basic things you can apply to all users, for instance "sex sells". An example of this is Delicious Library. This application allows you to keep track of things in your home such as books, movies, music and games. They made $500K in 3 months and made $54K the first day, with no advertising.

The quality of any software is determined by the interaction. If the interaction isn't good, it will poison the entire experience. Donald Norman has a good quote: "Attractive things work better". In society, this is often called "Dress for Success".

The Open Web is hear to stay because it has:

  • An Easy Programming Model
  • Easy Remoting
  • Extensive Customization Vectors (e.g. GreaseMonkey)
  • Easy Deployment
  • Great Widgets
  • Great Visual Effects
  • Great Mobile Story
  • Desktop Integration
  • State-of-the-Art Plug-ins

Bespin is a tech preview that they hope to release next week. Thunderhead will be released at the same time.

Conclusion
This was a great talk and easily the most inspiring of the conference. Dion and Ben always do a great job and the sexiness of their presentation made it all the more appealing.

Posted in The Web at Feb 05 2009, 11:03:10 AM MST 4 Comments