summaryrefslogtreecommitdiff
path: root/public/js/mv/load.js
blob: b58e3284c38bd59586c1898ec3da63d77ddf4dd8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"use strict";
var mv = function(mv) {
  mv.loader = {
    /* Callbacks */
    onbulkstart: nullFunc,
    onloadstart: nullFunc,
    onprogress: nullFunc,
    onabort: onabort,
    onerror: onerror,
    /* File state accessors */
    numfiles: function() { return numfiles; },
    filenames: function() { return filenames; },
    curfile: function() { return curfile; },
    /* Callback */
    setname: function(n) {},
    /* Use an array of URLs for loading, via d3.xhr */
    use: use,
    /* Initialise the loader module */
    init: init,
  }
  /* Set up handlers for file selector */
  var numfiles = 0;
  var filenames = [];
  var curfile = 0;
  /* Function to handle the loading of the next file - should invoke loadBlobable */
  var nextFile;
  /* Function to be called after all loading */
  var postLoadAll;
  /* The reader used to handle files once the request is complete */
  var reader;
  /* Dummy function */
  function nullFunc() {};
  /* Basic error functions - you probably want to override these */
  /* TODO: Make the defaults a little more sensible */
  function onabort(evt) {
    alert('File load aborted!');
  }
  function onerror(evt) {
    switch(evt.target.error.code) {
    case evt.target.error.NOT_FOUND_ERR:
      alert('File Not Found!');
      break;
    case evt.target.error.NOT_READABLE_ERR:
      alert('File is not readable');
      break;
    case evt.target.error.ABORT_ERR:
      break; // noop
    default:
      alert('An error occurred reading this file.');
    };
  }
  function use(urllist) {
    /* Load files using d3's xhr requests */
    numfiles = urllist.length
    filenames = urllist;
    nextFile = function() {
      mv.loader.setname(urllist[curfile] + "'; 'Downloading");
      var req = d3.xhr(urllist[curfile])
        .on('progress', function(d, i) { reader.onprogress(d3.event); })
        .on('load', function(d) {
          loadBlobable(d.response, urllist[curfile]);
        })
        .responseType("blob")
        .get()
      ;
    };
    startLoading();
  }
  function init(input, each, after) {
    reader = new FileReader();
    postLoadAll = after;
    input.on('change', function() {
      /* Load files using the file selector */
      var files = d3.event.target.files;
      numfiles = files.length;
      filenames = Array.prototype.map.call(files, function(d) { return d.name; });
      nextFile = function() {
        loadBlobable(files[curfile], files[curfile].name);
      }
      startLoading();
    }, false);
    /* General callbacks */
    reader.onerror = function() { mv.loader.onerror.apply(null, arguments) };
    reader.onprogress = function(evt) { if (evt.lengthComputable) { mv.loader.onprogress(evt.loaded, evt.total) } };
    reader.onabort = function() { mv.loader.onabort.apply(null, arguments) };
    reader.onloadstart = function() { mv.loader.onloadstart.apply(null, arguments) };
    /* Logic for finishing or moving on once a file has finished loading */
    reader.onload = function(evt) {
      each(reader.result, filenames[curfile], function() {
        ++curfile;
        if (curfile >= numfiles) {
          /* We're done */
          postLoadAll();
        } else {
          /* Go to the next file, as determined by the current nextFile function */
          nextFile();
        }
      });
    };
  };
  function startLoading() {
    curfile = 0;
    mv.loader.onbulkstart();
    nextFile();
  }
  function loadBlobable(blobable, name) {
    mv.loader.onloadstart();
    if (name.indexOf(".zip", name.length - 4) != -1) {
      zip.createReader(new zip.BlobReader(blobable), function(zipReader) {
        zipReader.getEntries(function(entries) {
          entries.forEach(function(d, i) {
            mv.loader.setname(name + "'; 'Unzipping " + d.filename + " (" + (i + 1) + "/" + entries.length + ")");
            d.getData(new zip.BlobWriter(), function(blob) {
              mv.loader.setname(d.filename);
              reader.readAsBinaryString(blob);
            }, mv.loader.onprogress);
          });
        }, mv.loader.onerror);
      }, mv.loader.onerror);
    } else {
      mv.loader.setname(name);
      reader.readAsBinaryString(blobable);
    }
  }
  return mv;
}(mv || {});