Tuesday, August 26, 2008

Zend DevZone book review

Cal Evans of Zend just posted a shining review of Advanced Ajax!

It’s not often that I review a book that is a year old for several reasons. The main reason is that technology changes so fast. In this day and age a book 12 months old usually contains out dated information. As with any good rule, there are exemptions, this book is one of them.

Having said that let me lay out a warning, “Advanced Ajax” means what it says, it is an advanced book. If you are a web designer who has just completed “Learn JavaScript in One Week” then you do not want to buy this book. Go play with the other crayons and come back when you’ve got a few years experience under your belt. This book is for those developers that already know what a pain it is to develop using JavaScript and love it anyhow. If you’ve already busted one flat-screen by banging your head on it because “the code should work!” then you are ready for this book.

Read the rest of the review.

Labels:

Sunday, August 10, 2008

Books to give away during my ZendCon08 talk!

In order to bribe more people to attend my talk at ZendCon08, my publisher has sent me three copies of my book to give away! I haven't quite figured out how to dole them out yet, or even have any idea how many people will attend the talk and want a copy, but I'll figure something out.

I think for the talk, I'll use a modified S5 theme I have in-progress using Safari's new CSS transforms and animation support for transitions. I'll post some examples of that as I make it ready for the talk, since I can't really post the content of my talk until I get the go-ahead from those who give it at IBM. The talk centers around looking at source code from work, and I'd rather not upset IBM's Higher Powers by exposing even part of the product without explicit permission...

Labels: , ,

Saturday, April 05, 2008

Part 2 of the Advanced Ajax review went up!

In the midst of things, the second half of the review from Agile Ajax went up! It seems that despite the rather heavy use of PHP for the server-side example code, Brian (apparently more into ASP, JSP, and Ruby) still liked it, which makes me very happy.

Back in February, I reviewed the first half of Shawn M. Lauriat's "Advanced Ajax: Architecture and Best Practices" (Prentice Hall, 2008, 360p). The first four chapters of Lauriat's book, which focused almost exclusively on client-side technologies, impressed me considerably. But it's taken me several weeks to get through the remainder of the book, and there's one reason why: PHP.

The server-side portion of "Advanced Ajax" uses PHP code to illustrate its many and varied lessons about Ajax architecture. It's not that I have anything against the popular web-development framework and scripting language. It's just that, after spending my career in the ASP Classic and JSP trenches and slowly ramping up on Rails in the last year, I'm not the ideal target audience for these code samples. Adding "PHP" to the title of the book might have limited its potential audience, but it also would have been more accurate.

That said, there's a lot of value here for adherents of any server-side framework. Lauriat discusses each topic from a general perspective before diving into the code. The technical approach to a given problem would obviously differ by framework, but the high-level approach wouldn't. If you don't mind skimming past the content that doesn't apply to you, Lauriat's advice about developing stable, scalable, accessible and secure Ajax applications transcends framework allegiance.

Read the rest of the review.

Sidenote: On the Ajaxian post for the review (part 2), Joeri left a comment that really hit on what I tried for in writing the book, almost quoting what I told Prentice Hall when describing the type book I intended to write:

I’ve read this since the last review.
It does a pretty good job documenting the best practices when building ajax apps. This is a book to read when you want to move beyond knowing the basics of javascript and xmlhttp to building a real web app using ajax methods.

Thank you, Joeri! I feel glad knowing that people out there have read the book and gotten out of it something resembling what I had hoped they would.

Labels: ,

Saturday, February 16, 2008

Advanced Ajax (Kindle Edition)

For those interested: Advanced Ajax (Kindle Edition) apparently went up on Amazon. I haven't met anyone yet who has a Kindle, but I imagine someone out there does! Hopefully lots of Ajax developers...

Labels:

Tuesday, February 12, 2008

Book review up on Agile Ajax

Book review: Advanced Ajax by Lauriat (Part 1 of 2) went up earlier today (also linked to from Ajaxian), and so far Brian Dillard (RIA Evangelist @ pathfinder and project lead for Really Simple History) seems to like it:

Because Ajax moves so much application logic from the server to the client, it forces many developers to master a wider range of web technologies than ever before. To work effectively on Ajax projects, front-end developers have to concern themselves with database performance, business logic and other server-side concerns. Back-end and middleware developers, meanwhile, have to make friends with XHTML, CSS, JavaScript and a wide range of browsers. Sure, it's possible to develop Ajax apps in a siloed team environment. But it's not the easiest way, and it rarely provides the strongest results.

Shawn M. Lauriat's "Advanced Ajax: Architecture and Best Practices" (Prentice Hall, 2008, 360p) bridges the gap between developers with exclusive client- or server-side skills. By exploring tools, technologies and best practices for every layer of the Ajax programming model, this solid new programming manual promises to plug the holes in any developer's resume. Lauriat's tops-to-tails approach offers something for almost any developer, but it also guarantees most readers will find some sections remedial. As this two-part review will demonstrate, that's not necessarily a liability.

Read the full review

Labels: ,

Wednesday, October 17, 2007

Real book!

I received a copy of the real thing this morning, express-mailed from the publisher:

Advanced Ajax book

It even has fully operational pages with ink on them!

Advanced Ajax, opened up to illegible code

It should start hitting shelves in the next week or two! I don't know where Amazon.com's shipping schedule fits in, but I would expect around the same time.

Labels:

Tuesday, October 09, 2007

Reviewers and plugging the book

Out in San Francisco for the Zend Conference, and I have two people lined up for reviewing the book. One of the reviews should make it up on Zend's Developer Zone if all goes well!

To anyone attending the conference: I have a bound manuscript with me if you want to flip through to take a look. I'll try to keep it out and noticeable so you'll have an easier time spotting me. I also have put out a few piles of flyers in the lobby giving you a 35% discount on the book (it also has the finalized table of contents on the back).

Labels: , , ,

Wednesday, October 03, 2007

Advanced Ajax goes to the UK

As my newly-wedded friend, Mutant, has found and brought to my attention: Advanced Ajax: Architecture, Best Practices and Open Ajax now appears on Amazon.co.uk! It has a price of £34.19, which doesn't quite mesh up with the US price of $39.99, but it at least makes me happy to see it become available to those not in the States.

Labels:

Friday, September 28, 2007

No properly-bound book for ZendCon, but discounts!

So the binding of the books won't happen in time for me to have one to bring with me to the Zend Conference, but I will have a bound manuscript to show off. I will also have flyers to hand out, which will give you a 35% discount on the book!

It ended up working out better for me to go out there for a few days around the conference (I arrive on the 6th), so if anybody in the Bay area feels up for a Saturday night run to any one of the many restaurants I miss in San Francisco, it would make me very happy! If not, I'll just go without you anyway, as I plan to do most of the nights that week (except, of course, the evening of Happy Hour 2.0).

Labels: , ,

Friday, September 21, 2007

The book went to the printer today

Assuming all went well at Prentice Hall, they've passed the book off to the printer today, and I should receive a pre-distribution copy to bring with me to the Zend Conference! I got a copy of a much later draft of the book cover, which has undergone some slight changes, but should look more or less like this:

Advanced Ajax Cover

The quote on the front cover reads:

“I very much enjoyed how this book covers the full Ajax application life-cycle and not only coding techniques. Anyone who is looking to become a professional front-end developer will appreciate the architectural insight and best practices delivered by this book.” - Andi Gutmans, Co-Founder & Co-Chief Technology Officer of Zend Technologies

Labels: ,

Wednesday, September 05, 2007

Up on Safari Bookshelf's Rough Cuts!

The entire book has now appeared: Advanced Ajax: Architecture and Best Practices.

Labels:

Tuesday, September 04, 2007

Amazon!

I received some of the PDFs to go over how it will print up, and noticed the ISBN number in the front matter PDF. So, putting it into Amazon.com, it brought up Advanced Ajax.

Back to work, just got excited.

Make sure everybody puts it on their wishlists for the holidays (not Halloween, unless you really want it). :-)

Labels:

Wednesday, August 29, 2007

Editing completed!

Unless they send something back again for additional changes, I've just sent off the last of the copy edits for the book! Next, I think I'll get PDFs of each chapter to go over the layout/presentation. Also, somewhere in this process, the book will start showing up on Amazon.com, Rough Cuts, etc.

Quick post, I know. But I just got back from a trip out to Seattle for PAX and feel quite worn out.

Labels: ,

Monday, August 20, 2007

Adavanced Ajax Cover

The cover below shows the almost-ready-for-publication cover of Advanced Ajax: Architecture and Best Practices. The yellow dialog boxes on the image just show notes from reviewers (things like the "L" in "Lauriat" bleeds into the dark bits and looks like an "I" or that my name should appear on the spine or the back cover makes it sound like I owned Buildforge, Inc.).

Advanced Ajax Cover

Exciting stuff (for me, at least) though. I have a few chapters left to get through as far as copy editing goes, but this should show up soon on Rough Cuts, I swear...

Labels: ,

Monday, July 30, 2007

With more editing comes the end of the E-Prime text

Well, I kept the book E-Prime up until this part of the process, and for that I feel satisfied. I don't feel proud enough of it to think myself better than the professional copy editors at Prentice Hall, though, so here it ends. Writing the initial draft in E-Prime definitely made it easier to keep the text as relevant and clear as possible, so it definitely feels well worth it to me.

For the uninitiated, writing in E-Prime means writing in a more active, subjective voice. Developers do things. These practices achieve these results. The cornerstone of E-Prime comes in removing all conjugations of "to be" from language. Writing something like "The rendering in Figure 3 is better." doesn't explain anything about what makes it better in that context. Writing in E-Prime doesn't always come easily, but it does make it much easier to write more coherently.

At least, I told myself that as I wrote the book. Time will tell, I suppose.

Labels: ,

Sunday, July 29, 2007

I found out why the first round of edits seemed really light

It turns out that the technical editor doesn't look at how badly I've written things, but instead looks at the content and form of the chapters. Now that I've made it to the copy editing stage, I feel quite a bit better knowing that my writing has gone through both steps. All of the pages I've gone through so far have as many edits as shown below:

Massive amounts of copy edits

Making my way through the edits and waiting for permission to come back from the places owning things of which I took screenshots for the book...

Labels:

Thursday, June 21, 2007

Appendix on OpenAjax complete

I worked hard to narrow down all of the information in OpenAjax wiki into something easy to read and based on information that has stabilized enough for developers to safely put into practice. A lot of the work by the OpenAjax Alliance remains in a state of flux, while other aspects of the Alliance (the work of the Security Working Group, for example) have yet to even reach an agreed upon direction and set of goals.

Developers can, however, start working with the OpenAjax hub today. It underwent a redesign and rewrite a few months ago, but has reached a point where libraries can start working with it. It doesn't so much bring a wide range of functionality as provide a couple of ways for multiple libraries to co-exist in the same interface, while encourging practices such as object-oriented scripting, event-driven application design, and the use of namespace in JavaScript (or rather, emulating it as much as possible).

One other bit of news: shortly, I'll have a link to post for the book's availability in the Rough Drafts program!

Labels: ,

Sunday, June 17, 2007

Frozen Toolkit

So the toolkit came out of the book, and the toolkit basically exists primarily for education purposes. It provides an object-oriented abstraction of the XMLHttpRequest object, as well as providing a method of easily implementing event-driven application development. Throughout the book, the toolkit has grown, and by the final appendix (currently in writing) it meets OpenAjax compliance.

The toolkit has minimal documentation at this point, and zero examples (outside of the book, of course), but I rather like it, as it allows the use of Ajax connections, with support for various HTTP response codes, event dispatching available for extension, and external JavaScript file loading. However, I do have a bit of a bias, since I wrote it. The API will probably change quite a bit before it settles into itself, but it has at least stabilized to the point that I'll post a link to the current source files, consolidated and compressed source, and JSDoc2-generated docs.

Frozen Toolkit

Labels: , ,

Wednesday, May 30, 2007

Initial text of the book complete!

Current word count: 73,430

I've absolutely no idea what that means in terms of pages. Doing a quick wc -l text/*.txt it looks like an average of about ten words per line, but I still haven't a clue how many pages that works out to, though I suppose I'll find out soon enough.

I still have a few figures to create, one or two code samples to write, an appendix to write, and lots of edits to come shortly, but I've finished the initial text of the book!

Labels:

Saturday, May 26, 2007

Intro to Chapter 10: Game Development

I do hope to finish this game since I have it quite close, but I need to finish the book first. I considered using sprites for the ships, star, and missiles, but decided against it to practice rotation and see what canvas could handle. Also, the original version didn't exactly use image sprites, so I stuck with entirely two-dimensional shapes in canvas. Anyway, on with a couple of paragraphs:

Ajax-driven game development brings together the challenges of scalability and performance, but often allows developers to push the boundaries of current web technologies. Just as with console or computer games, users will put up with stricter minimum requirements in order to have the better experience with the more advanced technologies available, properly used.

This chapter will focus on Universe Conflict, an implementation of Space War!, one of the first digital computer games, created in 1961 on the PDP-1 computer, as recreated using the canvas HTML5 element and Ajax (shown below). This allows the two players to battle each other from different machines, as opposed to the same one as in the original and ports since then. The game has very simple rules and a simple setup. Two ships, each controlled by a user, try to shoot each other without getting pulled into a star in the center of the screen.

Two ships poised to attach each other around a star

Sidenote: you can see the rendering in action in this simple demo of Universe Conflict, which just allows you to click a button and fly each ship around the screen using the arrow keys. Not terribly exciting, since I took the networking bits out, haven't created gravity, and only works in Opera and Firefox for now (Safari has some flickering and keyboard issues that I just haven't bothered to fix yet), but it should give a decent idea of how canvas can handle animation. I haven't tested this a whole lot, so if it sucks for you, let me know.

Labels: , ,

Monday, May 14, 2007

Slight knock on PHP in the section on coding standards

I admittedly held back quite a bit from how much I could easily rant on the topic of PHP's complete lack of consistency when it comes to its function/object library. However, I need to finish the chapter on documentation, not how much PHP's lack of consistency annoys me. As a result, the following excerpt reads much more like a hint of slight frustration than the outburst of obscenities uttered as I hit <ctrl>+<l>, <p>, <tab>, <return> to go back to the PHP manual for the twelfth time that day.

Coding conventions should also include variable, function, method, and object naming practices. When languages support upper-case and lower-case alphanumerics, underscores, and sometimes even the dollar sign character, function libraries and APIs have the potential to include a wide variety of calls available to developers. The following four PHP library functions, while all consistently lower-case, have different parameter ordering and variable naming:

strpos ( string $haystack, mixed $needle [, int $offset] )
str_split ( string $string [, int $split_length] )
explode ( string $delimiter, string $string [, int $limit] )

The strpos and str_split functions in particular should not have differences in their naming, as they reside within in the same categorization of library functions in the PHP Manual, but one has an underscore separating the "str" prefix from the full word of "split" while the other has the "str" prefix unseparated from the abbreviated "pos" instead. Looking at str_split and explode, these two functions have very similar functionality: str_split breaks a string into an array of substrings of a constant length, while explode breaks a string into an array of strings as divided by a passed delimiter. Unfortunately, while str_split takes the string as the first parameter and the split length as the second, explode takes the delimiter as the first parameter and the string as the second, requiring calls to pass an empty string as the first parameter in order to break the string into an array of characters.

No matter what the conventions decided, they should not deviate so far from standard practice that new developers have a difficult time working in the code. By using tabs, consistent naming conventions, and consistent parameter ordering, developers should have the ability to "just know" what a library function or API call looks and acts like, and developers will spend less time researching functions and more time using them.

Labels: , ,

Saturday, May 05, 2007

Support for different HTTP status codes with Ajax

While writing about adding support for different status codes into the AjaxRequest object (very easy, as I'll show momentarily), I made a little test page to try each of the initial set: HTTP Status Codes. Just click each link (check Firebug) and it optionally fetches all, part, or none of a 400-line file.

Now on to the excerpt:

Most browsers and XML feed readers take full advantage of the HTTP/1.1 specification to greatly reduce the data sent from the server, and the XMLHttpRequest object gives developers access to the same functionality. Two intertwined aspects of the HTTP/1.1 specification in particular can help Ajax-driven applications: status codes and cache-control.

Supporting these in the previously defined AjaxRequest object comes easily. It already supports setting custom headers through its headers object, just like setting GET and POST variables. In order to support the various status codes that the server can return, it just takes adding event types and adding some more flexibility to the stateChanged() method by changing it from:

// Event dispatching
AjaxRequest.prototype.events = {
  abort : [],
  data : [],
  load : [],
  open : [],
  send : [],
 };

// Callback for this.xhr.onreadystatechanged
AjaxRequest.prototype.stateChanged = function() {
 // Only trigger load if finished returning
 switch(this.xhr.readyState) {
  case 3:
   var e = new AjaxEvent(this);
   this.dispatchEvent('data', e);
   break;
  case 4:
   // Only continue if status OK
   if (this.xhr.status == 200) {
    var e = new AjaxEvent(this);
    this.dispatchEvent('load', e);
   }
 }
}

...to a new version that can handle multiple status codes:

// Event dispatching
AjaxRequest.prototype.events = {
  abort : [],
  data : [],
  internalservererror : [],
  load : [],
  notfound : [],
  notmodified : [],
  open : [],
  partialload : [],
  requestedrangenotsatisfiable : [],
  send : [],
  unauthorized : []
 };
// Simple lookup of event types by status code
AjaxRequest.prototype.statusCodeEvents = {
  200 : 'load',
  206 : 'partialload',
  304 : 'notmodified',
  401 : 'unauthorized',
  404 : 'notfound',
  416 : 'requestedrangenotsatisfiable',
  500 : 'internalservererror'
 };
// Callback for this.xhr.onreadystatechanged
AjaxRequest.prototype.stateChanged = function() {
 // Only trigger load if finished returning
 switch(this.xhr.readyState) {
  case 3:
   var e = new AjaxEvent(this);
   this.dispatchEvent('data', e);
   break;
  case 4:
   if (this.statusCodeEvents[this.xhr.status]) {
    var e = new AjaxEvent(this);
    this.dispatchEvent(this.statusCodeEvents[this.xhr.status], e);
   }
 }
}

The new implementation of stateChanged() now simply triggers the event mapped to the returned status code from the request, if the AjaxRequest object implements that event type. While the list of status codes only includes the most commonly used codes for this chapter's usage, it can include any additional codes added to the events and statusCodeEvents objects.

Labels: , , , ,

Saturday, March 31, 2007

Fun with getallheaders() and var_dump() - another excerpt from Chapter 8

In PHP, the Apache-specific functions give an extremely easy way of checking referers via the getallheaders() library function. Calling it, with PHP installed as an Apache module, returns an associative array containing all of the header names as the array keys, with their corresponding header values as the array values. Calling var_dump(getallheaders()) would display something like the following, with "Referer" as the last entry in the array:

array(9) {
  ["Host"]=>
  string(13) "192.168.2.106"
  ["User-Agent"]=>
  string(92) "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"
  ["Accept"]=>
  string(99) "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
  ["Accept-Language"]=>
  string(23) "en-us,en;q=0.7,fr;q=0.3"
  ["Accept-Encoding"]=>
  string(12) "gzip,deflate"
  ["Accept-Charset"]=>
  string(7) "UTF-8,*"
  ["Keep-Alive"]=>
  string(3) "300"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Referer"]=>
  string(31) "http://192.168.2.106/utilities/"
}

However, the following shows that a simple telnet connection can set the header to anything and the server will simply believe it, since it lacks any way of verifying it.

$ telnet 192.168.2.106 80
Trying 192.168.2.106...
Connected to 192.168.2.106.
Escape character is '^]'.
GET /utilities/getallheaders.php HTTP/1.1
Host: 192.168.2.106
Referer: The Forbidden Zone

HTTP/1.1 200 OK
Date: Thu, 22 Mar 2007 02:08:01 GMT
Server: Apache/2.2.3 (Unix) PHP/5.2.1
X-Powered-By: PHP/5.2.1
Content-Length: 117
Content-Type: text/html

array(2) {
  ["Host"]=>
  string(13) "192.168.2.106"
  ["Referer"]=>
  string(18) "The Forbidden Zone"
}

Labels: ,

Sunday, March 25, 2007

3500 words today, and counting

By standing on the shoulders of giants, Chapter 2: Accessibility has gone much easier than I even anticipated. Excerpt from the chapter, specifically the intro to the section "Screen readers can handle Ajax:"

If a user cannot see the screen (and the web application within it), they will need something to describe and read it to them. Note that it describes, as well as reads it. As touched upon in Chapter 2: Usability, semantic markup makes these descriptions much more relevant and meaningful to someone who does not (for example) have the ability to tell at a glance that four links have anything to do with each other, let alone that they provide navigation access to other parts of the web application.

A common misconception among Ajax developers and users alike: screen readers cannot handle dynamic content. They can, but similarly to supporting all of the major rendering engines of browsers, supporting the major engines in screen readers takes time and understanding. As a common example, Jaws and Windows-Eyes might recognize a focus change as a point to start reading, while Home Page Reader does not. As such, much like writing generic or all-encompassing code to support multiple browsers, writing scripts to dynamically change the DOM structure just needs to include all of the steps necessary for the most commonly used and supported screen readers.

Though use of text-only browsers such as Lynx or screen reader simulations such as the Firefox extension, Fangs do prove incredibly useful for quickly and easily checking a web application on initial page load, only by using a fully-fledged screen reader can you accurately and consistently test a dynamic web application. Jaws, developed by Freedom Scientific, has put itself into the majority of the market, especially in the United States, commanding a portion of the market comparable to IE's market share of browsers.

For developers whose primary development environment does not happen to consist of Windows and IE, the Fire Vox extension for Firefox has recently come onto the scene, and can run in Windows, Mac, and Linux. Initially written as a demo of CLC-4-TTS1, the extension has proven quite popular, and (through the CLC-4-TTS library) has beaten all of the big names in screen readers to offering support for the drafted WAI-ARIA guidelines, explored later in this chapter. It also provides MathML support (which Firefox supports "out of the box") and support for the CSS3 Speech Module.

  1. 1 Core Library Components for Text-to-Speech, written by Charles L. Chen, also the author of the Fire Vox extension

Labels: ,

Thursday, March 22, 2007

For a good example of why web applications should always regenerate session ID tokens on login

A sidenote in Chapter 8: Keeping a Web Application Secure

For a good example of why web applications should always regenerate session ID tokens on login, run tcpflow -i en0 -c port 80 | grep 'Set-Cookie:' and then navigate to a few banking or online payment sites. Most of them will set a cookie in order to store things like language, or to track your browsing for metrics. However, if the institutions do not regenerate a new session ID token on login, anybody who steals the initial, cleartext cookie, can then (assuming they take no other precautions such as tying sessions to IP addresses) use the cookie themselves without needing to authenticate as the victim.

Writing this chapter makes me hope more than ever that web developers working for financial institutions know how to keep things secure...unfortunately, common sense (and issues I've run into in the past) tells me that at least a few of them need to work on it a bit more, to put it entirely too mildly.

Labels: ,

Sunday, March 18, 2007

Intro to Chapter 8: Keeping a Web Application Secure

Many people currently have a misconception about Ajax-based web applications inherently lacking in security. While this has a basis more in misunderstanding the technology than in serious research, developers need to ensure that they do not leave doors open in the application that they might otherwise neglect, and inadvertently encourage this line of thought.

The only new technology occurring in Ajax-driven applications comes in the form of the XMLHttpRequest object, which only has the ability to make requests all browsers currently make already, with the restriction that the requests can only get made to the same domain name. In other words, while a browser makes request to any domain specified, the XMLHttpRequest object cannot perform cross-domain requests.

The largest security consideration specific to Ajax-driven web application development, a developer's mentality when writing the code itself must get kept in check. Just because users does not need to interact directly with JavaScript objects that send data to the server does not mean that they never will. Tools like Greasemonkey have made user scripts available and popular with users who don't even have any JavaScript knowledge, and can open up those abstracted objects to useful (if occasionally dangerous) functionality never intended by the developers.

In a nutshell, Ajax has not opened up any new security holes in web development, but it can raise the stakes. By exposing more of the server-side application to client-side scripting, developers broaden the surface area available to attackers. By involving more "moving parts" than in less dynamic web applications, it increases the chances that mistakes will get made. The practices elaborated on in this chapter minimize this risk.

Labels: ,

Thursday, March 08, 2007

Unit testing intro

Along with documentation, unit testing often gets left behind as a chore that should get done, but simply does not earn the attention from developers that it deserves. Maintaining and regularly running unit tests can have any number of beneficial effects on an application's development. These can include keeping the trunk stable, rather than having thoroughly untested changes create a ripple of frustration and lack of productivity hit other developers working on the same project.

More recently, unit testing has had a boost in popularity due to the Agile methods of software development, the short turnarounds of which thrive when the software has rigorous, frequent testing. No matter which methodology the development of an application follows, unit testing by individual developers can only help the quality and stability of the overall application.

For JavaScript, developers mostly use JsUnit, a JavaScript port of the Java JUnit unit testing tool. It works in all major browsers (IE6, IE7, Mozilla, Opera, and Safari), and provides a simple enough API to create tests almost immediately, while flexible enough to create entire nested suites of unit tests.

Labels: , ,

Wednesday, February 28, 2007

Some notes on Venkman

On a side note, after writing the bit on Venkman for the chapter on Debugging Client-side Code, I have to say that I have a whole new respect for the tool. I've generally fallen into the category of developers who installed Venkman, got a little overwhelmed at the interface, and moved on to other things in the rush to simply get things done, but I feel honestly quite a bit relieved to have sat down and gone through some use cases with it and actually learned how to use the amazingly flexible a tool. You can, for example, almost exactly replicate Firebug's JavaScript debugger within a remarkably small subset of Venkman's tools.

Additionally (I suppose, on a side-side note), Svend Tofte's tutorial definitely helped me discover some of the not-quite-so-obvious functionality Venkman offers. It doesn't provide (so far as I can tell, at least) the DOM Inspector hooks or anywhere near as concise or precise profiling as Firebug has available, but I have yet to see anything even close to its granularity around breakpoint management, from Meta Comments to conditional continuation, to Future breakpoints vs. standard breakpoints.

Labels: ,

Tuesday, February 20, 2007

Rounding out chapter 3

Looking again at the UserProfile object, almost every aspect of it, from the events object to the loadValues method, can easily get pulled out into a parent object that other data models can extend. The same also goes for the ProfileController object. Using inheritence in this manner not only prevents writing redundant code, it also vastly reduces the amount of JavaScript the browsers must download in order to run the web application in the first place. Data objects then only need to contain the code specific to that data, such as custom validation or authorization checks, rather than requiring that each data object also manage its own communications with the server.

Coupling the power of inheritence with the MVC pattern, an application gains a wealth of power in the form of quickly developed modules of functionality, supporting the overall application structure. Data filtering, cleaning, and management get supported by default, along with automatic updating of the server with the appropriate data no matter how convoluted an interface the user uses to interact with it.

These methodologies, combined with event-driven application development, provide a well-rounded base for many Ajax-driven applications. By using events to trigger actions throughout the application, objects stay abstracted enough for reuse in multiple interfaces, without the need for custom code to "hook in" the objects needing to interact with it.

As with all patterns, they should get regarded as tools to use for their suited purpose rather than rules to follow. The MVC pattern can add unnecessary layers to an otherwise small and simple interface. Event-driven architectures can add meaningless abstractions and hoops to jump through when dealing with large data sets or "streaming" results. In short: design the application for the requirements at hand. Doing otherwise will add complications and make the code much more difficult to maintain and debug.

Labels: , ,

Friday, January 26, 2007

Contrast comparisons

dark text on a black background darker, partially unreadable text on a black background

A color of rgb(100, 100, 100) on black has a luminosity contrast ratio of 3.550595556268441, falling short of both Level 2 and Level 3. When enhancing contrast and having such similar colors, it actually lessens the readability.

lighter text on a black background lighter, sharper text on a black background

A color of rgb(150, 150, 150) on black has a luminosity contrast ratio of 7.2236099811596866, which meets Level 2, but falls short of Level 3. Enhancement at this level sharpens the letters more than increasing the contrast between the text and the background.

even lighter text on a black background even lighter, sharper on a black background

A color of rgb(200, 200, 200) on black has a luminosity contrast ratio of 12.719459678993227, which exceeds Level 2 and Level 3. Enhancement at this level also sharpens the letters.

Side note: I kind of wish I had found the Colour Contrast Analyser Firefox Extension before writing the "High Contrast Design" section of the chapter.

Labels: , ,

Sunday, January 14, 2007

JSON vs. XML vs. XHTML

I've come to the conclusion that, abstracted properly, I really don't have a preference as to which one you use. The book will stay as messaging transportation method agnostic as possible, only using one method over another when it makes the most sense for that particular use case1.

Server-side validation
The result should return in a format easily parsed by JavaScript in order to highlight problem areas and provide a little metadata (such as the answer to "did it pass?"). Though XHTML, technically can get parsed as XML, the JavaScript then relies heavily on the markup structure of the page itself, which can lead to Very Bad Things. For this usage, either JSON or XML would work much better, but which one I would leave completely up to you.
Content replacement
By content replacement, I mean swapping out a large block where it really doesn't matter as to the contents (ie. navigating blog posts or looking up a word in reference materials). This one doesn't really matter which way you go about it. Even just swapping innerHTML with the responseText would work fine if you really wanted to go that route.
General server-side to client-side communication (and vice-versa)
Same story as with server-side form validation: it really doesn't matter...unless you either need to squeeze every last bit of performance out of your application (go with JSON), or you need output easier to consume by 3rd party applications (go with XML).

As a personal preference, I generally stick with (but no longer get into religious arguments about) using XML for the following reasons, in no particular order:

  • Easier to read when viewing the raw traffic
  • Easier to use from other, non JavaScript tools (though JSON libraries exist almost everywhere now)
  • I would rather use a transport method that, by default, does not have even the slightest chance of executing statements when parsed.
  • Habit
  • More portable, since many already-built applications need to keep the current language versions, many older installations of which do not yet have JSON libraries (which you can usually include, yes...but that gets into other issues)

The JSON vs. XML argument has gone on entirely too long for something that doesn't even really matter when it comes down to it. At this point, I might even implement some of the examples in a way that you can just change out the method you want to use and have it switch on the fly, since the architecture of the application that matters to the examples won't know or care how the data arrives or gets sent, anyway.

  • 1 All of these cases assume the normal, necessary error checking and validation routines before actually inserting anything into the page itself.

Labels:

Saturday, January 06, 2007

Inline Image Replacement (warning: hack alert)

In the process of designing the UI for indicating user's progress in a tabbed form, I realized I needed inline image replacement in order to accomplish exactly what I needed. The pure CSS solution works in Mozilla, Safari, and Opera, and should work in IE7 with some tweaking. IE6 will only work with JavaScript in place to convince it of what it should do.

The hack comes in, since I have only tried this with one set of transparent PNGs and this will probably take a fair amount of pounding on before it can stand up to wide usage. It also (for now) requires a solid background color.

Nevertheless, IIR. Suggestions actively encouraged... So far it works transparently (no pun intended) with screen readers, though the replaced text does go missing without the image there.

Labels: ,

Tuesday, December 26, 2006

Fangs

I just discovered that the Fangs extension for Firefox hadn't actually gone stale after all! I would guess, that like some other extensions and themes I've seen around, it seems (unfortunately) easier to not even bother with the official repository.

Fangs comes in handy when you need to quickly and easily get a rough idea of what a given page would sound like when using a screen reader. When I need to get a much better idea of the usability of a web application when doing things text-only, I generally use lynx to actually interact with the page. Using a screen reader, of course, lets you know exactly how it will (or won't) work, but for those who don't use screen readers day-to-day, this generally has cost, learning curve, and support implications (anyone know a decent Mac screen reader?).

I spent today writing more of Chapter 2: Usability, specifically the Semantic Markup section, so having Fangs back definitely made things a bit easier. I tried using MacOS X' Voice Over Utiliy for a few, but it seems altogether too clunky and not accurate enough for use with Safari. It also seems to read by page layout order, rather than the order of the markup, which sounds exceedingly horrible when you have a two-column layout like this one. I want it to work, and I sincerely hope I just missed a setting somewhere...

Labels:

Monday, December 18, 2006

Chapter 2 excerpt

Ajax usage has exploded in a manner resembling the upswing of such web technologies as:

  1. The blink and marquee HTML tags1
  2. Animated GIFs
  3. Applets
  4. The table HTML tag
  5. Flash

Each of these - admittedly, for the most part, less technical - exploded into usage to the point where (to varying degrees) most web designers and developers have reflexive, knee-jerk reactions upon the mention of them. The original usefulness of each technology now has an overshadowing of the preconceived notion that they cannot get used in any way beneficial to the general user2.

As such, Ajax-based functionality fits best where it makes a given task easier for the user, rather than replicating functionality easily achieved by simpler, faster-developed means. Using half a dozen JavaScript files, numerous CSS files, and several Ajax calls for content, simply in order to render a company home page uses up a lot of time and memory for very little by way of benefiting the user3, and actually makes the user wait much longer than necessary while using much more of your server resources than necessary.

In contrast, adding a light-weight content loading script that displays a blog's comments when requested by the user reduces loading time by using less bandwidth, and keeps the comments in better context rather than jumping to a comment page with (in some cases) drastically different design.

  • 1 Neither of these tags actually exist within the HTML specification, but browsers have supported them for years, regardless.
  • 2 With the exception of the blink and marquee tags, which actually have specific instructions against their usage written up by the W3C.
  • 3 This does not mean that the referenced technology does not ever have benefit to the user, just that this particular use case does not benefit the user enough to warrant its usage.

Labels: ,

Saturday, December 16, 2006

Updated sample and ajax.lib.js

The quick example now has some basic formatting and a link to run it.

More interestingly, from my perspective at least, I've updated the AjaxRequest and AjaxRequestManager objects.

The AjaxRequest object now has four events (open, send, load, and abort), and now has an actually readable onreadystatechange listener by using a quick trick in order to keep this references intact:

this.xhr.onreadystatechange = new Function("AjaxRequest.prototype.stateChanged.apply(requests["+id+"], arguments);");

The AjaxRequestManager now emulates support for event listening, in that it can accept addEventListener and removeEventListener calls. But instead of dispatching events, it auto-adds the listeners to each of the AjaxRequest objects it creates. This makes it a lot easier to write, for example, a Throbber object, since it can get added as a listener to each request in order to keep an eye on things while keeping things nice and loosely coupled.

Edited so you can read the code...

Labels: , ,

Friday, December 15, 2006

Current state of the Ajax library

A little large to post here, but you can check out the source and an example, where the usage boils down to:

this.request = request_manager.createAjaxRequest();
// For this example, this does nothing, but demonstrates how to set GET parameters
this.request.get = {
  one : 1,
  two : 2
 };
this.request.addEventListener('load', new Array(this, this.ran));
this.request.open('GET', 'xml.php');
return this.request.send();

In order to run the code, a simple new SimpleDemo().run(); will do the trick from Firebug (side note: sample only tested from Firefox - let me know how it fares in other browsers).

Basically, I need to ensure that usage like this makes things easier to read and port to other libraries. I honestly don't care if anyone actually uses this library, I just want the usability and abstraction to get through. The Ajax portion weighs in at just under seven kilobytes, including white-space, comments, and full names so you can actually read it, and I have every intention on keeping it that way. I've included a reference to Firebug Lite, just in case you don't have the full version installed.

Edit: okay, so the source code viewing works in Opera, but not Safari, and calling run(); from Firebug Lite pretty much does squat in either of them. Editing will commence, but I will still greatly appreciate any feedback and criticism.

Labels: , ,

Tuesday, December 12, 2006

Table of Contents

At least, as of right now. Suggestions? Comments? Complaints? Just know that some of these chapter sections mean more as notes to me than actual chapter sub-headings. Ask questions, though.

  1. Introductions1
    • Background Info
    • Intentions
    • Prerequisites
  2. Usability
    • Interface vs. Showcase
    • User Expectations
    • Feedback and Indications
    • Semantic markup
    • What CSS and JavaScript have in Common
  3. Accessibility
    • Section 508 and WCAG
    • Screenreaders Can Handle AJAX
    • Unobtrusive JavaScript
    • Assuming Nothing
    • Designing with Accessibility in Mind
  4. Client-side Application Architecture2
    • Objects and Event Triggering
    • Model-View-Controller Design Pattern
    • Event-driven Application Development
  5. Debug