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