]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/io/io-upload-iframe.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / io / io-upload-iframe.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('io-upload-iframe', function(Y) {
9
10    /**
11     * Extends the IO base class to enable file uploads, with HTML forms,
12     * using an iframe as the transport medium.
13     * @module io
14     * @submodule io-upload-iframe
15     */
16
17     var w = Y.config.win,
18         d = Y.config.doc,
19         _std = (d.documentMode && d.documentMode >= 8),
20                 _d = decodeURIComponent;
21    /**
22     * @description Parses the POST data object and creates hidden form elements
23     * for each key-value, and appends them to the HTML form object.
24     * @method appendData
25     * @private
26     * @static
27     * @param {object} f HTML form object.
28     * @param {string} s The key-value POST data.
29     * @return {array} e Array of created fields.
30     */
31     function _addData(f, s) {
32         var o = [],
33             m = s.split('='),
34             i, l;
35
36         for (i = 0, l = m.length - 1; i < l; i++) {
37             o[i] = d.createElement('input');
38             o[i].type = 'hidden';
39             o[i].name = _d(m[i].substring(m[i].lastIndexOf('&') + 1));
40             o[i].value = (i + 1 === l) ? _d(m[i + 1]) : _d(m[i + 1].substring(0, (m[i + 1].lastIndexOf('&'))));
41             f.appendChild(o[i]);
42         }
43
44         return o;
45     }
46
47    /**
48     * @description Removes the custom fields created to pass additional POST
49     * data, along with the HTML form fields.
50     * @method f
51     * @private
52     * @static
53     * @param {object} f HTML form object.
54     * @param {object} o HTML form fields created from configuration.data.
55     * @return {void}
56     */
57     function _removeData(f, o) {
58         var i, l;
59
60         for (i = 0, l = o.length; i < l; i++) {
61             f.removeChild(o[i]);
62         }
63     }
64
65    /**
66     * @description Sets the appropriate attributes and values to the HTML
67     * form, in preparation of a file upload transaction.
68     * @method _setAttrs
69     * @private
70     * @static
71     * @param {object} f HTML form object.
72     * @param {object} id The Transaction ID.
73     * @param {object} uri Qualified path to transaction resource.
74     * @return {void}
75     */
76     function _setAttrs(f, id, uri) {
77         f.setAttribute('action', uri);
78         f.setAttribute('method', 'POST');
79         f.setAttribute('target', 'ioupload' + id );
80         f.setAttribute(Y.UA.ie && !_std ? 'encoding' : 'enctype', 'multipart/form-data');
81     }
82
83    /**
84     * @description Reset the HTML form attributes to their original values.
85     * @method _resetAttrs
86     * @private
87     * @static
88     * @param {object} f HTML form object.
89     * @param {object} a Object of original attributes.
90     * @return {void}
91     */
92     function _resetAttrs(f, a){
93         var p;
94
95         for (p in a) {
96             if (a.hasOwnProperty(p)) {
97                 if (a[p]) {
98                     f.setAttribute(p, f[p]);
99                 }
100                 else {
101                     f.removeAttribute(p);
102                 }
103             }
104         }
105     }
106
107    /**
108     * @description Starts timeout count if the configuration object
109     * has a defined timeout property.
110     *
111     * @method _startTimeout
112     * @private
113     * @static
114     * @param {object} o Transaction object generated by _create().
115     * @param {object} c Configuration object passed to YUI.io().
116     * @return {void}
117     */
118     function _startTimeout(o, c) {
119         Y.io._timeout[o.id] = w.setTimeout(
120             function() {
121                 var r = { id: o.id, status: 'timeout' };
122
123                 Y.io.complete(r, c);
124                 Y.io.end(r, c);
125             }, c.timeout);
126     }
127
128    /**
129     * @description Clears the timeout interval started by _startTimeout().
130     * @method _clearTimeout
131     * @private
132     * @static
133     * @param {number} id - Transaction ID.
134     * @return {void}
135     */
136     function _clearTimeout(id) {
137         w.clearTimeout(Y.io._timeout[id]);
138         delete Y.io._timeout[id];
139     }
140
141    /**
142     * @description
143     * @method _destroy
144     * @private
145     * @static
146     * @param {o} o The transaction object
147     * @param {object} uri Qualified path to transaction resource.
148     * @param {object} c Configuration object for the transaction.
149     * @return {void}
150     */
151     function _destroy(id) {
152         Y.Event.purgeElement('#ioupload' + id, false);
153         Y.one('body').removeChild(Y.one('#ioupload' + id));
154     }
155
156    /**
157     * @description Bound to the iframe's Load event and processes
158     * the response data.
159     * @method _handle
160     * @private
161     * @static
162     * @param {o} o The transaction object
163     * @param {object} c Configuration object for the transaction.
164     * @return {void}
165     */
166     function _handle(o, c) {
167         var d = Y.one('#ioupload' + o.id).get('contentWindow.document'),
168             b = d.one('body'),
169             p;
170
171         if (c.timeout) {
172             _clearTimeout(o.id);
173         }
174
175         if (b) {
176             // When a response Content-Type of "text/plain" is used, Firefox and Safari
177             // will wrap the response string with <pre></pre>.
178             p = b.one('pre:first-child');
179             o.c.responseText = p ? p.get('text') : b.get('text');
180         }
181         else {
182             o.c.responseXML = d._node;
183         }
184
185         Y.io.complete(o, c);
186         Y.io.end(o, c);
187         // The transaction is complete, so call _destroy to remove
188         // the event listener bound to the iframe transport, and then
189         // destroy the iframe.
190         w.setTimeout( function() { _destroy(o.id); }, 0);
191     }
192
193    /**
194     * @description Creates the iframe transported used in file upload
195     * transactions, and binds the response event handler.
196     *
197     * @method _create
198     * @private
199     * @static
200     * @param {object} o Transaction object generated by _create().
201     * @param {object} c Configuration object passed to YUI.io().
202     * @return {void}
203     */
204     function _create(o, c) {
205         var i = Y.Node.create('<iframe id="ioupload' + o.id + '" name="ioupload' + o.id + '" />');
206             i._node.style.position = 'absolute';
207             i._node.style.top = '-1000px';
208             i._node.style.left = '-1000px';
209
210         Y.one('body').appendChild(i);
211         // Bind the onload handler to the iframe to detect the file upload response.
212         Y.on("load", function() { _handle(o, c); }, '#ioupload' + o.id);
213     }
214
215    /**
216     * @description Uploads HTML form data, inclusive of files/attachments,
217     * using the iframe created in _create to facilitate the transaction.
218     * @method _upload
219     * @private
220     * @static
221     * @param {o} o The transaction object
222     * @param {object} uri Qualified path to transaction resource.
223     * @param {object} c Configuration object for the transaction.
224     * @return {void}
225     */
226     function _send(o, uri, c) {
227         var f = (typeof c.form.id === 'string') ? d.getElementById(c.form.id) : c.form.id,
228             fields,
229             // Track original HTML form attribute values.
230             attr = {
231                 action: f.getAttribute('action'),
232                 target: f.getAttribute('target')
233             };
234
235         // Initialize the HTML form properties in case they are
236         // not defined in the HTML form.
237         _setAttrs(f, o.id, uri);
238         if (c.data) {
239             fields = _addData(f, c.data);
240         }
241
242         // Start polling if a callback is present and the timeout
243         // property has been defined.
244         if (c.timeout) {
245             _startTimeout(o, c);
246         }
247
248         // Start file upload.
249         f.submit();
250         Y.io.start(o.id, c);
251         if (c.data) {
252             _removeData(f, fields);
253         }
254         // Restore HTML form attributes to their original values.
255         _resetAttrs(f, attr);
256
257         return {
258             id: o.id,
259             abort: function() {
260                 var r = { id: o.id, status: 'abort' };
261
262                 if (Y.one('#ioupload' + o.id)) {
263                     _destroy(o.id);
264                     Y.io.complete(r, c);
265                     Y.io.end(r, c);
266                 }
267                 else {
268                     return false;
269                 }
270             },
271             isInProgress: function() {
272                 return Y.one('#ioupload' + o.id) ? true : false;
273             }
274         };
275     }
276
277     Y.mix(Y.io, {
278         upload: function(o, uri, c) {
279             _create(o, c);
280             return _send(o, uri, c);
281         }
282     });
283
284
285
286 }, '3.3.0' ,{requires:['io-base','node-base']});