OK, just a post to keep you all updated since I didn't get as much time as I
expected though I have progress, mind you.

Also, I recommend a good understanding of the internals of $.ajax to follow
everything.

First, let me start with some design decisions I came up with:

1) the fake XHR returned by $.ajax only emulates header related methods &
abort

The rational behind the decision is as follows:
- the onreadystatechange callback was already used by jQuery internally on
the old implementation, meaning that using it was pointless if not plain
wrong.
- same goes for open & send, it doesn't make sense for external code to use
them

On a sidenote, readyState could be emulated but I fail to see the point. I
*could* emulate onreadystatechange but is there really a use case for this?

Of course, the complete(), success() & error() methods are implemented. If
you do something like jQuery.ajax(options).complete(completeCallback); in
async=false mode, the completeCallback method WILL be called with correct
arguments even though the request already completed.

Each callback family handled "return false;" in callbacks, meaning no
further callbacks of that family will be called later on.

For backward compatibility, the complete, success & error callbacks provided
in the options object are also called (they are actually added to the list
of callbacks before issuing the request).

2) I added the notion of "transport" which is the actual implementation that
will send the request

ajaxSettings has two new properties:
- transportSelector, a function that will take an options object and
determine what transport type is more suited for the request,
- transportDefinitions which is a hashmap of transport definitions
(obviously).

Transport definitions contains two functions:
- filter which takes the options object & returns a new transport type if it
deems it more suited than itself
- factory which takes no argument & returns a new transport of the desired
type

The idea in having the filter function is:
- to set s.global as false if the transport cannot ensure completion
(cross-domain script / jsonp),
- to keep differentiating code as close to the implementation as possible. A
good example are scripts which wont be handled the same if they are cross
domain or not (first will use xhr, second will use a script tag). If
s.transportDefinitions[transportType] is not an object but a function, it is
considered a filter. Following previous example, transportSelector would
just return "script" no matter what, and the script transport definition
would look like this:
s.transportDefinitions["script"] = function (s) { return isCrossDomain(s) ?
"script-tag" : "xhr" }

Filters get called until a final transportType is found, then the
corresponding transport factory gets called.

By changing transportSelector & transportDefinitions, a user can completely

I also added some options into the ajax options object beside
transportSelector & transportDefinition:
- transport: which can be used to bypass transportSelector (filters called
until final type is found are not bypassed)
- transportDataType: it's the data type used to determine which transport to
use (in transportSelector), if not provided it's equivalent to dataType. The
idea came when I was refactoring and realized that it was no reason why you
couldn't ask for xml through jsonp. So you would have something like
$.ajax({ dataType: "xml", transportDataType: "jsonp", ...}) and the request
will be made through jsonp and the resulting json object will be parsed as
xml (I already implemented the logic). As a consequence dataFilter gets 3
arguments:
- the data,
- s.dataType,
- a function that permits to get/set the transportDataType (so that you can
make "casts" in your dataFilter).
- crossDomain: a boolean computed into the main $.ajax method to make life
of filters easier.

So far, I have:
- the logic in $.ajax (with xhr emulation & callbacks system),
- the factory system,
- a helper function to help create transports (in the end only 3 functions +
the filter will have to be provided to create a new transport),
- the interface for a transport (which is much easier to deal with than an
xhr).

I have yet to implement actual transports and start testing.

Also, generalizing the implementaton, global events, timeout, ifModified,
etc, are handled for all transports (now, given lack of headers, ifModified
may not have an effect with most transports but still).

The code hasn't exploded in size but I cannot estimate yet how bigger it
will get.

Now onto stuff I'd like to see in jQuery and am very tempted to add in the
process is ful-fledged support for CORS with the definition of
jQuery.support.crossDomainRequest (values false, "standard" or
"XDomainRequest" -- detection code can be found here:
http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/ --).
Using filters and the new s.crossDomain computed option, it should be very
easy to handle all situations (by throwing an exception or whatnot so that
client code could fallback on a proxy or something).

Feedbacks welcome is you see anything gross in there.

-- Julian

2009/11/15 Julian Aubourg <aubourg.jul...@gmail.com>

> I looked into your code and we basically have the same approach. I'll try &
> get the refactoring done by the middle of next week (like I said, I have
> social life getting in the way right now ;) ).
>
> 2009/11/15 Shade <get...@gmail.com>
>
> I've built two different JavaScript projects which implement a nearly
>> identical interface to the native XHR object, including updating
>> properties, etc, while hiding under the covers how the actual XHR
>> happens. One is flXHR (http://flxhr.flensed.com) which actually has a
>> jQuery plugin that adapts flXHR to be automatically selected and used
>> by jQuery when making $.ajax calls. It relies on the XHR registry
>> plugin of jQuery. Because flXHR exposes the identical interface to
>> native XHR, this makes it able to be used throughout $.ajax without
>> any changes to jquery itself.
>>
>> The other project isn't specifically jQuery related, but it's called
>> jXHR (http://mulletxhr.com).
>>
>> The reason I mention these two projects is that they seem to be doing
>> exactly what is being suggested with this mockXHR object. I use a
>> couple of tricks to make that happen, including emulating updating
>> properties. I'd be willing to collaborate on this solution and share
>> the tricks I used in my two projects.
>>
>> Let me know if this would of assistance. I definitely support trying
>> to revamp the way the $.ajax system works to give it more
>> extensibility.
>>
>> --Kyle
>>
>>
>>
>>
>> On Nov 13, 4:38 pm, Jason Persampieri <papp...@gmail.com> wrote:
>> > On Nov 13, 6:39 am, Scott Sauyet <scott.sau...@gmail.com> wrote:
>> >
>> >
>> >
>> >
>> >
>> > > On Thu, Nov 12, 2009 at 1:15 PM, John Resig <jere...@gmail.com>
>> wrote:
>> > > >> I think the one area that would be troublesome is in the properties
>> > > >> that xhr provides (like readyState, responseXML, etc.). I'm not
>> sure
>> > > >> how you'd build this mock XHR and keep those properties up to date.
>> >
>> > > On Thu, Nov 12, 2009 at 10:14 PM, Julian Aubourg
>> >
>> > > <aubourg.jul...@gmail.com> wrote:
>> > > > As an example of what I'm talking about with an real xhr as a base:
>> > > > - layer 0 is window.ActiveXObject ? new
>> ActiveXObject("Microsoft.XMLHTTP") :
>> > > > new XMLHttpRequest()
>> > > > - layer 1 is a standard compliant xhr implementation that delegates
>> to layer
>> > > > 0 while hiding browser incompatibilities. It listens to layer 0
>> through its
>> > > > onreadystatechange event handler and propagates the event by calling
>> its own
>> > > > onreadystatechange if available
>> >
>> > > I had briefly mentioned a similar idea in the other thread [1], but
>> > > was rather scared of the actual implementation.  I guess the question
>> > > is whether there are possible state changes to the underlying XHR
>> > > object that might affect the properties but that are not exposed
>> > > through the onreadystatechange handler.  I don't have nearly the
>> > > knowledge of XHR to answer this.  If there aren't any, I think this is
>> > > quite a good idea.
>> >
>> > >   -- Scott
>> >
>> > > [1]http://tinyurl.com/yl2lqjz#msg_1fa4cac00dbcedcf
>> >
>> > Well, then.  I had started working on something similar, but much
>> > simpler.  I had planned to intercept the return value of $.ajax and
>> > extend it with 'success' and 'error' functions.  Of course, I hadn't
>> > gotten to the point of actually testing this, so who knows if it would
>> > have worked.   Your solution sounds much more robust and forward
>> > thinking.  Very nice.
>> >
>> > _jason- Hide quoted text -
>> >
>> > - Show quoted text -
>>
>> --
>>
>> You received this message because you are subscribed to the Google Groups
>> "jQuery Development" group.
>> To post to this group, send email to jquery-...@googlegroups.com.
>> To unsubscribe from this group, send email to
>> jquery-dev+unsubscr...@googlegroups.com<jquery-dev%2bunsubscr...@googlegroups.com>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/jquery-dev?hl=.
>>
>>
>>
>

--

You received this message because you are subscribed to the Google Groups 
"jQuery Development" group.
To post to this group, send email to jquery-...@googlegroups.com.
To unsubscribe from this group, send email to 
jquery-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/jquery-dev?hl=.


Reply via email to