JAVASCRIPT   10

io-upload-iframe.js

Guest on 25th July 2021 04:29:02 PM

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

Raw Paste


Login or Register to edit or fork this paste. It's free.