1 /*jshint node:true, indent:2, curly:true, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, trailing:true, white:true */
3 /*global XT:true, XV:true, enyo:true, _:true, Globalize:true, FileReader:true */
9 @class An input control for managing the upload of files.<br />
10 Creates a file-type HTML input element,
11 with some HTML5 functionality.
15 /** @lends XV.FileInput# */{
17 kind: "XV.InputWidget",
25 onValueChange: "valueChange"
28 {name: "label", fit: true, classes: "xv-label"},
29 {name: "input", kind: "onyx.Input", onchange: "inputChanged"},
30 {name: "scrim", kind: "onyx.Scrim", showing: false, floating: true}
34 Generally we don't want to set the value of the widget, because
35 setting the value of a file input with the binary data will just throw a security
36 exception. But this function is also used as an essential part of selecting a file.
37 In that circumstance the value is the filename and the options has no silent attribute,
38 which is what's used to differentiate the appropriate times to suppress the setting of
41 setValue: function (value, options) {
42 if (options && options.silent) {
43 // don't try to update widget. Just throws a security exception if you do.
46 this.inherited(arguments);
50 Turns the payload of the bubbled event into the file instead of the filename
53 valueChange: function (inSender, inEvent) {
54 if (inEvent.transformedByFileInput) {
55 // we've already been here. We want to propagate up, but don't run this function again.
59 // I feel bad going to the DOM like this but not that bad.
60 // Some inspiration from https://github.com/JMTK/decorated-file-input
61 // which we can use to replace this widget if we want
63 file = inEvent.originator.$.input.hasNode().files[0],
64 filename = inEvent.value,
71 if (filename.indexOf("C:\\fakepath\\") === 0) {
72 // some browsers obnoxiously give you a fake path, but the only thing
73 // we want is the filename really.
74 filename = filename.replace("C:\\fakepath\\", "");
77 // XXX Browser support for this HTML5 construct is not universal
79 // XXX unsure about the overhead of this constructor. maybe save it globally?
80 reader = new FileReader();
84 message: "Sorry! File upload is only supported on modern browsers"
91 reader.onload = function () {
92 that.$.scrim.setShowing(false);
93 inEvent.value = reader.result;
94 inEvent.filename = filename;
95 inEvent.transformedByFileInput = true; // used to avoid infinite loop
96 that.doValueChange(inEvent);
99 // XXX not sure why this scrim isn't working
100 this.$.scrim.setShowing(true);
102 // XXX binary string is only one of several options here
103 // http://www.html5rocks.com/en/tutorials/file/dndfiles/
104 reader.readAsBinaryString(file); // async
106 // this event will be bubbled by the callback