Permalink
Browse files

Merge branch 'documentation' into documentation_merge

Conflicts:
	src/dom/dom.js
	src/lang/array.js
	src/lang/date.js
	src/lang/hash.js
	src/lang/object.js
	src/lang/string.js
  • Loading branch information...
2 parents 550ec6e + e13bf37 commit c9a9d1c8be17a0e7c451767275e5b53d8c2271ba @samleb samleb committed Mar 8, 2010
View
@@ -3,31 +3,31 @@
*
* Prototype's APIs around the `XmlHttpRequest` object.
*
- * The Prototype framework enables you to deal with Ajax calls in a manner that is
- * both easy and compatible with all modern browsers.
+ * The Prototype framework enables you to deal with Ajax calls in a manner that
+ * is both easy and compatible with all modern browsers.
*
* Actual requests are made by creating instances of [[Ajax.Request]].
*
- * <h5>Request headers</h5>
+ * ##### Request headers
*
* The following headers are sent with all Ajax requests (and can be
* overridden with the `requestHeaders` option described below):
*
* * `X-Requested-With` is set to `XMLHttpRequest`.
* * `X-Prototype-Version` is set to Prototype's current version (e.g.,
- * `1.6.0.3`).
+ * `<%= PROTOTYPE_VERSION %>`).
* * `Accept` is set to `text/javascript, text/html, application/xml,
* text/xml, * / *`
* * `Content-type` is automatically determined based on the `contentType`
* and `encoding` options.
*
- * <h5>Ajax options</h5>
+ * ##### Ajax options
*
* All Ajax classes share a common set of _options_ and _callbacks_.
* Callbacks are called at various points in the life-cycle of a request, and
* always feature the same list of arguments.
*
- * <h5>Common options</h5>
+ * ##### Common options
*
* * `asynchronous` ([[Boolean]]; default `true`): Determines whether
* `XMLHttpRequest` is used asynchronously or not. Synchronous usage is
@@ -64,10 +64,10 @@
* `true` otherwise): Sanitizes the contents of
* [[Ajax.Response#responseText]] before evaluating it.
*
- * <h5>Common callbacks</h5>
+ * ##### Common callbacks
*
* When used on individual instances, all callbacks (except `onException`) are
- * invoked with two parameters: the `XMLHttpRequest` object and the result of
+ * invoked with two parameters: the [[Ajax.Response]] object and the result of
* evaluating the `X-JSON` response header, if any (can be `null`).
*
* For another way of describing their chronological order and which callbacks
@@ -4,9 +4,9 @@
* Periodically performs an Ajax request and updates a container's contents
* based on the response text.
*
- * `Ajax.PeriodicalUpdater` behaves like [[Ajax.Updater]], but performs the
+ * [[Ajax.PeriodicalUpdater]] behaves like [[Ajax.Updater]], but performs the
* update at a prescribed interval, rather than only once. (Note that it is
- * _not_ a subclass of `Ajax.Updater`; it's a wrapper around it.)
+ * _not_ a subclass of [[Ajax.Updater]]; it's a wrapper around it.)
*
* This class addresses the common need of periodical update, as required by
* all sorts of "polling" mechanisms (e.g., an online chatroom or an online
@@ -16,10 +16,11 @@
* keeping track of the response text so it can (optionally) react to
* receiving the exact same response consecutively.
*
- * <h5>Additional options</h5>
+ * ##### Additional options
*
- * `Ajax.PeriodicalUpdater` features all the common options and callbacks
- * described in the [[Ajax section]] &mdash; _plus_ those added by `Ajax.Updater`.
+ * [[Ajax.PeriodicalUpdater]] features all the common options and callbacks
+ * described in the [[Ajax section]] &mdash; _plus_ those added by
+ * [[Ajax.Updater]].
*
* It also provides two new options:
*
@@ -34,9 +35,9 @@
* is the same; when the result is different once again, `frequency` will
* revert to its original value.
*
- * <h5>Disabling and re-enabling a <code>PeriodicalUpdater</code></h5>
+ * ##### Disabling and re-enabling a [[Ajax.PeriodicalUpdater]]
*
- * You can hit the brakes on a running `PeriodicalUpdater` by calling
+ * You can hit the brakes on a running [[Ajax.PeriodicalUpdater]] by calling
* [[Ajax.PeriodicalUpdater#stop]]. If you wish to re-enable it later, call
* [[Ajax.PeriodicalUpdater#start]].
*
@@ -55,7 +56,155 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
* - options (Object): Configuration for the request. See the
* [[Ajax section]] for more information.
*
- * Creates a new `Ajax.PeriodicalUpdater`.
+ * Creates a new [[Ajax.PeriodicalUpdater]].
+ *
+ * Periodically performs an AJAX request and updates a container's contents
+ * based on the response text. Offers a mechanism for "decay," which lets it
+ * trigger at widening intervals while the response is unchanged.
+ *
+ * This object addresses the common need of periodical update, which is used
+ * by all sorts of "polling" mechanisms (e.g. in an online chatroom or an
+ * online mail client).
+ *
+ * The basic idea is to run a regular [[Ajax.Updater]] at
+ * regular intervals, monitoring changes in the response text if the `decay`
+ * option (see below) is active.
+ *
+ * ##### Additional options
+ *
+ * [[Ajax.PeriodicalUpdater]] features all the common options and callbacks
+ * (see the [[Ajax section]] for more information), plus those added by
+ * [[Ajax.Updater]]. It also provides two new options that deal with the
+ * original period, and its decay rate (how Rocket Scientist does that make
+ * us sound, uh?!).
+ *
+ * <table>
+ * <thead>
+ * <tr>
+ * <th>Option</th>
+ * <th>Default</th>
+ * <th>Description</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <th><code>frequency</code></th>
+ * <td><code>2</code></td>
+ * <td>Okay, this is not a frequency (e.g 0.5Hz), but a period (i.e. a number of seconds).
+ * Don't kill me, I didn't write this one! This is the minimum interval at which AJAX
+ * requests are made. You don't want to make it too short (otherwise you may very well
+ * end up with multiple requests in parallel, if they take longer to process and return),
+ * but you technically can provide a number below one, e.g. 0.75 second.</td>
+ * </tr>
+ * <tr>
+ * <th><code>decay</code></th>
+ * <td>1</td>
+ * <td>This controls the rate at which the request interval grows when the response is
+ * unchanged. It is used as a multiplier on the current period (which starts at the original
+ * value of the <code>frequency</code> parameter). Every time a request returns an unchanged
+ * response text, the current period is multiplied by the decay. Therefore, the default
+ * value means regular requests (no change of interval). Values higher than one will
+ * yield growing intervals. Values below one are dangerous: the longer the response text
+ * stays the same, the more often you'll check, until the interval is so short your browser
+ * is left with no other choice than suicide. Note that, as soon as the response text
+ * <em>does</em> change, the current period resets to the original one.</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * To better understand decay, here is a small sequence of calls from the
+ * following example:
+ *
+ * new Ajax.PeriodicalUpdater('items', '/items', {
+ * method: 'get', frequency: 3, decay: 2
+ * });
+ *
+ * <table id="decayTable">
+ * <thead>
+ * <tr>
+ * <th>Call#</th>
+ * <th>When?</th>
+ * <th>Decay before</th>
+ * <th>Response changed?</th>
+ * <th>Decay after</th>
+ * <th>Next period</th>
+ * <th>Comments</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>1</td>
+ * <td>00:00</td>
+ * <td>2</td>
+ * <td>n/a</td>
+ * <td>1</td>
+ * <td>3</td>
+ * <td>Response is deemed changed, since there is no prior response to compare to!</td>
+ * </tr>
+ * <tr>
+ * <td>2</td>
+ * <td>00:03</td>
+ * <td>1</td>
+ * <td>yes</td>
+ * <td>1</td>
+ * <td>3</td>
+ * <td>Response did change again: we "reset" to 1, which was already the decay.</td>
+ * </tr>
+ * <tr>
+ * <td>3</td>
+ * <td>00:06</td>
+ * <td>1</td>
+ * <td>no</td>
+ * <td>2</td>
+ * <td>6</td>
+ * <td>Response didn't change: decay augments by the <code>decay</code> option factor:
+ * we're waiting longer now&#8230;</td>
+ * </tr>
+ * <tr>
+ * <td>4</td>
+ * <td>00:12</td>
+ * <td>2</td>
+ * <td>no</td>
+ * <td>4</td>
+ * <td>12</td>
+ * <td>Still no change, doubling again.</td>
+ * </tr>
+ * <tr>
+ * <td>5</td>
+ * <td>00:24</td>
+ * <td>4</td>
+ * <td>no</td>
+ * <td>8</td>
+ * <td>24</td>
+ * <td>Jesus, is this thing going to change or what?</td>
+ * </tr>
+ * <tr>
+ * <td>6</td>
+ * <td>00:48</td>
+ * <td>8</td>
+ * <td>yes</td>
+ * <td>1</td>
+ * <td>3</td>
+ * <td>Ah, finally! Resetting decay to 1, and therefore using the original period.</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * ##### Disabling and re-enabling a [[Ajax.PeriodicalUpdater]]
+ *
+ * You can pull the brake on a running [[Ajax.PeriodicalUpdater]] by simply
+ * calling its `stop` method. If you wish to re-enable it later, just call
+ * its `start` method. Both take no argument.
+ *
+ * ##### Beware! Not a specialization!
+ *
+ * [[Ajax.PeriodicalUpdater]] is not a specialization of [[Ajax.Updater]],
+ * despite its name. When using it, do not expect to be able to use methods
+ * normally provided by [[Ajax.Request]] and "inherited" by [[Ajax.Updater]],
+ * such as `evalJSON` or `getHeader`. Also the `onComplete` callback is
+ * hijacked to be used for update management, so if you wish to be notified
+ * of every successful request, use `onSuccess` instead (beware: it will get
+ * called *before* the update is performed).
**/
initialize: function($super, container, url, options) {
$super(options);
View
@@ -3,9 +3,92 @@
*
* Initiates and processes an Ajax request.
*
- * `Ajax.Request` is a general-purpose class for making HTTP requests.
+ * [[Ajax.Request]] is a general-purpose class for making HTTP requests which
+ * handles the life-cycle of the request, handles the boilerplate, and lets
+ * you plug in callback functions for your custom needs.
*
- * <h5>Automatic JavaScript response evaluation</h5>
+ * In the optional `options` hash, you usually provide an `onComplete` and/or
+ * `onSuccess` callback, unless you're in the edge case where you're getting a
+ * JavaScript-typed response, that will automatically be `eval`'d.
+ *
+ * For a full list of common options and callbacks, see "Ajax options" heading
+ * of the [[Ajax section]].
+ *
+ * ##### A basic example
+ *
+ * new Ajax.Request('/your/url', {
+ * onSuccess: function(response) {
+ * // Handle the response content...
+ * }
+ * });
+ *
+ * ##### Request life-cycle
+ *
+ * Underneath our nice requester objects lies, of course, `XMLHttpRequest`. The
+ * defined life-cycle is as follows:
+ *
+ * 1. Created
+ * 2. Initialized
+ * 3. Request sent
+ * 4. Response being received (can occur many times, as packets come in)
+ * 5. Response received, request complete
+ *
+ * As you can see under the "Ajax options" heading of the [[Ajax section]],
+ * Prototype's AJAX objects define a whole slew of callbacks, which are
+ * triggered in the following order:
+ *
+ * 1. `onCreate` (this is actually a callback reserved to [[Ajax.Responders]])
+ * 2. `onUninitialized` (maps on Created)
+ * 3. `onLoading` (maps on Initialized)
+ * 4. `onLoaded` (maps on Request sent)
+ * 5. `onInteractive` (maps on Response being received)
+ * 6. `on`*XYZ* (numerical response status code), onSuccess or onFailure (see below)
+ * 7. `onComplete`
+ *
+ * The two last steps both map on *Response received*, in that order. If a
+ * status-specific callback is defined, it gets invoked. Otherwise, if
+ * `onSuccess` is defined and the response is deemed a success (see below), it
+ * is invoked. Otherwise, if `onFailure` is defined and the response is *not*
+ * deemed a sucess, it is invoked. Only after that potential first callback is
+ * `onComplete` called.
+ *
+ * ##### A note on portability
+ *
+ * Depending on how your browser implements `XMLHttpRequest`, one or more
+ * callbacks may never be invoked. In particular, `onLoaded` and
+ * `onInteractive` are not a 100% safe bet so far. However, the global
+ * `onCreate`, `onUninitialized` and the two final steps are very much
+ * guaranteed.
+ *
+ * ##### `onSuccess` and `onFailure`, the under-used callbacks
+ *
+ * Way too many people use [[Ajax.Request]] in a similar manner to raw XHR,
+ * defining only an `onComplete` callback even when they're only interested in
+ * "successful" responses, thereby testing it by hand:
+ *
+ * // This is too bad, there's better!
+ * new Ajax.Request('/your/url', {
+ * onComplete: function(response) {
+ * if (200 == response.status)
+ * // yada yada yada
+ * }
+ * });
+ *
+ * First, as described below, you could use better "success" detection: success
+ * is generally defined, HTTP-wise, as either no response status or a "2xy"
+ * response status (e.g., 201 is a success, too). See the example below.
+ *
+ * Second, you could dispense with status testing altogether! Prototype adds
+ * callbacks specific to success and failure, which we listed above. Here's
+ * what you could do if you're only interested in success, for instance:
+ *
+ * new Ajax.Request('/your/url', {
+ * onSuccess: function(response) {
+ * // yada yada yada
+ * }
+ * });
+ *
+ * ##### Automatic JavaScript response evaluation
*
* If an Ajax request follows the _same-origin policy_ **and** its response
* has a JavaScript-related `Content-type`, the content of the `responseText`
@@ -28,20 +111,20 @@
*
* The MIME-type string is examined in a case-insensitive manner.
*
- * <h5>Methods you may find useful</h5>
+ * ##### Methods you may find useful
*
- * Instances of the `Request` object provide several methods that can come in
- * handy in your callback functions, especially once the request is complete.
+ * Instances of the [[Ajax.Request]] object provide several methods that come
+ * in handy in your callback functions, especially once the request is complete.
*
- * <h5>Is the response a successful one?</h5>
+ * ###### Is the response a successful one?
*
* The [[Ajax.Request#success]] method examines the XHR object's `status`
* property and follows general HTTP guidelines: unknown status is deemed
* successful, as is the whole `2xy` status code family. It's a generally
* better way of testing your response than the usual
* `200 == transport.status`.
*
- * <h5>Getting HTTP response headers</h5>
+ * ###### Getting HTTP response headers
*
* While you can obtain response headers from the XHR object using its
* `getResponseHeader` method, this makes for verbose code, and several
@@ -58,14 +141,14 @@
* }
* });
*
- * <h5>Evaluating JSON headers</h5>
+ * ##### Evaluating JSON headers
*
* Some backends will return JSON not as response text, but in the `X-JSON`
* header. In this case, you don't even need to evaluate the returned JSON
* yourself, as Prototype automatically does so. It passes the result as the
* `headerJSON` property of the [[Ajax.Response]] object. Note that if there
- * is no such header &mdash; or its contents are invalid &mdash; `headerJSON` will be set
- * to `null`.
+ * is no such header &mdash; or its contents are invalid &mdash; `headerJSON`
+ * will be set to `null`.
*
* new Ajax.Request('/your/url', {
* onSuccess: function(transport) {
Oops, something went wrong.

1 comment on commit c9a9d1c

Contributor

arthurschreiber commented on c9a9d1c Mar 8, 2010

Wow, this is very nice! :)

Please sign in to comment.