Home | History | Annotate | Download | only in js
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 var harness = {
      6   /**
      7    * Kick off the test harness.
      8    *
      9    * Called by harness.html after the dom has been parsed.
     10    */
     11   init: function() {
     12     console.log('Initializing harness...');
     13 
     14     util.installFileErrorToString();
     15 
     16     var self = this;
     17 
     18     function onFilesystem(filesystem) {
     19       console.log('Filesystem found.');
     20       self.filesystem = filesystem;
     21     };
     22 
     23     window.webkitRequestFileSystem(window.PERSISTENT, 16 * 1024 * 1024,
     24                                    onFilesystem,
     25                                    util.flog('Error initializing filesystem'));
     26 
     27     var paramstr = decodeURIComponent(document.location.search.substr(1));
     28     this.params = paramstr ? JSON.parse(paramstr) : {};
     29 
     30     var input = document.getElementById('default-path');
     31     input.value = this.params.defaultPath || '';
     32     input.addEventListener('keyup', this.onInputKeyUp.bind(this));
     33 
     34     var iframe = document.getElementById('dialog');
     35     iframe.setAttribute('src', 'main.html' + document.location.search);
     36   },
     37 
     38   onInputKeyUp: function(event) {
     39     if (event.keyCode != 13)
     40       return;
     41 
     42     this.changePath();
     43   },
     44 
     45   changePath: function() {
     46     var input = document.getElementById('default-path');
     47     this.changeParam('defaultPath', input.value);
     48   },
     49 
     50   changeParam: function(name, value) {
     51     this.params[name] = value;
     52     document.location.href = '?' + JSON.stringify(this.params);
     53   },
     54 
     55   /**
     56    * 'Reset Fileystem' button click handler.
     57    */
     58   onClearClick: function() {
     59     utils.forEachDirEntry(this.filesystem.root, function(dirEntry) {
     60       if (!dirEntry)
     61         return console.log('Filesystem reset.');
     62 
     63       console.log('Remove: ' + dirEntry.name);
     64 
     65       if (dirEntry.isDirectory) {
     66         dirEntry.removeRecursively();
     67       } else {
     68         dirEntry.remove();
     69       }
     70     });
     71   },
     72 
     73   /**
     74    * Change handler for the 'input type=file' element.
     75    */
     76   onFilesChange: function(event) {
     77     this.importFiles([].slice.call(event.target.files));
     78   },
     79 
     80   /**
     81    * The fileManager object under test.
     82    *
     83    * This is a getter rather than a normal property because the fileManager
     84    * is initialized asynchronously, and we won't be sure when it'll be
     85    * done.  Since harness.fileManager is intended to be used for debugging
     86    * from the JS console, we don't really need to be sure it's ready at any
     87    * particular time.
     88    */
     89   get fileManager() {
     90     return document.getElementById('dialog').contentWindow.fileManager;
     91   },
     92 
     93   /**
     94    * Import a list of File objects into harness.filesystem.
     95    */
     96   importFiles: function(files) {
     97     var currentSrc = null;
     98     var currentDest = null;
     99     var importCount = 0;
    100 
    101     var self = this;
    102 
    103     function onWriterCreated(writer) {
    104       writer.onerror = util.flog('Error writing: ' + currentDest.fullPath);
    105       writer.onwriteend = function() {
    106         console.log('Wrote: ' + currentDest.fullPath);
    107         //console.log(writer);
    108         //console.log(currentDest);
    109         ++importCount;
    110         processNextFile();
    111       };
    112 
    113       writer.write(currentSrc);
    114     }
    115 
    116     function onFileFound(fileEntry) {
    117       currentDest = fileEntry;
    118       currentDest.createWriter(onWriterCreated,
    119                                util.flog('Error creating writer for: ' +
    120                                          currentDest.fullPath));
    121     }
    122 
    123     function processNextFile() {
    124       if (files.length == 0) {
    125         console.log('Import complete: ' + importCount + ' file(s)');
    126         return;
    127       }
    128 
    129       currentSrc = files.shift();
    130       var destPath = currentSrc.name.replace(/\^\^/g, '/');
    131       self.getOrCreateFile(destPath, onFileFound,
    132                               util.flog('Error finding path: ' + destPath));
    133     }
    134 
    135     console.log('Start import: ' + files.length + ' file(s)');
    136     processNextFile();
    137   },
    138 
    139   /**
    140    * Locate the file referred to by path, creating directories or the file
    141    * itself if necessary.
    142    */
    143   getOrCreateFile: function(path, successCallback, errorCallback) {
    144     var dirname = null;
    145     var basename = null;
    146 
    147     function onDirFound(dirEntry) {
    148       dirEntry.getFile(basename, { create: true },
    149                        successCallback, errorCallback);
    150     }
    151 
    152     var i = path.lastIndexOf('/');
    153     if (i > -1) {
    154       dirname = path.substr(0, i);
    155       basename = path.substr(i + 1);
    156     } else {
    157       basename = path;
    158     }
    159 
    160     if (!dirname)
    161       return onDirFound(this.filesystem.root);
    162 
    163     this.getOrCreatePath(dirname, onDirFound, errorCallback);
    164   },
    165 
    166   /**
    167    * Locate the directory referred to by path, creating directories along the
    168    * way.
    169    */
    170   getOrCreatePath: function(path, successCallback, errorCallback) {
    171     var names = path.split('/');
    172 
    173     function getOrCreateNextName(dir) {
    174       if (!names.length)
    175         return successCallback(dir);
    176 
    177       var name;
    178       do {
    179         name = names.shift();
    180       } while (!name || name == '.');
    181 
    182       dir.getDirectory(name, { create: true }, getOrCreateNextName,
    183                        errorCallback);
    184     }
    185 
    186     getOrCreateNextName(this.filesystem.root);
    187   }
    188 };
    189