API Docs for: 3.8.0
Show:

File: file/js/file-html5.js

  1.     /**
  2.      * The FileHTML5 class provides a wrapper for a file pointer in an HTML5 The File wrapper
  3.      * also implements the mechanics for uploading a file and tracking its progress.
  4.      * @module file-html5
  5.      */    
  6.      
  7.     /**
  8.      * The class provides a wrapper for a file pointer.
  9.      * @class FileHTML5
  10.      * @extends Base
  11.      * @constructor
  12.      * @param {Object} config Configuration object.
  13.      */
  14.     var Lang = Y.Lang,
  15.         Bind = Y.bind,
  16.         Win = Y.config.win;

  17.     var FileHTML5 = function(o) {
  18.        
  19.         var file = null;

  20.         if (FileHTML5.isValidFile(o)) {
  21.             file = o;
  22.         }
  23.         else if (FileHTML5.isValidFile(o.file)) {
  24.             file = o.file;
  25.         }
  26.         else {
  27.             file = false;
  28.         }

  29.         FileHTML5.superclass.constructor.apply(this, arguments);      
  30.        
  31.         if (file && FileHTML5.canUpload()) {
  32.            if (!this.get("file")) {
  33.                this._set("file", file);
  34.            }

  35.            if (!this.get("name")) {
  36.            this._set("name", file.name || file.fileName);
  37.            }

  38.            if (this.get("size") != (file.size || file.fileSize)) {
  39.            this._set("size", file.size || file.fileSize);
  40.            }

  41.            if (!this.get("type")) {
  42.            this._set("type", file.type);
  43.            }

  44.            if (file.hasOwnProperty("lastModifiedDate") && !this.get("dateModified")) {
  45.                this._set("dateModified", file.lastModifiedDate);
  46.            }
  47.         }
  48.     };


  49.     Y.extend(FileHTML5, Y.Base, {

  50.        /**
  51.         * Construction logic executed during FileHTML5 instantiation.
  52.         *
  53.         * @method initializer
  54.         * @protected
  55.         */
  56.         initializer : function (cfg) {
  57.             if (!this.get("id")) {
  58.                 this._set("id", Y.guid("file"));
  59.             }
  60.         },

  61.        /**
  62.         * Handler of events dispatched by the XMLHTTPRequest.
  63.         *
  64.         * @method _uploadEventHandler
  65.         * @param {Event} event The event object received from the XMLHTTPRequest.
  66.         * @protected
  67.         */      
  68.         _uploadEventHandler: function (event) {
  69.             var xhr = this.get("xhr");

  70.             switch (event.type) {
  71.                 case "progress":
  72.                   /**
  73.                    * Signals that progress has been made on the upload of this file.
  74.                    *
  75.                    * @event uploadprogress
  76.                    * @param event {Event} The event object for the `uploadprogress` with the
  77.                    *                      following payload:
  78.                    *  <dl>
  79.                    *      <dt>originEvent</dt>
  80.                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
  81.                    *      <dt>bytesLoaded</dt>
  82.                    *          <dd>The number of bytes of the file that has been uploaded.</dd>
  83.                    *      <dt>bytesTotal</dt>
  84.                    *          <dd>The total number of bytes in the file (the file size)</dd>
  85.                    *      <dt>percentLoaded</dt>
  86.                    *          <dd>The fraction of the file that has been uploaded, out of 100.</dd>
  87.                    *  </dl>
  88.                    */
  89.                    this.fire("uploadprogress", {originEvent: event,
  90.                                                bytesLoaded: event.loaded,
  91.                                                bytesTotal: this.get("size"),
  92.                                                percentLoaded: Math.min(100, Math.round(10000*event.loaded/this.get("size"))/100)
  93.                                                });
  94.                    this._set("bytesUploaded", event.loaded);
  95.                    break;

  96.                 case "load":
  97.                   /**
  98.                    * Signals that this file's upload has completed and data has been received from the server.
  99.                    *
  100.                    * @event uploadcomplete
  101.                    * @param event {Event} The event object for the `uploadcomplete` with the
  102.                    *                      following payload:
  103.                    *  <dl>
  104.                    *      <dt>originEvent</dt>
  105.                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
  106.                    *      <dt>data</dt>
  107.                    *          <dd>The data returned by the server.</dd>
  108.                    *  </dl>
  109.                    */

  110.                    if (xhr.status >= 200 && xhr.status <= 299) {
  111.                         this.fire("uploadcomplete", {originEvent: event,
  112.                                                      data: event.target.responseText});
  113.                         var xhrupload = xhr.upload,
  114.                             boundEventHandler = this.get("boundEventHandler");
  115.    
  116.                         xhrupload.removeEventListener ("progress", boundEventHandler);
  117.                         xhrupload.removeEventListener ("error", boundEventHandler);
  118.                         xhrupload.removeEventListener ("abort", boundEventHandler);
  119.                         xhr.removeEventListener ("load", boundEventHandler);
  120.                         xhr.removeEventListener ("error", boundEventHandler);
  121.                         xhr.removeEventListener ("readystatechange", boundEventHandler);
  122.                        
  123.                         this._set("xhr", null);
  124.                    }
  125.                    else {
  126.                         this.fire("uploaderror", {originEvent: event,
  127.                                                   status: xhr.status,
  128.                                                   statusText: xhr.statusText,
  129.                                                   source: "http"});
  130.                    }                  
  131.                    break;

  132.                 case "error":
  133.                   /**
  134.                    * Signals that this file's upload has encountered an error.
  135.                    *
  136.                    * @event uploaderror
  137.                    * @param event {Event} The event object for the `uploaderror` with the
  138.                    *                      following payload:
  139.                    *  <dl>
  140.                    *      <dt>originEvent</dt>
  141.                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
  142.                    *      <dt>status</dt>
  143.                    *          <dd>The status code reported by the XMLHttpRequest. If it's an HTTP error,
  144.                                   then this corresponds to the HTTP status code received by the uploader.</dd>
  145.                    *      <dt>statusText</dt>
  146.                    *          <dd>The text of the error event reported by the XMLHttpRequest instance</dd>
  147.                    *      <dt>source</dt>
  148.                    *          <dd>Either "http" (if it's an HTTP error), or "io" (if it's a network transmission
  149.                    *              error.)</dd>
  150.                    *
  151.                    *  </dl>
  152.                    */
  153.                    this.fire("uploaderror", {originEvent: event,
  154.                                                   status: xhr.status,
  155.                                                   statusText: xhr.statusText,
  156.                                                   source: "io"});
  157.                    break;

  158.                 case "abort":

  159.                   /**
  160.                    * Signals that this file's upload has been cancelled.
  161.                    *
  162.                    * @event uploadcancel
  163.                    * @param event {Event} The event object for the `uploadcancel` with the
  164.                    *                      following payload:
  165.                    *  <dl>
  166.                    *      <dt>originEvent</dt>
  167.                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
  168.                    *  </dl>
  169.                    */
  170.                    this.fire("uploadcancel", {originEvent: event});
  171.                    break;

  172.                 case "readystatechange":

  173.                   /**
  174.                    * Signals that XMLHttpRequest has fired a readystatechange event.
  175.                    *
  176.                    * @event readystatechange
  177.                    * @param event {Event} The event object for the `readystatechange` with the
  178.                    *                      following payload:
  179.                    *  <dl>
  180.                    *      <dt>readyState</dt>
  181.                    *          <dd>The readyState code reported by the XMLHttpRequest instance.</dd>
  182.                    *      <dt>originEvent</dt>
  183.                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
  184.                    *  </dl>
  185.                    */
  186.                    this.fire("readystatechange", {readyState: event.target.readyState,
  187.                                                   originEvent: event});
  188.                    break;
  189.             }
  190.         },

  191.        /**
  192.         * Starts the upload of a specific file.
  193.         *
  194.         * @method startUpload
  195.         * @param url {String} The URL to upload the file to.
  196.         * @param parameters {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
  197.         * @param fileFieldName {String} (optional) The name of the POST variable that should contain the uploaded file ('Filedata' by default)
  198.         */
  199.         startUpload: function(url, parameters, fileFieldName) {
  200.          
  201.             this._set("bytesUploaded", 0);
  202.            
  203.             this._set("xhr", new XMLHttpRequest());
  204.             this._set("boundEventHandler", Bind(this._uploadEventHandler, this));
  205.                          
  206.             var uploadData = new FormData(),
  207.                 fileField = fileFieldName || "Filedata",
  208.                 xhr = this.get("xhr"),
  209.                 xhrupload = this.get("xhr").upload,
  210.                 boundEventHandler = this.get("boundEventHandler");

  211.             Y.each(parameters, function (value, key) {uploadData.append(key, value);});
  212.             uploadData.append(fileField, this.get("file"));




  213.             xhr.addEventListener ("loadstart", boundEventHandler, false);
  214.             xhrupload.addEventListener ("progress", boundEventHandler, false);
  215.             xhr.addEventListener ("load", boundEventHandler, false);
  216.             xhr.addEventListener ("error", boundEventHandler, false);
  217.             xhrupload.addEventListener ("error", boundEventHandler, false);
  218.             xhrupload.addEventListener ("abort", boundEventHandler, false);
  219.             xhr.addEventListener ("abort", boundEventHandler, false);
  220.             xhr.addEventListener ("loadend", boundEventHandler, false);
  221.             xhr.addEventListener ("readystatechange", boundEventHandler, false);

  222.             xhr.open("POST", url, true);

  223.             xhr.withCredentials = this.get("xhrWithCredentials");

  224.             Y.each(this.get("xhrHeaders"), function (value, key) {
  225.                  xhr.setRequestHeader(key, value);
  226.             });

  227.             xhr.send(uploadData);
  228.      
  229.             /**
  230.              * Signals that this file's upload has started.
  231.              *
  232.              * @event uploadstart
  233.              * @param event {Event} The event object for the `uploadstart` with the
  234.              *                      following payload:
  235.              *  <dl>
  236.              *      <dt>xhr</dt>
  237.              *          <dd>The XMLHttpRequest instance handling the file upload.</dd>
  238.              *  </dl>
  239.              */
  240.              this.fire("uploadstart", {xhr: xhr});

  241.         },

  242.        /**
  243.         * Cancels the upload of a specific file, if currently in progress.
  244.         *
  245.         * @method cancelUpload
  246.         */    
  247.         cancelUpload: function () {
  248.             this.get('xhr').abort();
  249.         }


  250.     }, {

  251.        /**
  252.         * The identity of the class.
  253.         *
  254.         * @property NAME
  255.         * @type String
  256.         * @default 'file'
  257.         * @readOnly
  258.         * @protected
  259.         * @static
  260.         */
  261.         NAME: 'file',

  262.        /**
  263.         * The type of transport.
  264.         *
  265.         * @property TYPE
  266.         * @type String
  267.         * @default 'html5'
  268.         * @readOnly
  269.         * @protected
  270.         * @static
  271.         */
  272.         TYPE: 'html5',

  273.        /**
  274.         * Static property used to define the default attribute configuration of
  275.         * the File.
  276.         *
  277.         * @property ATTRS
  278.         * @type {Object}
  279.         * @protected
  280.         * @static
  281.         */
  282.         ATTRS: {

  283.        /**
  284.         * A String containing the unique id of the file wrapped by the FileFlash instance.
  285.         * The id is supplied by the Flash player uploader.
  286.         *
  287.         * @attribute id
  288.         * @type {String}
  289.         * @initOnly
  290.         */
  291.         id: {
  292.             writeOnce: "initOnly",
  293.             value: null
  294.         },

  295.        /**
  296.         * The size of the file wrapped by FileHTML5. This value is supplied by the instance of File().
  297.         *
  298.         * @attribute size
  299.         * @type {Number}
  300.         * @initOnly
  301.         */
  302.         size: {
  303.             writeOnce: "initOnly",
  304.             value: 0
  305.         },

  306.        /**
  307.         * The name of the file wrapped by FileHTML5. This value is supplied by the instance of File().
  308.         *
  309.         * @attribute name
  310.         * @type {String}
  311.         * @initOnly
  312.         */
  313.         name: {
  314.             writeOnce: "initOnly",
  315.             value: null
  316.         },

  317.        /**
  318.         * The date that the file wrapped by FileHTML5 was created on. This value is supplied by the instance of File().
  319.         *
  320.         * @attribute dateCreated
  321.         * @type {Date}
  322.         * @initOnly
  323.         * @default null
  324.         */
  325.         dateCreated: {
  326.             writeOnce: "initOnly",
  327.             value: null
  328.         },

  329.        /**
  330.         * The date that the file wrapped by FileHTML5 was last modified on. This value is supplied by the instance of File().
  331.         *
  332.         * @attribute dateModified
  333.         * @type {Date}
  334.         * @initOnly
  335.         */
  336.         dateModified: {
  337.             writeOnce: "initOnly",
  338.             value: null
  339.         },

  340.        /**
  341.         * The number of bytes of the file that has been uploaded to the server. This value is
  342.         * non-zero only while a file is being uploaded.
  343.         *
  344.         * @attribute bytesUploaded
  345.         * @type {Date}
  346.         * @readOnly
  347.         */
  348.         bytesUploaded: {
  349.             readOnly: true,
  350.             value: 0
  351.         },

  352.        /**
  353.         * The type of the file wrapped by FileHTML. This value is provided by the instance of File()
  354.         *
  355.         * @attribute type
  356.         * @type {String}
  357.         * @initOnly
  358.         */
  359.         type: {
  360.             writeOnce: "initOnly",
  361.             value: null
  362.         },

  363.        /**
  364.         * The pointer to the instance of File() wrapped by FileHTML5.
  365.         *
  366.         * @attribute file
  367.         * @type {File}
  368.         * @initOnly
  369.         */
  370.         file: {
  371.             writeOnce: "initOnly",
  372.             value: null
  373.         },

  374.        /**
  375.         * The pointer to the instance of XMLHttpRequest used by FileHTML5 to upload the file.
  376.         *
  377.         * @attribute xhr
  378.         * @type {XMLHttpRequest}
  379.         * @initOnly
  380.         */
  381.         xhr: {
  382.             readOnly: true,
  383.             value: null
  384.         },

  385.        /**
  386.         * The dictionary of headers that should be set on the XMLHttpRequest object before
  387.         * sending it.
  388.         *
  389.         * @attribute xhrHeaders
  390.         * @type {Object}
  391.         * @initOnly
  392.         */
  393.         xhrHeaders: {
  394.             value: {}
  395.         },

  396.        /**
  397.         * A Boolean indicating whether the XMLHttpRequest should be sent with user credentials.
  398.         * This does not affect same-site requests.
  399.         *
  400.         * @attribute xhrWithCredentials
  401.         * @type {Boolean}
  402.         * @initOnly
  403.         */
  404.         xhrWithCredentials: {
  405.             value: true
  406.         },

  407.        /**
  408.         * The bound event handler used to handle events from XMLHttpRequest.
  409.         *
  410.         * @attribute boundEventHandler
  411.         * @type {Function}
  412.         * @initOnly
  413.         */
  414.         boundEventHandler: {
  415.             readOnly: true,
  416.             value: null
  417.         }
  418.         },

  419.        /**
  420.         * Checks whether a specific native file instance is valid
  421.         *
  422.         * @method isValidFile
  423.         * @param file {File} A native File() instance.
  424.         * @static
  425.         */
  426.         isValidFile: function (file) {
  427.             return (Win && Win.File && file instanceof File);
  428.         },

  429.        /**
  430.         * Checks whether the browser has a native upload capability
  431.         * via XMLHttpRequest Level 2.
  432.         *
  433.         * @method canUpload
  434.         * @static
  435.         */
  436.         canUpload: function () {
  437.             return (Win && Win.FormData && Win.XMLHttpRequest);
  438.         }
  439.     });

  440.     Y.FileHTML5 = FileHTML5;
  441.