Add PDoc for most of Ajax section.
This commit is contained in:
parent
8c2af9bd66
commit
449e532f9a
109
src/ajax.js
109
src/ajax.js
|
@ -1,3 +1,112 @@
|
|||
/**
|
||||
* == Ajax ==
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Actual requests are made by creating instances of [[Ajax.Request]].
|
||||
*
|
||||
* <h4>Request headers</h4>
|
||||
*
|
||||
* 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`).
|
||||
* * `Accept` is set to `text/javascript, text/html, application/xml,
|
||||
* text/xml, * / *`
|
||||
* * `Content-type` is automatically determined based on the `contentType`
|
||||
* and `encoding` options.
|
||||
*
|
||||
* <h4>Ajax options</h4>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* * `asynchronous` ([[Boolean]]; default `true`): Determines whether
|
||||
* `XMLHttpRequest` is used asynchronously or not. Synchronous usage is
|
||||
* seriously discouraged — it halts all script execution for the duration of
|
||||
* the request _and_ blocks the browser UI.
|
||||
* * `contentType` ([[String]]; default `application/x-www-form-urlencoded`):
|
||||
* The `Content-type` header for your request. Change this header if you
|
||||
* want to send data in another format (like XML).
|
||||
* * `encoding` ([[String]]; default `UTF-8`): The encoding for the contents
|
||||
* of your request. It is best left as-is, but should weird encoding issues
|
||||
* arise, you may have to tweak this.
|
||||
* * `method` ([[String]]; default `post`): The HTTP method to use for the
|
||||
* request. The other common possibility is `get`. Abiding by Rails
|
||||
* conventions, Prototype also reacts to other HTTP verbs (such as `put` and
|
||||
* `delete`) by submitting via `post` and adding a extra `_method` parameter
|
||||
* with the originally-requested method.
|
||||
* * `parameters` ([[String]]): The parameters for the request, which will be
|
||||
* encoded into the URL for a `get` method, or into the request body for the
|
||||
* other methods. This can be provided either as a URL-encoded string, a
|
||||
* [[Hash]], or a plain [[Object]].
|
||||
* * `postBody` ([[String]]): Specific contents for the request body on a
|
||||
* `post` method. If it is not provided, the contents of the `parameters`
|
||||
* option will be used instead.
|
||||
* * `requestHeaders` ([[Object]]): A set of key-value pairs, with properties
|
||||
* representing header names.
|
||||
* * `evalJS` ([[Boolean]] | [[String]]; default `true`): Automatically `eval`s
|
||||
* the content of [[Ajax.Response#responseText]] and populates
|
||||
* [[Ajax.Response#responseJSON]] with it if the `Content-type` returned by
|
||||
* the server is set to `application/json`. If the request doesn't obey
|
||||
* same-origin policy, the content is sanitized before evaluation. If you
|
||||
* need to force evalutation, pass `'force'`. To prevent it altogether, pass
|
||||
* `false`.
|
||||
* * `sanitizeJSON` ([[Boolean]]; default is `false` for same-origin requests,
|
||||
* `true` otherwise): Sanitizes the contents of
|
||||
* [[Ajax.Response#responseText]] before evaluating it.
|
||||
*
|
||||
* <h4>Common callbacks</h4>
|
||||
*
|
||||
* When used on individual instances, all callbacks (except `onException`) are
|
||||
* invoked with two parameters: the `XMLHttpRequest` 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
|
||||
* are mutually exclusive, see [[Ajax.Request]].
|
||||
*
|
||||
* * `onCreate`: Triggered when the [[Ajax.Request]] object is initialized.
|
||||
* This is _after_ the parameters and the URL have been processed, but
|
||||
* _before_ opening the connection via the XHR object.
|
||||
* * `onUninitialized` (*Not guaranteed*): Invoked just after the XHR object
|
||||
* is created.
|
||||
* * `onLoading` (*Not guaranteed*): Triggered when the underlying XHR object
|
||||
* is being setup, and its connection opened.
|
||||
* * `onLoaded` (*Not guaranteed*): Triggered once the underlying XHR object
|
||||
* is setup, the connection is open, and it is ready to send its actual
|
||||
* request.
|
||||
* * `onInteractive` (*Not guaranteed*): Triggered whenever the requester
|
||||
* receives a part of the response (but not the final part), should it
|
||||
* be sent in several packets.
|
||||
* * `onSuccess`: Invoked when a request completes and its status code is
|
||||
* `undefined` or belongs in the `2xy` family. This is skipped if a
|
||||
* code-specific callback is defined (e.g., `on200`), and happens _before_
|
||||
* `onComplete`.
|
||||
* * `onFailure`: Invoked when a request completes and its status code exists
|
||||
* but _is not_ in the `2xy` family. This is skipped if a code-specific
|
||||
* callback is defined (e.g. `on403`), and happens _before_ `onComplete`.
|
||||
* * `onXYZ` (_with `XYZ` representing any HTTP status code_): Invoked just
|
||||
* after the response is complete _if_ the status code is the exact code
|
||||
* used in the callback name. _Prevents_ execution of `onSuccess` and
|
||||
* `onFailure`. Happens _before_ `onComplete`.
|
||||
* * `onException`: Triggered whenever an XHR error arises. Has a custom
|
||||
* signature: the first argument is the requester (i.e. an [[Ajax.Request]]
|
||||
* instance), and the second is the exception object.
|
||||
* * `onComplete`: Triggered at the _very end_ of a request's life-cycle, after
|
||||
* the request completes, status-specific callbacks are called, and possible
|
||||
* automatic behaviors are processed. Guaranteed to run regardless of what
|
||||
* happened during the request.
|
||||
*
|
||||
**/
|
||||
|
||||
//= require "ajax/ajax"
|
||||
//= require "ajax/responders"
|
||||
//= require "ajax/base"
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/** section: Ajax
|
||||
* Ajax
|
||||
**/
|
||||
|
||||
var Ajax = {
|
||||
getTransport: function() {
|
||||
return Try.these(
|
||||
|
@ -7,5 +11,11 @@ var Ajax = {
|
|||
) || false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.activeRequestCount -> Number
|
||||
*
|
||||
* Represents the number of active XHR requests triggered through
|
||||
* [[Ajax.Request]], [[Ajax.Updater]], or [[Ajax.PeriodicalUpdater]].
|
||||
**/
|
||||
activeRequestCount: 0
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Abstract class; does not need documentation.
|
||||
Ajax.Base = Class.create({
|
||||
initialize: function(options) {
|
||||
this.options = {
|
||||
|
|
|
@ -1,6 +1,92 @@
|
|||
/** section: Ajax
|
||||
* class Ajax.Request
|
||||
*
|
||||
* Initiates and processes an Ajax request.
|
||||
*
|
||||
* `Ajax.Request` is a general-purpose class for making HTTP requests.
|
||||
*
|
||||
* <h4>Automatic JavaScript response evaluation</h4>
|
||||
*
|
||||
* If an Ajax request follows the _same-origin policy_ **and** its response
|
||||
* has a JavaScript-related `Content-type`, the content of the `responseText`
|
||||
* property will automatically be passed to `eval`.
|
||||
*
|
||||
* In other words: you don't even need to provide a callback to leverage
|
||||
* pure-JavaScript AJAX responses. This is the convention that drives Rails's
|
||||
* RJS.
|
||||
*
|
||||
* The list of JavaScript-related MIME-types handled by Prototype is:
|
||||
*
|
||||
* * `application/ecmascript`
|
||||
* * `application/javascript`
|
||||
* * `application/x-ecmascript`
|
||||
* * `application/x-javascript`
|
||||
* * `text/ecmascript`
|
||||
* * `text/javascript`
|
||||
* * `text/x-ecmascript`
|
||||
* * `text/x-javascript`
|
||||
*
|
||||
* The MIME-type string is examined in a case-insensitive manner.
|
||||
*
|
||||
* <h4>Methods you may find useful</h4>
|
||||
*
|
||||
* Instances of the `Request` object provide several methods that can come in
|
||||
* handy in your callback functions, especially once the request is complete.
|
||||
*
|
||||
* <h5>Is the response a successful one?</h5>
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
* While you can obtain response headers from the XHR object using its
|
||||
* `getResponseHeader` method, this makes for verbose code, and several
|
||||
* implementations raise an exception when the header is not found. To make
|
||||
* this easier, you can use the [[Ajax.Response#getHeader]] method, which
|
||||
* delegates to the longer version and returns `null` if an exception occurs:
|
||||
*
|
||||
* new Ajax.Request('/your/url', {
|
||||
* onSuccess: function(response) {
|
||||
* // Note how we brace against null values
|
||||
* if ((response.getHeader('Server') || '').match(/Apache/))
|
||||
* ++gApacheCount;
|
||||
* // Remainder of the code
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* <h5>Evaluating JSON headers</h5>
|
||||
*
|
||||
* 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 — or its contents are invalid — `headerJSON` will be set
|
||||
* to `null`.
|
||||
*
|
||||
* new Ajax.Request('/your/url', {
|
||||
* onSuccess: function(transport) {
|
||||
* transport.headerJSON
|
||||
* }
|
||||
* });
|
||||
**/
|
||||
Ajax.Request = Class.create(Ajax.Base, {
|
||||
_complete: false,
|
||||
|
||||
/**
|
||||
* new Ajax.Request(url[, options])
|
||||
* - url (String): The URL to fetch. When the _same-origin_ policy is in
|
||||
* effect (as it is in most cases), `url` **must** be a relative URL or an
|
||||
* absolute URL that starts with a slash (i.e., it must not begin with
|
||||
* `http`).
|
||||
* - options (Object): Configuration for the request. See the
|
||||
* [[Ajax section]] for more information.
|
||||
*
|
||||
* Creates a new `Ajax.Request`.
|
||||
**/
|
||||
initialize: function($super, url, options) {
|
||||
$super(options);
|
||||
this.transport = Ajax.getTransport();
|
||||
|
@ -95,6 +181,11 @@ Ajax.Request = Class.create(Ajax.Base, {
|
|||
this.transport.setRequestHeader(name, headers[name]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Request.success() -> Boolean
|
||||
*
|
||||
* Tests whether the request was successful.
|
||||
**/
|
||||
success: function() {
|
||||
var status = this.getStatus();
|
||||
return !status || (status >= 200 && status < 300);
|
||||
|
@ -148,10 +239,18 @@ Ajax.Request = Class.create(Ajax.Base, {
|
|||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Request.getHeader(name) -> String | null
|
||||
* - name (String): The name of an HTTP header that may have been part of
|
||||
* the response.
|
||||
*
|
||||
* Returns the value of the given response header, or `null` if that header
|
||||
* was not found.
|
||||
**/
|
||||
getHeader: function(name) {
|
||||
try {
|
||||
return this.transport.getResponseHeader(name) || null;
|
||||
} catch (e) { return null }
|
||||
} catch (e) { return null; }
|
||||
},
|
||||
|
||||
evalResponse: function() {
|
||||
|
|
|
@ -1,3 +1,71 @@
|
|||
/** section: Ajax
|
||||
* Ajax.Responders
|
||||
*
|
||||
* A repository of global listeners notified about every step of
|
||||
* Prototype-based Ajax requests.
|
||||
*
|
||||
* Sometimes, you need to provide generic behaviors over all Ajax operations
|
||||
* happening on the page (through [[Ajax.Request]], [[Ajax.Updater]] or
|
||||
* [[Ajax.PeriodicalUpdater]]).
|
||||
*
|
||||
* For instance, you might want to automatically show an indicator when an
|
||||
* Ajax request is ongoing, and hide it when none are. You may well want to
|
||||
* factor out exception handling as well, logging those somewhere on the page
|
||||
* in a custom fashion. The possibilities are myriad.
|
||||
*
|
||||
* To achieve this, Prototype provides `Ajax.Responders`, which lets you
|
||||
* register (and, if you wish, unregister later) _responders_, which are
|
||||
* objects with specially-named methods. These names come from a set of
|
||||
* general callbacks corresponding to different points in time (or outcomes)
|
||||
* of an Ajax request's life cycle.
|
||||
*
|
||||
* For instance, Prototype automatically registers a responder that maintains
|
||||
* a nifty variable: [[Ajax.activeRequestCount]]. This represents, at a given
|
||||
* time, the number of currently active Ajax requests — by monitoring their
|
||||
* `onCreate` and `onComplete` events. The code for this is fairly simple:
|
||||
*
|
||||
* Ajax.Responders.register({
|
||||
* onCreate: function() {
|
||||
* Ajax.activeRequestCount++;
|
||||
* },
|
||||
* onComplete: function() {
|
||||
* Ajax.activeRequestCount--;
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* <h4>Responder callbacks</h4>
|
||||
*
|
||||
* The callbacks for responders are similar to the callbacks described in
|
||||
* the [[Ajax section]], but take a different signature. They're invoked with
|
||||
* three parameters: the requester object (i.e., the corresponding "instance"
|
||||
* of [[Ajax.Request]]), the `XMLHttpRequest` object, and the result of
|
||||
* evaluating the `X-JSON` response header, if any (can be `null`). They also
|
||||
* execute in the context of the responder, bound to the `this` reference.
|
||||
*
|
||||
* * `onCreate`: Triggered whenever a requester object from the `Ajax`
|
||||
* namespace is created, after its parameters are adjusted and before its
|
||||
* XHR connection is opened. This takes *two* arguments: the requester
|
||||
* object and the underlying XHR object.
|
||||
* * `onUninitialized` (*Not guaranteed*): Invoked just after the XHR object
|
||||
* is created.
|
||||
* * `onLoading` (*Not guaranteed*): Triggered when the underlying XHR object
|
||||
* is being setup, and its connection opened.
|
||||
* * `onLoaded` (*Not guaranteed*): Triggered once the underlying XHR object
|
||||
* is setup, the connection is open, and it is ready to send its actual
|
||||
* request.
|
||||
* * `onInteractive` (*Not guaranteed*): Triggered whenever the requester
|
||||
* receives a part of the response (but not the final part), should it
|
||||
* be sent in several packets.
|
||||
* * `onException`: Triggered whenever an XHR error arises. Has a custom
|
||||
* signature: the first argument is the requester (i.e. an [[Ajax.Request]]
|
||||
* instance), and the second is the exception object.
|
||||
* * `onComplete`: Triggered at the _very end_ of a request's life-cycle, after
|
||||
* the request completes, status-specific callbacks are called, and possible
|
||||
* automatic behaviors are processed. Guaranteed to run regardless of what
|
||||
* happened during the request.
|
||||
*
|
||||
**/
|
||||
|
||||
Ajax.Responders = {
|
||||
responders: [],
|
||||
|
||||
|
@ -5,11 +73,30 @@ Ajax.Responders = {
|
|||
this.responders._each(iterator);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Responders.register(responder) -> undefined
|
||||
* - responder (Object): A list of functions with keys corresponding to the
|
||||
* names of possible callbacks.
|
||||
*
|
||||
* Add a group of responders to all Ajax requests.
|
||||
**/
|
||||
register: function(responder) {
|
||||
if (!this.include(responder))
|
||||
this.responders.push(responder);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Responders.unregister(responder) -> undefined
|
||||
* - responder (Object): A list of functions with keys corresponding to the
|
||||
* names of possible callbacks.
|
||||
*
|
||||
* Remove a previously-added group of responders.
|
||||
*
|
||||
* As always, unregistering something requires you to use the very same
|
||||
* object you used at registration. If you plan to use `unregister`, be sure
|
||||
* to assign your responder to a _variable_ before passing it into
|
||||
* [[Ajax.Responders#register]] — don't pass it an object literal.
|
||||
**/
|
||||
unregister: function(responder) {
|
||||
this.responders = this.responders.without(responder);
|
||||
},
|
||||
|
|
|
@ -1,4 +1,64 @@
|
|||
/** section: Ajax
|
||||
* class Ajax.Response
|
||||
*
|
||||
* A wrapper class around `XmlHttpRequest` for dealing with HTTP responses
|
||||
* of Ajax requests.
|
||||
*
|
||||
* An instance of `Ajax.Response` is passed as the first argument of all Ajax
|
||||
* requests' callbacks. You _will not_ need to create instances of
|
||||
* `Ajax.Response` yourself.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#readyState -> Number
|
||||
*
|
||||
* The request’s current state.
|
||||
*
|
||||
* `0` corresponds to `"Uninitialized"`, `1` to `"Loading"`, `2` to
|
||||
* `"Loaded"`, `3` to `"Interactive"`, and `4` to `"Complete"`.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#responseText -> String
|
||||
*
|
||||
* The text body of the response.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#responseXML -> document | null
|
||||
*
|
||||
* The XML body of the response if the `Content-type` of the request is set
|
||||
* to `application/xml`; `null` otherwise.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#responseJSON -> Object | Array | null
|
||||
*
|
||||
* The JSON body of the response if the `Content-type` of the request is set
|
||||
* to `application/json`; `null` otherwise.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#headerJSON -> Object | Array | null
|
||||
*
|
||||
* Auto-evaluated content of the `X-JSON` header if present; `null` otherwise.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#request -> Ajax.Request | Ajax.Updater
|
||||
*
|
||||
* The request object itself (an instance of [[Ajax.Request]] or
|
||||
* [[Ajax.Updater]]).
|
||||
**/
|
||||
|
||||
/**
|
||||
* Ajax.Response#transport -> XmlHttpRequest
|
||||
*
|
||||
* The native `XmlHttpRequest` object itself.
|
||||
**/
|
||||
|
||||
Ajax.Response = Class.create({
|
||||
// Don't document the constructor; should never be manually instantiated.
|
||||
initialize: function(request){
|
||||
this.request = request;
|
||||
var transport = this.transport = request.transport,
|
||||
|
@ -18,7 +78,18 @@ Ajax.Response = Class.create({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Response#status -> Number
|
||||
*
|
||||
* The HTTP status code sent by the server.
|
||||
**/
|
||||
status: 0,
|
||||
|
||||
/**
|
||||
* Ajax.Response#statusText -> String
|
||||
*
|
||||
* The HTTP status text sent by the server.
|
||||
**/
|
||||
statusText: '',
|
||||
|
||||
getStatus: Ajax.Request.prototype.getStatus,
|
||||
|
@ -29,18 +100,44 @@ Ajax.Response = Class.create({
|
|||
} catch (e) { return '' }
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Response#getHeader(name) -> String | null
|
||||
*
|
||||
* See [[Ajax.Request#getHeader]].
|
||||
**/
|
||||
getHeader: Ajax.Request.prototype.getHeader,
|
||||
|
||||
/**
|
||||
* Ajax.Response#getAllHeaders() -> String | null
|
||||
*
|
||||
* Returns a string containing all headers separated by line breaks. _Does
|
||||
* not__ throw errors if no headers are present the way its native
|
||||
* counterpart does.
|
||||
**/
|
||||
getAllHeaders: function() {
|
||||
try {
|
||||
return this.getAllResponseHeaders();
|
||||
} catch (e) { return null }
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Response.getResponseHeader(name) -> String
|
||||
*
|
||||
* Returns the value of the requested header if present; throws an error
|
||||
* otherwise. This is just a wrapper around the `XmlHttpRequest` method of
|
||||
* the same name.
|
||||
**/
|
||||
getResponseHeader: function(name) {
|
||||
return this.transport.getResponseHeader(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajax.Response.getAllResponseHeaders() -> String
|
||||
*
|
||||
* Returns a string containing all headers separated by line breaks; throws
|
||||
* an error if no headers exist. This is just a wrapper around the
|
||||
* `XmlHttpRequest` method of the same name.
|
||||
**/
|
||||
getAllResponseHeaders: function() {
|
||||
return this.transport.getAllResponseHeaders();
|
||||
},
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
/** section: Ajax
|
||||
* class Ajax.Updater < Ajax.Request
|
||||
*
|
||||
* A class that performs an Ajax request and updates a container’s contents
|
||||
* with the contents of the response.
|
||||
*
|
||||
* `Ajax.Updater` is a subclass of [[Ajax.Request]] built for a common
|
||||
* use-case.
|
||||
*
|
||||
* <h4>Example</h4>
|
||||
*
|
||||
* new Ajax.Updater('items', '/items', {
|
||||
* parameters: { text: $F('text') }
|
||||
* });
|
||||
*
|
||||
* This example will make a request to the URL `/items` (with the given
|
||||
* parameters); it will then replace the contents of the element with the ID
|
||||
* of `items` with whatever response it receives.
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Ajax.Updater = Class.create(Ajax.Request, {
|
||||
initialize: function($super, container, url, options) {
|
||||
this.container = {
|
||||
|
|
Loading…
Reference in New Issue