www.it-ebooks.info www.it-ebooks.info Closure: The Definitive Guide Michael Bolin Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo www.it-ebooks.info Closure: The Definitive Guide by Michael Bolin Copyright © 2010 Michael Bolin. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://my.safaribooksonline.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or corporate@oreilly.com. Editors: Simon St.Laurent and Julie Steele Production Editor: Kristen Borg Copyeditor: Nancy Kotary Proofreader: Kristen Borg Indexer: Ellen Troutman Zaig Cover Designer: Karen Montgomery Interior Designer: David Futato Illustrator: Robert Romano Printing History: September 2010: First Edition. Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. Closure: The Definitive Guide, the image of a golden plover, and related trade dress are trademarks of O’Reilly Media, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trademark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions, or for damages resulting from the use of the information con- tained herein. ISBN: 978-1-449-38187-5 [M] 1283888246 www.it-ebooks.info Table of Contents Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii My Experiences with Closure xviii Audience xx ECMAScript Versus JavaScript xx Using This Book xxi Acknowledgments xxiv 1. Introduction to Closure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Tools Overview 2 Closure Library 2 Closure Templates 3 Closure Compiler 3 Closure Testing Framework 4 Closure Inspector 4 Closure Design Goals and Principles 5 Reducing Compiled Code Size Is Paramount 5 All Source Code Is Compiled Together 6 Managing Memory Matters 6 Make It Possible to Catch Errors at Compile Time 7 Code Must Work Without Compilation 7 Code Must Be Browser-Agnostic 7 Built-in Types Should Not Be Modified 8 Code Must Work Across Frames 8 Tools Should Be Independent 8 Downloading and Installing the Tools 9 Closure Library and Closure Testing Framework 10 Closure Templates 11 Closure Compiler 12 Closure Inspector 12 iii www.it-ebooks.info Example: Hello World 12 Closure Library 13 Closure Templates 14 Closure Compiler 17 Closure Testing Framework 19 Closure Inspector 21 2. Annotations for Closure JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 JSDoc Tags 25 Type Expressions 29 Simple Types and Union Types 29 Function Types 31 Record Types 32 Special @param Types 33 Subtypes and Type Conversion 38 The ALL Type 41 JSDoc Tags That Do Not Deal with Types 41 Constants 42 Deprecated Members 43 License and Copyright Information 43 Is All of This Really Necessary? 43 3. Closure Library Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Dependency Management 45 calcdeps.py 45 goog.global 47 COMPILED 48 goog.provide(namespace) 48 goog.require(namespace) 50 goog.addDependency(relativePath, provides, requires) 51 Function Currying 54 goog.partial(functionToCall, ) 54 goog.bind(functionToCall, selfObject, ) 57 Exports 58 goog.getObjectByName(name, opt_object) 58 goog.exportProperty(object, propertyName, value) 58 goog.exportSymbol(publicPath, object, opt_objectToExportTo) 60 Type Assertions 61 goog.typeOf(value) 62 goog.isDef(value) 62 goog.isNull(value) 63 goog.isDefAndNotNull(value) 63 goog.isArray(obj) 63 iv | Table of Contents www.it-ebooks.info goog.isArrayLike(obj) 64 goog.isDateLike(obj) 64 goog.isString(obj), goog.isBoolean(obj), goog.isNumber(obj) 64 goog.isFunction(obj) 65 goog.isObject(obj) 65 Unique Identifiers 65 goog.getUid(obj) 65 goog.removeUid(obj) 66 Internationalization (i18n) 67 goog.LOCALE 67 goog.getMsg(str, opt_values) 68 Object Orientation 68 goog.inherits(childConstructorFunction, parentConstructorFunction) 68 goog.base(self, opt_methodName, var_args) 69 goog.nullFunction 69 goog.abstractMethod 70 goog.addSingletonGetter(constructorFunction) 70 Additional Utilities 70 goog.DEBUG 70 goog.now() 71 goog.globalEval(script) 71 goog.getCssName(className, opt_modifier), goog.setCssNameMapping(mapping) 71 4. Common Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 goog.string 75 goog.string.htmlEscape(str, opt_isLikelyToContainHtmlChars) 75 goog.string.regExpEscape(str) 77 goog.string.whitespaceEscape(str, opt_xml) 78 goog.string.compareVersions(version1, version2) 78 goog.string.hashCode(str) 79 goog.array 79 goog.array.forEach(arr, func, opt_obj) 80 Using Iterative goog.array Functions in a Method 81 goog.object 82 goog.object.get(obj, key, opt_value) 82 goog.setIfUndefined(obj, key, value) 83 goog.object.transpose(obj) 83 goog.json 84 goog.json.parse(str) 85 goog.json.unsafeParse(str) 85 goog.json.serialize(obj) 86 goog.dom 86 Table of Contents | v www.it-ebooks.info goog.dom.getElement(idOrElement) 86 goog.dom.getElementsByTagNameAndClass(nodeName, className, elementToLookIn) 87 goog.dom.getAncestorByTagNameAndClass(element, tag, className) 89 goog.dom.createDom(nodeName, attributes, var_args) 91 goog.dom.htmlToDocumentFragment(htmlString) 92 goog.dom.ASSUME_QUIRKS_MODE and goog.dom.ASSUME_STANDARDS_MODE 93 goog.dom.classes 95 goog.dom.classes.get(element) 95 goog.dom.classes.has(element, className) 95 goog.dom.classes.add(element, var_args) and goog.dom.classes.remove(element, var_args) 96 goog.dom.classes.toggle(element, className) 96 goog.dom.classes.swap(element, fromClass, toClass) 97 goog.dom.classes.enable(element, className, enabled) 98 goog.userAgent 98 Rendering Engine Constants 99 Platform Constants 101 goog.userAgent.isVersion(version) 102 goog.userAgent.product 102 goog.net.cookies 104 goog.net.cookies.isEnabled() 104 goog.net.cookies.set(name, value, opt_maxAge, opt_path, opt_domain) 104 goog.net.cookies.get(name, opt_default) 105 goog.net.cookies.remove(name, opt_path, opt_domain) 105 goog.style 105 goog.style.getPageOffset(element) 105 goog.style.getSize(element) 106 goog.style.getBounds(element) 106 goog.style.setOpacity(element, opacity) 106 goog.style.setPreWrap(element) 106 goog.style.setInlineBlock(element) 106 goog.style.setUnselectable(element, unselectable, opt_noRecurse) 107 goog.style.installStyles(stylesString, opt_node) 107 goog.style.scrollIntoContainerView(element, container, opt_center) 108 goog.functions 108 goog.functions.TRUE 108 goog.functions.constant(value) 108 goog.functions.error(message) 109 vi | Table of Contents www.it-ebooks.info 5. Classes and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Example of a Class in Closure 112 Closure JavaScript Example 112 Equivalent Example in Java 115 Static Members 116 Singleton Pattern 118 Example of a Subclass in Closure 119 Closure JavaScript Example 119 Equivalent Example in Java 123 Declaring Fields in Subclasses 124 @override and @inheritDoc 125 Using goog.base() to Simplify Calls to the Superclass 126 Abstract Methods 127 Example of an Interface in Closure 128 Multiple Inheritance 130 Enums 132 goog.Disposable 132 Overriding disposeInternal() 133 6. Event Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A Brief History of Browser Event Models 137 Closure Provides a Consistent DOM Level 2 Events API Across Browsers 138 goog.events.listen() 138 goog.events.EventTarget 141 goog.events.Event 146 goog.events.EventHandler 148 Handling Keyboard Events 152 7. Client-Server Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Server Requests 155 goog.net.XmlHttp 155 goog.net.XhrIo 156 goog.net.XhrManager 161 goog.Uri and goog.uri.utils 163 Resource Loading and Monitoring 165 goog.net.BulkLoader 165 goog.net.ImageLoader 167 goog.net.IframeLoadMonitor 168 goog.net.MultiIframeLoadMonitor 169 goog.net.NetworkTester 169 Cross-Domain Communication 170 goog.net.jsonp 171 goog.net.xpc 173 Table of Contents | vii www.it-ebooks.info Uploading Files 176 Comet 178 8. User Interface Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Design Behind the goog.ui Package 182 goog.ui.Component 184 Basic Life Cycle 184 Components with Children 190 Events 194 States 195 Errors 196 goog.ui.Control 197 Handling User Input 198 Managing State 199 Delegating to the Renderer 201 Example: Responding to a Mouseover Event 206 goog.ui.Container 206 Using Common Components 210 Pulling in CSS 212 goog-inline-block 215 Example of Rendering a Component: goog.ui.ComboBox 218 Example of Decorating a Control: goog.ui.Button and goog.ui.CustomButton 220 Creating Custom Components 227 example.Checklist and example.ChecklistItem 228 example.ui.ChecklistItem and example.ui.ChecklistItemRenderer 229 example.ui.Label 232 example.ui.Checklist and example.ui.ChecklistRenderer 233 Rendering Example 236 Decorating Example 237 Conclusions 239 9. Rich Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Design Behind the goog.editor Package 241 Trade-offs: Control, Code Size, and Performance 242 goog.editor.BrowserFeature 243 Creating an Editable Region 243 goog.editor.Field 244 goog.editor.SeamlessField 251 Extending the Editor: The Plugin System 253 Registering Plugins 253 Interacting with Plugins 254 goog.editor.Plugin 256 viii | Table of Contents www.it-ebooks.info [...]... customizations against another team’s need to keep the size of the JavaScript they’re sending to the user small? The Closure Tools were designed to solve many of these problems Maybe that’s understating the point These problems are at the very core of their design Many of the tools were started by our friends on Gmail Gmail began as a relatively modest JavaScript app Then they added more and more features,... and Principles Before diving into the code, it is important to understand the design goals and principles that motivate the implementation of the Closure Tools Much of the design of the toolkit is motivated by the capabilities of the Compiler and the style of the Library Reducing Compiled Code Size Is Paramount The primary objective of the Closure Compiler is to reduce the size of JavaScript code Because... of the Gmail client, which precipitated the development of the two other major tools in the Closure suite: the Library and Templates The Library was simply named “Closure,” as it was a play on the programming construct used so frequently in JavaScript, as well as the idea that it would bring “closure” to the nightmare that was JavaScript development at Google Like many other JavaScript toolkits, the. .. explains the design of the Closure Library event system and the best practices when using it • Chapter 7, Client-Server Communication, covers the various ways the goog.net package in the Closure Library can be used to communicate with the server Preface | xxi www.it-ebooks.info • Chapter 8, User Interface Components, discusses a number of the UI widgets provided by the Closure Library and documents the. .. Nevertheless, even though it is possible to compile jQuery with the Compiler or to use Templates to create functions that can be called from Dojo, the entire Closure suite should be adopted to achieve the maximum benefit from the tools It is indeed the case with Closure that the whole is greater than the sum of its parts For example, although the Library and the Compiler can be used independently, they... from evaluating expressions at compile time rather than runtime All Source Code Is Compiled Together The Compiler is designed to compile all code that could be run during the course of the application at once As shown in Figure 1-1, there are many potential sources of input, but the Compiler receives all of them at the same time This is in contrast to other languages, in which portions of source code... all of the Closure Tools in the order they are most likely to be used • Chapter 1, Introduction to Closure, introduces the tools and provides a general overview of how they fit together with a complete code example that exercises all of the tools When working on a JavaScript project, you will spend the bulk of your time designing and implementing your application Because of this, the majority of the book... in the suite is open-sourced under the Apache 2.0 license, and is created, maintained, and made available for free by Google Closure is used in the development of many web applications at Google, including Gmail, Google Maps, and Google Docs The performance and scale of these web applications is a testament to the strength and sophistication of the Closure Tools suite Some developers might balk at the. .. reduces bandwidth costs Further, it helps protect your IP because renaming variables serves to obfuscate your code, making it more difficult for other websites to copy your functionality Tools Overview In addition to the Closure Compiler, there are currently four other tools available in the Closure suite Figure 1-1 shows the common workflow when using all of the tools together This section provides... brings together a number of web development tools, including a JavaScript debugger, available through the browser When using the Firebug debugger with obfuscated code produced by the Closure Compiler, it is hard to trace a runtime error back to its position in the original source code The Closure Inspector facilitates debugging by exposing the mapping between the original and compiled code in the Firebug . www.it-ebooks.info www.it-ebooks.info Closure: The Definitive Guide Michael Bolin Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo www.it-ebooks.info Closure: The Definitive Guide by Michael Bolin Copyright. against another team’s need to keep the size of the JavaScript they’re sending to the user small? The Closure Tools were designed to solve many of these problems. Maybe that’s un- derstating the point for them to add new features. This triggered a rewrite of the Gmail client, which precipitated the development of the two other major tools in the Closure suite: the Library and Templates. The