Wednesday, July 14, 2010

Manuscript Submitted!

On Monday, I submitted my manuscript for Closure: The Definitive Guide to O'Reilly for copyedit review. The past two months of revisions were extremely stressful, so I can't even begin to describe what a huge relief hitting that milestone has been for me. Honestly, I thought the draft was in reasonable shape when I finished it back in May, so I ended up doing a lot more work than I expected to get it into a state suitable for submitting for copyedit.

Nevertheless, I am really excited with how much better the book has gotten in the past two months (it's probably one Amazon star better than it was before), though what is even more exciting is that I am already able to share the latest version with you via O'Reilly's Rough Cuts program. What I submitted for copyedit on Monday was just made available on Rough Cuts today! (Apparently you can see the Table of Contents and read the Foreword and Preface without paying for the book.)

Since the last update to Rough Cuts (mind you, that is when I thought I had a complete first draft), I have added an additional 91 pages for a whopping total of 546 pages. The following are some of the new sections that were added:

  • Detailed example of dividing compiled code into modules and loading them with the Closure Library (appears in Chapter 12).
  • Rewrite of the complex component example at the end of end of Chapter 8.
  • More hidden options in Chapter 14, which has been renamed to "Inside the Compiler."
  • An explanation of goog.events.KeyHandler in Chapter 6.
  • A section on goog.Uri in Chapter 7.
  • A section on mock objects in Chapter 15.
  • A new appendix on plovr (appears as Appendix C).
  • Acknowledgments in the Preface.
As part of the revising process, I (with the help of contributing author, Julie Parent) responded to all 100+ comments made on the Rough Cuts web site, which were a big help in improving the quality of the draft. Thank you so much to everyone who contributed so far! (Special thanks to Derek Slager, who filed the overwhelming majority of the corrections.) As the manuscript has not been finalized yet, you can still submit feedback now to help improve the final version of the book, so don't be shy!

For the next month or so, the manuscript will bounce back and forth between O'Reilly and me. According to Amazon, my book will be out on September 15, 2010, though I think that may be a little optimistic. Fortunately, the beauty of Rough Cuts is that you don't have to wait until the fall to get the help you need with Closure today!

Saturday, May 15, 2010

All Chapters Drafted!

This past week, I published a new update to my book-in-progress, Closure: The Definitive Guide. This update includes new chapters on the Closure Inspector and Closure Templates, which means that now every chapter has been drafted, so if you have been holding off on subscribing to the book because you thought the Rough Cut was "too rough," now you no longer have an excuse!

Though there are admittedly some sections that are still marked TODO, such as the section on "mocks" in Chapter 15 on the Testing Framework. There are also some sections that are mentioned in the text but lack a reference because they have not been drafted yet, such as the one on creating multiple modules with the Compiler and understanding line joining in Closure Templates. (Though the latter is explained in the online documentation.) Although I have my own punch list of things to add, please feel free to add comments on the Safari books page, as the feedback I have gotten there so far has already proved useful!

Also, if you have been following along with my page count graph, you will notice that things have flattened out lately:



There is also a striking difference of the slope of the lines in the blue and white sections, though what you may find even more curious is the discontinuity in the blue section. That's because I decided to try working in finance, and after seven weeks, I decided that it wasn't for me. It was actually a great company with incredibly sharp people, but I just couldn't get excited about the problems there as I could for the ones in building Web applications.

I got a new job at Yext, which is a much better fit for me. I realize the home page of Yext does not look like much, but I think that this TechCrunch article tells the story better than I can.

Fortunately, Yext has been very supportive of my book, so I was able to take a bit of time before starting to focus on writing, and as you can see from the graph, it has really paid off! Clearly, working at a startup has slowed my rate of progress, but it has given me more experience training engineers (who have never worked at Google) how to use Closure, so I think The Definitive Guide will be a better book in the long run because of it.

Although now that I'm about to enter the revising stage, I think a real sign of progress will be when the line on the graph starts to go down, because as Blaise Pascal (apparently not Mark Twain) said: "I have only made this [letter] longer, because I have not had the time to make it shorter."

Sunday, March 21, 2010

I'm a Golden Plover!


Today's update to the Rough Cut is particularly momentous as it features the cover of my book for the first time: the mysterious cover-choosing-cabal over at O'Reilly has chosen a golden plover as my animal, and I could not be more excited! (Contrary to popular belief, no, you do not get to pick your own animal.)

Although the Rhino has long been an icon of JavaScript books from O'Reilly, some of the more recent releases appear to be birds, so I'm thrilled to be part of that group.

The latest installment to the Rough Cut are the chapters on Client-Server Communication (20pp) and User Interface Components (50pp), which are core modules to the Closure Library, so I'm sure that this new information will be of great use to Closure neophytes (and likely some veterans, as well.)

Over the weekend, I finished drafting the chapter on Working with the Compiler Source Code. I am quite happy with the code samples that I came up with, and I hope they encourage JavaScript developers to start thinking about more innovative uses of the Compiler. Also, guest author Julie Parent has been hard at work on a chapter on goog.editor, the rich text editor widget in the Closure Library that seems to be a popular topic in the discussion group. Hopefully both of those chapters will also hit the Rough Cut in the next few weeks.

This means that 12 of the 16 chapters have been drafted, and the topics for the remaining four chapters are not as complex as those of the existing chapters, so the end is in sight! My current estimate for the final page count for the book is between 450-500 pages, which is nearly twice as long as I originally anticipated. I'm doing my best to put the Definitive in Closure: The Definitive Guide!

Friday, March 5, 2010

toString() Might Not Return a String

I was reading NCZ's JavaScript quiz, and it occurred to me that toString() is not guaranteed to return a string because it is, after all, just a method. Try to guess what is printed to the console when the following JavaScript is executed:
var obj = {
nine: 9,
toString: function() {
return this.nine;
},
valueOf: function() {
return 10;
}
};

console.log(obj.toString() === '9');
console.log('' + obj === '9');
console.log('' + obj.toString() === '9');
console.log(obj + obj);
console.log(String(obj) === '9');
Because obj.toString() returns a number, not a string, obj.toString() is the number 9, not the string '9', so the first expression is false.

In the second example, I would expect that because '' is a string, the value on the right of the + would also be coerced to a string via its toString() method, which means the result would be '9'. But I am wrong! It turns out that valueOf takes precedence, so '' + obj evaluates to '10', which means '' + obj === '9' is false. It would be true if there were no valueOf method defined on obj, though.

Because toString() is called explicitly in the third example, '' + obj.toString() becomes '' + 9, which evaluates to '9', so the expression is true.

The fourth one is interesting because '99', 18, and 20 are all reasonable guesses, but it turns out that valueOf() takes precedence again, so this evaluates to 20. If there were no valueOf() method defined on obj, then the result would be 18.

In the final example, String() is used as a function (and not as a constructor function, which you should never do!), and it does, in fact, return a string, so String(obj) === '9' evaluates to true. I always assumed that the implementation of String was something like:
function(s) {
return '' + s.toString();
};
Though a few years back, I discovered that alert.toString() throws an exception on IE6 (also alert.toString evaluates to undefined on IE6), but '' + alert and String(alert) return 'function alert() { [native code] }', as expected. At least in that case, my proposed implementation for String() would not work, though IE6 has been known to be nonstandard and buggy...

Monday, March 1, 2010

Update to Closure: The Definitive Guide

Today I'm excited to announce a significant update to Closure: The Definitive Guide. The book contains complete drafts of two new chapters that focus on the Closure Compiler: Using the Compiler and Advanced Compilation. These two chapters contribute 80 pages of new content in addition to the 167 pages that are already available.

Because I was curious, I also created a graph of my progress on the book that is automatically updated every six hours:



When I put together the original proposal for the book, I projected that it would only be 250 pages long. Clearly, that was an underestimate. This presents quite the opportunity for you, the reader, since I'd argue that the book is now underpriced as you can preorder the print version for only $25.99. For only $14 more, you can also get online and PDF access to the book today. If you do, I strongly encourage you to provide feedback on O'Reilly's web site. Remember, the book is still in draft form, so if you have suggestions on how the book could be improved, make them now so they can be included in the final version!

Sunday, February 21, 2010

New Firefox Extension: Fullscreen Tasks in Gmail

I know that when you have a lot of things to do, using Tasks in the cramped space within Gmail or Calendar may seem frustrating. There is actually a great workaround, which is to use the fullscreen version of the Tasks iGoogle gadget available at https://mail.google.com/tasks/canvas. Unfortunately, few people seem to know about it even though it was posted on the Gmail blog back in October.

My new extension simply adds a link in the sidebar that makes it possible to bring up the fullscreen version of Tasks in an iframe without leaving Gmail:



You can download the extension from http://bolinfest.com/chickenscratch/fullscreen-tasks-in-gmail.xpi. For some reason, you need to install it by first downloading it and then using the File -> Open File... menu in Firefox to open it up and install it. The traditional method of installing, which is just going to the URL in Firefox, does not seem to work for some reason: I get some nonsense about it not being a valid install package.

Because I thought this was going to be a short script, I originally tried to write it in Greasemonkey because I feel like it is easier to get users to install Greasemonkey scripts than separate extensions these days. Initially I tried using the Gmail Greasemonkey API, but unfortunately it is super-busted: many of the methods in the API do not work right now.

Then I considered looking under the hood of Gmail and trying to use XPaths, but those were nightmarish and would be likely to break, so I decided that I really needed some of the primitives in Chickenfoot to grab the appropriate DOM elements. For example, to display Tasks, I need to hide the threadlist and insert my iframe. In Chickenfoot, I came up with a fairly good heuristic:
  var n1 = find('first select all').element;
var n2 = find('second select all').element;
if (!n1 || !n2) {
return false;
}
ancestor = goog.dom.findCommonAncestor(n1, n2);
dom = goog.dom.getDomHelper(ancestor);

This essentially finds the DOM element for each of the "Select: All" controls that appear above and below the threadlist, and uses their common ancestor as the node to hide to make room for my Tasks iframe.

If you are interested, the code for the Chickenfoot script is also available. In creating the extension, I ended up fixing some bugs in Chickenfoot, but also added some new features, so when Chickenfoot 1.0.8 is released, it will be possible to run my script as-is. One new feature is that Closure Lite will be available as a library in Chickenfoot, so with the include('closure-lite.js') call in Chickenfoot, lots of goog goodness will be readily available, which made the development of this script go so much faster.

For a script that should be so easy to write, it may be surprising that it is over 100 lines long. Much of this is because I tried to include a number of features that should make the extension easier to use:
  • Keyboard shortcut that works when either the threadlist or the Tasks iframe have focus.
  • Tooltip to make the keyboard shortcut more discoverable.
  • Logic to ensure that the style of the "Full Tasks" link matches that of your Gmail theme.
  • Focus is given back to the threadlist when exiting fullscreen Tasks.
  • The Tasks iframe is resized when the browser window is resized.
  • Timing logic to account for the fact that many things in Gmail are loaded asynchronously.
I bring this up not just to toot my own horn, but to comment on something that I recently read about in Coders at Work that Kushal recently touched upon on his blog as well, which is the idea of the "empathy gene". (Some bloggers misattribute the phrase to Josh Bloch because he brings it up in his interview in Coders at Work, but Bloch actually attributes the phrase to Kevin Bourrillion during the interview.)

I think it's particularly relevant in this example because most userscripts that I have looked at are pretty hacky pieces of code. This is partially because most userscripts are viewed as hacks in the first place, though there is nothing about writing userscripts that forces them to be that way. For example, with my new extension, there are a million ways I could have chosen to jam a Tasks iframe into Gmail, most of which would have taken many fewer lines of code. But to make something reliable, thoughtful, and usable took a lot more code than that. I like to think that this is my empathy gene at work.

An even better example of non-hacky Greasemonkey scripts are those written by Mihai. Mihai clearly has the empathy gene, which is one of the reasons why Google Reader is such a great product. (Though even an empathetic guy like Mihai has been known to ruin Christmas every once in awhile -- oops!)

Finally, although I enjoyed creating this extension and am glad that I also made improvements to Chickenfoot in the process, I would be even happier if this feature (or something like it) were made available in Gmail (I'm looking at you, Mountain View!). Though if Tasks were able to "graduate" into the navigation bar in the top of the page that is available across all apps, that would solve most of my problems. It may be time to update iGoogleBar to do exactly that!

Tuesday, January 26, 2010

I'm a Semi-Published Author! (Closure: The Definitive Guide)

Today, I am officially a semi-published author in that the half of the book I am working on is available (for pay) online as part of O'Reilly's Rough Cuts program! The title is Closure: The Definitive Guide, and as you may have guessed, the aim is to create an (invaluable!) manual for the Closure Tools suite. When I am finished, the book will cover the Library, Templates, the Compiler, the Testing Framework, and the Inspector, though the six chapters that are available today are only on the Library. However, if you purchase the book through Rough Cuts, you will get the updates to the book as I publish them there, so it is more like buying a subscription than a book.

I am extremely excited about the Rough Cuts program because it allows me to get information out to you, the web developer, much faster than I could if I forced you to wait for the print version. It also gives you the opportunity to provide me with feedback to help ensure that the Guide contains the information that you need.

For those of you who have purchased a book via Rough Cuts before, you may be surprised to see how "rough" my book is compared to the other offerings. This is a fairly new program at O'Reilly, so the first books to go through Rough Cuts were not made available until a nearly complete draft of the book was done. By comparison, my book is half done and has gone through neither copy edit nor technical review. So when providing feedback, please bear in mind the staff at O'Reilly will ultimately help with things like the misuse of parallel structure, but I need your help in determining when something merits a code sample or more explanation.

The material that is currently available is:
  • Preface
  • Chapter 1: Introduction to Closure
  • Chapter 2: Annotations for Closure JavaScript
  • Chapter 3: Closure Primitives
  • Chapter 4: Common Utilities
  • Chapter 5: Classes and Inheritance
  • Chapter 6: Event Management
  • Appendix A: Inheritance Patterns in JavaScript
  • Appendix B: Frequently Misunderstood JavaScript Concepts
Although there is nothing that requires me to write the chapters in order, I was encouraged to start out that way in order to have something that would be well-connected for Rough Cuts readers. This meant that I had to draft the introduction earlier than I would have liked, but I am actually quite happy with what is there right now. Among other things, it contains a complete "Hello World" example that shows how to use all of the tools together, which is something I have yet to see on any blogs or even as part of Google's own documentation.

Currently, I am taking a break from writing more on the Library and am skipping a few chapters ahead to start focusing on the Compiler. As an active member of the Closure Google Groups, it is pretty clear to me that developers need more help in that area, so I hope to make that information available soon.

I also hope to improve Closure in the process of writing this book. When I run into things that I feel are hard to explain, sometimes I end up filing bugs or feature requests against Closure with proposed changes. It is so much easier to write a few paragraphs to report a bug than it is to draft several pages to explain away a quirk!

With 150 pages of content, I suspect I have given you enough to chew on while I put together more information on the Compiler. Please take a look and let me know what you think.

Update: Changed the book link from http://techbus.safaribooksonline.com/9781449381882 to http://my.safaribooksonline.com/9781449381882 where it is actually possible to purchase the book! There is a button that says "Purchase Options" on the upper-right.