Bootstrapping

Tip

This section discusses some material that you may want to initially skim over and come back to review once you feel well acquainted with Dojo.

Before you can use Dojo at all, you have to somehow get it into the page. Regardless of whether you install Dojo locally or load it via AOL's CDN, you simply provide a SCRIPT tag that points to the file that loads some JavaScript code, and then magic elves inside of your web browser miraculously causes everything to "just work," right? Well, not quite. Like most other things in computing, it all comes back to pure and simple automation, and Dojo's bootstrap process is not different.

Tip

The term "bootstrap" refers to the idea of "pulling yourself up by your own bootstraps." In other words, it's the idea of getting up and running without help from anywhere else. The notional idea of Dojo bootstrapping itself is the same concept as your computer "booting up" when you turn it on.

For the record, Example 1-2 is the absolute minimum effort that is generally required to get some XDomain Dojo goodness into your HTML page. What's especially notable about loading Dojo from the CDN is that less than 30KB of data comes across the wire. Chances are good that you'll use the previous code block, or some variation of it, quite often. Save yourself some typing by copying it into a template that you can reuse.

Example 1-2. A minimalist application harness example

<html>
  <head>
    <title>Title Goes Here</title>
    <!-- A lightweight style sheet that smoothes out look and feel across browsers -->
   <link rel="stylesheet"  type="text/css"
       href="http://o.aolcdn.com/dojo/1.1/dojo/resources/dojo.css" />

    <script
      type="text/javascript"
      src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js">
    </script>

    <script type="text/javascript">
        /* If needed, Dojo modules may be asynchronously requested into the page
here via dojo.require statements... */

        dojo.addOnLoad(function(  ) {

            /* Any content that depends upon dojo.require statements goes here... */

        });
    </script>

  </head>
  <body>
    <!-- ... -->
  </body>
</html>

Tip

The dojo.addOnLoad function accepts another function as its parameter. The examples in this book generally supply this parameter with an anonymous function, although you could opt to define a function like var init = function( ) { /*...*/} and pass it in. Anonymous functions and some of the reasons they are important were briefly discussed in the Preface.

Two new constructs in the previous listing include the dojo.require statement and the dojo.addOnLoad block. The dojo.require statement is discussed at length in the section "Managing Source Code with Modules" in Chapter 2, but in a nutshell, it pulls a named resource into the page for you to use the same way that import works in Java or #include works in C programming. One incredibly important aspect of dojo.require is that it performs synchronous loading for local installations of the toolkit but acts asynchronously if you are doing XDomain loading. That distinction is especially important as it relates to dojo.addOnLoad.

dojo.addOnLoad

Because dojo.require statements act asynchronously over XDomain loads, it is not necessarily safe to immediately use resources you have requested via dojo.require when the page loads[9] because latency and other factors may (and usually will) cause some delay. Then, when you try to reference a module requested via dojo.require that is not yet loaded, you get a nice error thrown at you and the entire bootstrapping process most likely screeches to a halt. The technical term for the situation in which the outcome is undefined because of unpredictable timing constraints that compete with one another is called a race condition.

For the reasons just mentioned, using dojo.addOnLoad is a very good habit to get into because it makes your page as portable as possible—whether or not it is XDomain-loaded.

Warning

A common mistake is not using dojo.addOnLoad to safely and portably perform logic that should occur after the page loads and all dojo.require statements have been satisfied. The issue usually comes up when you have developed locally and then start switching SCRIPT tags to do XDomain loading.

Given that the previous code snippet uses XDomain loading, there aren't any extra steps involving local installation, so it really is a one-step process to bootstrap the entire toolkit from an existing page.

Tip

Although widgets are not introduced for many more chapters, another nuance of addOnLoad that bears mentioning—because we're on the topic—is that addOnLoad does not fire until after widgets have been parsed in the page (assuming Dojo has been configured to parse widgets on page load).

While bootstrapping is synonymous with "loading a script" at a high level, there's a lot more happening with that loading process than meets the eye. From a bird's eye view, at least two basic actions occur, though not necessarily in this exact order:

Platform configuration

Takes into account any custom configuration options that may have been specified through djConfig, an associative array that must be defined before the SCRIPT tag that loads Dojo is executed or as an attribute of the SCRIPT tag that loads Dojo. More specifics on djConfig are coming up later in this chapter.

Determines Dojo should be cross-domain loaded or loaded locally. XDomain loading details happen transparently so long as an Internet connection is available and the inclusion of the XDomain loader was configured at build time. By default, configuring for XDomain loading produces a dojo.xd.js (and other *.xd.js build artifacts), which provides a replacement for standard dojo.js.

Based on the environment specified for the particular build of Dojo (usually the browser but it could also be another option such as Rhino or a mobile device), sets up any environment-specific features. Even though you won't generally need to perform browser-specific configuration when using the default build of Dojo for the browser, Base still provides data members like dojo.isIE and dojo.isFF to expose the underlying browser for those few times when you do need them.

Performs browser-specific augmentation such as establishing an XMLHttpRequest (XHR) object for asynchronous calls using Dojo's various AJAX utilities. Workarounds for browser incompatibilities such as normalizing DOM events, standardizing a map of key codes, and extra measures to minimize and prevent memory leaks are also handled.

Namespace establishment and loading

Establishes the dojo namespace so that all of the utility provided by the toolkit does not clobber any existing symbols in the page.

Loads the dojo namespace with the various functions and symbols that constitute Base.

Tip

Although less frequently used than dojo.addOnLoad, dojo.addOnUnload is the preferred vehicle for performing logic that should take place when the page unloads.

Configuration with djConfig

Tip

Much of the content in this section will make a lot more sense once you've spent some time writing code, so don't feel the need to dwell on it. It's here as a reference more than anything.

Upcoming sections introduce djConfig, a configuration switch that you can place in the SCRIPT tag that bootstraps the toolkit (or define anytime before Dojo bootstraps) to customize where it looks for resources, whether debugging tools should be wired in, and so on.

Table 1-1 provides a synopsis of the key/value pairs you can pass into it to configure the bootstrapping process. (Some of the commentary may introduce constructs that have not yet been introduced. For now, just skim over those and come back to them whenever the occasion calls for it.)

Warning

Defining djConfig anytime after the SCRIPT tag that loads the toolkit executes has no effect.

Table 1-1. djConfig configuration switches

Key

Value type (default value)

Comment

[a]

afterOnLoad

Boolean

(false)

Used to facilitate injecting Dojo into a page after it has already been loaded. Useful for hacking on a page or developing widgets that are necessarily lazy-loaded, i.e., for social networking apps, etc.

baseUrl

String

(undefined)

Technically, this parameter allows you to redefine the root level path of the toolkit for a local or an XDomain load, usually for the purpose of resolving dependencies such as custom modules. In practice, however, it is almost exclusively used to resolve local modules when bootstrapping over XDomain.

cacheBust

String|Date

(undefined)

In the case of a String value, appends the value provided to requests for modules so that previous version of the page that is cached locally will be overridden. Typically, this value will be a random string of characters that you generate yourself or a unique identifier for your application version that would prevent nasty bugs from surfacing that may be caused by older versions of modules.

During the development cycle, you might provide a Date value such as (new Date( )).getTime( ), which guarantees a new value each time the page loads and prevents annoying caching problems.

debugAtAllCosts

Boolean

(false)

Usually provides more specific debugging information at the cost of performance. You might specify this value to better track down the line number where an error occurred if you are told that an error originated in a build file like bootstrap.js, dojo.js, or dojo.xd.js.

dojoBlankHtmlUrl

String

("")

Used to provide the location for a blank HTML document, which is necessary for using the IFRAME transport via dojo.io.iframe.create (discussed in Chapter 4). A default is located at dojo/resources/blank.html.

dojoIframeHistoryUrl

String

("")

Used to provide the location for a special file that is used in combination with dojo.back, a module for managing the back button (discussed in Chapter 2). A default is located at dojo/resources/iframe_history.html.

enableMozDomContentLoaded

Boolean

(false)

Gecko-based browsers like Firefox may optionally use the DOMContentLoaded event as the trigger to signal that the page has loaded because of a technical nuance related to synchronous XHR request involving a document greater than 65536 bytes[a]

extraLocale

String or Array

("")

Used to specify additional locales so that Dojo can transparently handle the details associated with providing a localized module. Values may be provided as a String value or as an Array of String values.

isDebug

Boolean

(false)

Loads Firebug or Firebug Lite machinery for debugging. Note that stubs for debugging functions such as the various console methods are in place by default so that code doesn't bust if you choose to remove diagnostic information from your application.

libraryScriptUri

String

("")

Used to configure nonbrowser environments such as Rhino and SpiderMonkey (JavaScript engines) in a manner similar to the way that baseUrl works for browser environments.

locale

String

(browser provided)

Used to override dojo.locale with a local other than the one that is retrieved from the browser.

modulePaths

Object

(undefined)

Specifies a collection of key/value pairs that associates modules with their relative paths on disk. While you'll generally place your modules in the toolkit's root directory, this parameter allows for variations if they are needed. When loading Dojo from the CDN or other XDomain, a baseUrl parameter is also required.

parseOnLoad

Boolean

(false)

Specifies whether to automatically parse the page for widgets on page load (essentially just a dojo.parser.parse( ) function call at the appropriate time during the bootstrap process).

require

Array

([])

Provides a convenient way of providing modules that should be automatically required once Base loads. When used in conjunction with afterOnLoad, it designates resources that should be loaded when injecting Dojo into a page after the page has already loaded.

useXDomain

Boolean

(false)

Used to force XDomain loading. This action is taken by default with XDomain builds. (See "Benefits of Using XDomain Builds" for benefits of using XDomain loading locally.)

xdWaitSeconds

Number

(15)

Specifies the number of seconds to wait before timing out a request for resources that are cross-domain loaded.

Warning

The djConfig parameter is modulePaths, while the Base function for setting up individual module paths is dojo.registerModulePath (no "s" on the end).

Most of the time, you will define djConfig in the same SCRIPT tag that bootstraps the toolkit using Object -like syntax. The following example illustrates:

<script
    type="text/javascript"
    src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js"
    djConfig="parseOnLoad:true,isDebug:true">
</script>

However, you might opt to define it prior to the SCRIPT tag that loads the toolkit if you have a lot of configuration switches, or if it's just more convenient to do it that way for your particular situation. Here's a translation of the previous example that produces the very same effect:

<script type="text/javascript">
    djConfig = {
        parseOnLoad : true,
        isDebug : true
    };
</script>

<script
  type="text/javascript"
  src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js ">
</script>


[9] Generally speaking, the page load occurring consists of either the window's onload event or possibly the DOMContentLoaded for Mozilla variations completing.

Get Dojo: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.