b2g/components/HelperAppDialog.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/b2g/components/HelperAppDialog.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,123 @@
     1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
    1.10 +
    1.11 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.12 +Cu.import("resource://gre/modules/Services.jsm");
    1.13 +
    1.14 +XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
    1.15 +                                  "resource://gre/modules/Downloads.jsm");
    1.16 +
    1.17 +XPCOMUtils.defineLazyModuleGetter(this, "Task",
    1.18 +                                  "resource://gre/modules/Task.jsm");
    1.19 +
    1.20 +// -----------------------------------------------------------------------
    1.21 +// HelperApp Launcher Dialog
    1.22 +//
    1.23 +// For now on b2g we never prompt and just download to the default
    1.24 +// location.
    1.25 +//
    1.26 +// -----------------------------------------------------------------------
    1.27 +
    1.28 +function HelperAppLauncherDialog() { }
    1.29 +
    1.30 +HelperAppLauncherDialog.prototype = {
    1.31 +  classID: Components.ID("{710322af-e6ae-4b0c-b2c9-1474a87b077e}"),
    1.32 +  QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
    1.33 +
    1.34 +  show: function(aLauncher, aContext, aReason) {
    1.35 +    aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
    1.36 +    aLauncher.saveToDisk(null, false);
    1.37 +  },
    1.38 +
    1.39 +  promptForSaveToFile: function(aLauncher,
    1.40 +                                aContext,
    1.41 +                                aDefaultFile,
    1.42 +                                aSuggestedFileExt,
    1.43 +                                aForcePrompt) {
    1.44 +    throw Cr.NS_ERROR_NOT_AVAILABLE;
    1.45 +  },
    1.46 +
    1.47 +  promptForSaveToFileAsync: function(aLauncher,
    1.48 +                                     aContext,
    1.49 +                                     aDefaultFile,
    1.50 +                                     aSuggestedFileExt,
    1.51 +                                     aForcePrompt) {
    1.52 +    // Retrieve the user's default download directory.
    1.53 +    Task.spawn(function() {
    1.54 +      let file = null;
    1.55 +      try {
    1.56 +        let defaultFolder = yield Downloads.getPreferredDownloadsDirectory();
    1.57 +        let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    1.58 +        dir.initWithPath(defaultFolder);
    1.59 +        file = this.validateLeafName(dir, aDefaultFile, aSuggestedFileExt);
    1.60 +      } catch(e) { }
    1.61 +      aLauncher.saveDestinationAvailable(file);
    1.62 +    }.bind(this)).then(null, Cu.reportError);
    1.63 +  },
    1.64 +
    1.65 +  validateLeafName: function(aLocalFile, aLeafName, aFileExt) {
    1.66 +    if (!(aLocalFile && this.isUsableDirectory(aLocalFile)))
    1.67 +      return null;
    1.68 +
    1.69 +    // Remove any leading periods, since we don't want to save hidden files
    1.70 +    // automatically.
    1.71 +    aLeafName = aLeafName.replace(/^\.+/, "");
    1.72 +
    1.73 +    if (aLeafName == "")
    1.74 +      aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
    1.75 +    aLocalFile.append(aLeafName);
    1.76 +
    1.77 +    this.makeFileUnique(aLocalFile);
    1.78 +    return aLocalFile;
    1.79 +  },
    1.80 +
    1.81 +  makeFileUnique: function(aLocalFile) {
    1.82 +    try {
    1.83 +      // Note - this code is identical to that in
    1.84 +      //   toolkit/content/contentAreaUtils.js.
    1.85 +      // If you are updating this code, update that code too! We can't share code
    1.86 +      // here since this is called in a js component.
    1.87 +      let collisionCount = 0;
    1.88 +      while (aLocalFile.exists()) {
    1.89 +        collisionCount++;
    1.90 +        if (collisionCount == 1) {
    1.91 +          // Append "(2)" before the last dot in (or at the end of) the filename
    1.92 +          // special case .ext.gz etc files so we don't wind up with .tar(2).gz
    1.93 +          if (aLocalFile.leafName.match(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i))
    1.94 +            aLocalFile.leafName = aLocalFile.leafName.replace(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i, "(2)$&");
    1.95 +          else
    1.96 +            aLocalFile.leafName = aLocalFile.leafName.replace(/(\.[^\.]*)?$/, "(2)$&");
    1.97 +        }
    1.98 +        else {
    1.99 +          // replace the last (n) in the filename with (n+1)
   1.100 +          aLocalFile.leafName = aLocalFile.leafName.replace(/^(.*\()\d+\)/, "$1" + (collisionCount+1) + ")");
   1.101 +        }
   1.102 +      }
   1.103 +      aLocalFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
   1.104 +    }
   1.105 +    catch (e) {
   1.106 +      dump("*** exception in makeFileUnique: " + e + "\n");
   1.107 +
   1.108 +      if (e.result == Cr.NS_ERROR_FILE_ACCESS_DENIED)
   1.109 +        throw e;
   1.110 +
   1.111 +      if (aLocalFile.leafName == "" || aLocalFile.isDirectory()) {
   1.112 +        aLocalFile.append("unnamed");
   1.113 +        if (aLocalFile.exists())
   1.114 +          aLocalFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
   1.115 +      }
   1.116 +    }
   1.117 +  },
   1.118 +
   1.119 +  isUsableDirectory: function(aDirectory) {
   1.120 +    return aDirectory.exists() &&
   1.121 +           aDirectory.isDirectory() &&
   1.122 +           aDirectory.isWritable();
   1.123 +  },
   1.124 +};
   1.125 +
   1.126 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HelperAppLauncherDialog]);

mercurial