|
1 /* |
|
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved. |
|
3 Code licensed under the BSD License: |
|
4 http://developer.yahoo.net/yui/license.txt |
|
5 version: 3.0.0 |
|
6 build: 1549 |
|
7 */ |
|
8 YUI.add('io-xdr', function(Y) { |
|
9 |
|
10 /** |
|
11 * Extends the IO base class to provide an alternate, Flash transport, for making |
|
12 * cross-domain requests. |
|
13 * @module io |
|
14 * @submodule io-xdr |
|
15 */ |
|
16 |
|
17 /** |
|
18 * @event io:xdrReady |
|
19 * @description This event is fired by YUI.io when the specified transport is |
|
20 * ready for use. |
|
21 * @type Event Custom |
|
22 */ |
|
23 var E_XDR_READY = 'io:xdrReady', |
|
24 |
|
25 |
|
26 /** |
|
27 * @description Object that stores callback handlers for cross-domain requests |
|
28 * when using Flash as the transport. |
|
29 * |
|
30 * @property _fn |
|
31 * @private |
|
32 * @static |
|
33 * @type object |
|
34 */ |
|
35 _fn = {}, |
|
36 |
|
37 /** |
|
38 * @description Map of transaction state used when XDomainRequest is the |
|
39 * XDR transport. |
|
40 * |
|
41 * @property _rS |
|
42 * @private |
|
43 * @static |
|
44 * @type object |
|
45 */ |
|
46 _rS = {}; |
|
47 |
|
48 /** |
|
49 * @description Method that creates the Flash transport swf. |
|
50 * |
|
51 * @method _swf |
|
52 * @private |
|
53 * @static |
|
54 * @param {string} uri - location of io.swf. |
|
55 * @param {string} yid - YUI instance id. |
|
56 * @return void |
|
57 */ |
|
58 function _swf(uri, yid) { |
|
59 var o = '<object id="yuiIoSwf" type="application/x-shockwave-flash" data="' + |
|
60 uri + '" width="0" height="0">' + |
|
61 '<param name="movie" value="' + uri + '">' + |
|
62 '<param name="FlashVars" value="yid=' + yid + '">' + |
|
63 '<param name="allowScriptAccess" value="always">' + |
|
64 '</object>', |
|
65 c = document.createElement('div'); |
|
66 |
|
67 document.body.appendChild(c); |
|
68 c.innerHTML = o; |
|
69 } |
|
70 |
|
71 /** |
|
72 * @description Sets event handlers for XDomainRequest transactions. |
|
73 * |
|
74 * @method _xdr |
|
75 * @private |
|
76 * @static |
|
77 * @param {object} o - Transaction object generated by _create() in io-base. |
|
78 * @param {object} c - configuration object for the transaction. |
|
79 * @return void |
|
80 */ |
|
81 function _xdr(o, c) { |
|
82 o.c.onprogress = function() { _rS[o.id] = 3; } |
|
83 o.c.onload = function() { |
|
84 _rS[o.id] = 4; |
|
85 Y.io.xdrResponse(o, c, 'success'); |
|
86 }; |
|
87 o.c.onerror = function() { |
|
88 _rS[o.id] = 4; |
|
89 Y.io.xdrResponse(o, c, 'failure'); |
|
90 }; |
|
91 if (c.timeout) { |
|
92 o.c.ontimeout = function() { |
|
93 _rS[o.id] = 4; |
|
94 Y.io.xdrResponse(o, c, 'timeout'); |
|
95 }; |
|
96 o.c.timeout = c.timeout; |
|
97 } |
|
98 } |
|
99 |
|
100 /** |
|
101 * @description Creates a response object for XDR transactions, for success |
|
102 * and failure cases. |
|
103 * |
|
104 * @method _data |
|
105 * @private |
|
106 * @static |
|
107 * @param {object} o - Transaction object generated by _create() in io-base. |
|
108 * @param {boolean} isFlash - True if Flash was used as the transport. |
|
109 * @param {boolean} isXML - True if the response data are XML. |
|
110 * |
|
111 * @return object |
|
112 */ |
|
113 function _data(o, isFlash, isXML) { |
|
114 var text, xml; |
|
115 |
|
116 if (!o.status) { |
|
117 text = isFlash ? decodeURI(o.c.responseText) : o.c.responseText; |
|
118 xml = isXML ? Y.DataType.XML.parse(text) : null; |
|
119 |
|
120 return { id: o.id, c: { responseText: text, responseXML: xml } }; |
|
121 } |
|
122 else { |
|
123 return { id: o.id, status: o.status }; |
|
124 } |
|
125 |
|
126 } |
|
127 |
|
128 /** |
|
129 * @description Method for intiating an XDR transaction abort. |
|
130 * |
|
131 * @method _abort |
|
132 * @private |
|
133 * @static |
|
134 * @param {object} o - Transaction object generated by _create() in io-base. |
|
135 * @param {object} c - configuration object for the transaction. |
|
136 */ |
|
137 function _abort(o, c) { |
|
138 return c.xdr.use === 'flash' ? o.c.abort(o.id, c) : o.c.abort(); |
|
139 } |
|
140 |
|
141 /** |
|
142 * @description Method for determining if an XDR transaction has completed |
|
143 * and all data are received. |
|
144 * |
|
145 * @method _isInProgress. |
|
146 * @private |
|
147 * @static |
|
148 * @param {object} o - Transaction object generated by _create() in io-base. |
|
149 * @param {object} c - configuration object for the transaction. |
|
150 */ |
|
151 function _isInProgress(o, t) { |
|
152 return (t === 'flash' && o.c) ? o.c.isInProgress(o.id) : _rS[o.id] !== 4; |
|
153 } |
|
154 |
|
155 Y.mix(Y.io, { |
|
156 |
|
157 /** |
|
158 * @description Map of io transports. |
|
159 * |
|
160 * @property _transport |
|
161 * @private |
|
162 * @static |
|
163 * @type object |
|
164 */ |
|
165 _transport: {}, |
|
166 |
|
167 /** |
|
168 * @description Method for accessing the transport's interface for making a |
|
169 * cross-domain transaction. |
|
170 * |
|
171 * @method _xdr |
|
172 * @private |
|
173 * @static |
|
174 * @param {string} uri - qualified path to transaction resource. |
|
175 * @param {object} o - Transaction object generated by _create() in io-base. |
|
176 * @param {object} c - configuration object for the transaction. |
|
177 */ |
|
178 xdr: function(uri, o, c) { |
|
179 if (c.on && c.xdr.use === 'flash') { |
|
180 _fn[o.id] = { |
|
181 on: c.on, |
|
182 context: c.context, |
|
183 arguments: c.arguments |
|
184 }; |
|
185 // These nodes do not need to be serialized across Flash's |
|
186 // ExternalInterface. Doing so will result in exceptions. |
|
187 c.context = null; |
|
188 c.form = null; |
|
189 |
|
190 o.c.send(uri, c, o.id); |
|
191 } |
|
192 else if (window.XDomainRequest) { |
|
193 _xdr(o, c); |
|
194 o.c.open(c.method || 'GET', uri); |
|
195 o.c.send(c.data); |
|
196 } |
|
197 |
|
198 return { |
|
199 id: o.id, |
|
200 abort: function() { |
|
201 return o.c ? _abort(o, c) : false; |
|
202 }, |
|
203 isInProgress: function() { |
|
204 return o.c ? _isInProgress(o, c.xdr.use) : false; |
|
205 } |
|
206 } |
|
207 }, |
|
208 |
|
209 /** |
|
210 * @description Response controller for cross-domain requests when using the |
|
211 * Flash transport or IE8's XDomainRequest object. |
|
212 * |
|
213 * @method xdrResponse |
|
214 * @private |
|
215 * @static |
|
216 * @param {object} o - Transaction object generated by _create() in io-base. |
|
217 * @param {object} c - configuration object for the transaction. |
|
218 * @param {string} e - Event name |
|
219 * @return object |
|
220 */ |
|
221 xdrResponse: function(o, c, e) { |
|
222 var m, fn, |
|
223 isFlash = c.xdr.use === 'flash' ? true : false, |
|
224 isXML = c.xdr.dataType === 'xml' ? true : false; |
|
225 c.on = c.on || {}; |
|
226 |
|
227 if (isFlash) { |
|
228 m = _fn || {}; |
|
229 fn = m[o.id] ? m[o.id] : null; |
|
230 if (fn) { |
|
231 c.on = fn.on; |
|
232 c.context = fn.context; |
|
233 c.arguments = fn.arguments; |
|
234 } |
|
235 } |
|
236 if (e === ('abort' || 'timeout')) { |
|
237 o.status = e; |
|
238 } |
|
239 |
|
240 switch (e) { |
|
241 case 'start': |
|
242 Y.io.start(o.id, c); |
|
243 break; |
|
244 case 'success': |
|
245 Y.io.success(_data(o, isFlash, isXML), c); |
|
246 isFlash ? delete m[o.id] : delete _rS[o.id]; |
|
247 break; |
|
248 case 'timeout': |
|
249 case 'abort': |
|
250 case 'failure': |
|
251 Y.io.failure(_data(o, isFlash, isXML), c); |
|
252 isFlash ? delete m[o.id] : delete _rS[o.id]; |
|
253 break; |
|
254 } |
|
255 }, |
|
256 |
|
257 /** |
|
258 * @description Fires event "io:xdrReady" |
|
259 * |
|
260 * @method xdrReady |
|
261 * @private |
|
262 * @static |
|
263 * @param {number} id - transaction id |
|
264 * @param {object} c - configuration object for the transaction. |
|
265 * |
|
266 * @return void |
|
267 */ |
|
268 xdrReady: function(id) { |
|
269 Y.fire(E_XDR_READY, id); |
|
270 }, |
|
271 |
|
272 /** |
|
273 * @description Method to initialize the desired transport. |
|
274 * |
|
275 * @method transport |
|
276 * @public |
|
277 * @static |
|
278 * @param {object} o - object of transport configurations. |
|
279 * @return void |
|
280 */ |
|
281 transport: function(o) { |
|
282 var id = o.yid ? o.yid : Y.id; |
|
283 |
|
284 _swf(o.src, id); |
|
285 this._transport.flash = Y.config.doc.getElementById('yuiIoSwf'); |
|
286 } |
|
287 }); |
|
288 |
|
289 |
|
290 |
|
291 }, '3.0.0' ,{requires:['io-base','datatype-xml']}); |