browser/devtools/app-manager/app-validator.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 "use strict";
     6 let {Ci,Cu,CC} = require("chrome");
     7 const promise = require("devtools/toolkit/deprecated-sync-thenables");
     9 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
    10 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
    11 let XMLHttpRequest = CC("@mozilla.org/xmlextras/xmlhttprequest;1");
    12 let strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
    14 function AppValidator(project) {
    15   this.project = project;
    16   this.errors = [];
    17   this.warnings = [];
    18 }
    20 AppValidator.prototype.error = function (message) {
    21   this.errors.push(message);
    22 };
    24 AppValidator.prototype.warning = function (message) {
    25   this.warnings.push(message);
    26 };
    28 AppValidator.prototype._getPackagedManifestFile = function () {
    29   let manifestFile = FileUtils.File(this.project.location);
    30   if (!manifestFile.exists()) {
    31     this.error(strings.GetStringFromName("validator.nonExistingFolder"));
    32     return null;
    33   }
    34   if (!manifestFile.isDirectory()) {
    35     this.error(strings.GetStringFromName("validator.expectProjectFolder"));
    36     return null;
    37   }
    38   manifestFile.append("manifest.webapp");
    39   if (!manifestFile.exists() || !manifestFile.isFile()) {
    40     this.error(strings.GetStringFromName("validator.wrongManifestFileName"));
    41     return null;
    42   }
    43   return manifestFile;
    44 };
    46 AppValidator.prototype._getPackagedManifestURL = function () {
    47   let manifestFile = this._getPackagedManifestFile();
    48   if (!manifestFile) {
    49     return null;
    50   }
    51   return Services.io.newFileURI(manifestFile).spec;
    52 };
    54 AppValidator.prototype._fetchManifest = function (manifestURL) {
    55   let deferred = promise.defer();
    56   this.manifestURL = manifestURL;
    58   let req = new XMLHttpRequest();
    59   try {
    60     req.open("GET", manifestURL, true);
    61   } catch(e) {
    62     this.error(strings.formatStringFromName("validator.invalidManifestURL", [manifestURL], 1));
    63     deferred.resolve(null);
    64     return deferred.promise;
    65   }
    66   req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
    67   req.onload = (function () {
    68     let manifest = null;
    69     try {
    70       manifest = JSON.parse(req.responseText);
    71     } catch(e) {
    72       this.error(strings.formatStringFromName("validator.invalidManifestJSON", [e, manifestURL], 2));
    73     }
    74     deferred.resolve(manifest);
    75   }).bind(this);
    76   req.onerror = (function () {
    77     this.error(strings.formatStringFromName("validator.noAccessManifestURL", [req.statusText, manifestURL], 2));
    78     deferred.resolve(null);
    79   }).bind(this);
    81   try {
    82     req.send(null);
    83   } catch(e) {
    84     this.error(strings.formatStringFromName("validator.noAccessManifestURL", [e, manifestURL], 2));
    85     deferred.resolve();
    86   }
    88   return deferred.promise;
    89 };
    91 AppValidator.prototype._getManifest = function () {
    92   let manifestURL;
    93   if (this.project.type == "packaged") {
    94     manifestURL = this._getPackagedManifestURL();
    95     if (!manifestURL)
    96       return promise.resolve(null);
    97   } else if (this.project.type == "hosted") {
    98     manifestURL = this.project.location;
    99     try {
   100       Services.io.newURI(manifestURL, null, null);
   101     } catch(e) {
   102       this.error(strings.formatStringFromName("validator.invalidHostedManifestURL", [manifestURL, e.message]));
   103       return promise.resolve(null);
   104     }
   105   } else {
   106     this.error(strings.formatStringFromName("validator.invalidProjectType", [this.project.type], 1));
   107     return promise.resolve(null);
   108   }
   109   return this._fetchManifest(manifestURL);
   110 };
   112 AppValidator.prototype.validateManifest = function (manifest) {
   113   if (!manifest.name) {
   114     this.error(strings.GetStringFromName("validator.missNameManifestProperty"));
   115   }
   117   if (!manifest.icons || Object.keys(manifest.icons).length === 0) {
   118     this.warning(strings.GetStringFromName("validator.missIconsManifestProperty"));
   119   } else if (!manifest.icons["128"]) {
   120     this.warning(strings.GetStringFromName("validator.missIconMarketplace"));
   121   }
   122 };
   124 AppValidator.prototype._getOriginURL = function () {
   125   if (this.project.type == "packaged") {
   126     let manifestURL = Services.io.newURI(this.manifestURL, null, null);
   127     return Services.io.newURI(".", null, manifestURL).spec;
   128   } else if (this.project.type == "hosted") {
   129     return Services.io.newURI(this.project.location, null, null).prePath;
   130   }
   131 };
   133 AppValidator.prototype.validateLaunchPath = function (manifest) {
   134   let deferred = promise.defer();
   135   // The launch_path field has to start with a `/`
   136   if (manifest.launch_path && manifest.launch_path[0] !== "/") {
   137     this.error(strings.formatStringFromName("validator.nonAbsoluteLaunchPath", [manifest.launch_path], 1));
   138     deferred.resolve();
   139     return deferred.promise;
   140   }
   141   let origin = this._getOriginURL();
   142   let path;
   143   if (this.project.type == "packaged") {
   144     path = "." + ( manifest.launch_path || "/index.html" );
   145   } else if (this.project.type == "hosted") {
   146     path = manifest.launch_path || "/";
   147   }
   148   let indexURL;
   149   try {
   150     indexURL = Services.io.newURI(path, null, Services.io.newURI(origin, null, null)).spec;
   151   } catch(e) {
   152     this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [origin + path], 1));
   153     deferred.resolve();
   154     return deferred.promise;
   155   }
   157   let req = new XMLHttpRequest();
   158   try {
   159     req.open("HEAD", indexURL, true);
   160   } catch(e) {
   161     this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
   162     deferred.resolve();
   163     return deferred.promise;
   164   }
   165   req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
   166   req.onload = () => {
   167     if (req.status >= 400)
   168       this.error(strings.formatStringFromName("validator.accessFailedLaunchPathBadHttpCode", [indexURL, req.status], 2));
   169     deferred.resolve();
   170   };
   171   req.onerror = () => {
   172     this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
   173     deferred.resolve();
   174   };
   176   try {
   177     req.send(null);
   178   } catch(e) {
   179     this.error(strings.formatStringFromName("validator.accessFailedLaunchPath", [indexURL], 1));
   180     deferred.resolve();
   181   }
   183   return deferred.promise;
   184 };
   186 AppValidator.prototype.validateType = function (manifest) {
   187   let appType = manifest.type || "web";
   188   if (["web", "privileged", "certified"].indexOf(appType) === -1) {
   189     this.error(strings.formatStringFromName("validator.invalidAppType", [appType], 1));
   190   } else if (this.project.type == "hosted" &&
   191              ["certified", "privileged"].indexOf(appType) !== -1) {
   192     this.error(strings.formatStringFromName("validator.invalidHostedPriviledges", [appType], 1));
   193   }
   195   // certified app are not fully supported on the simulator
   196   if (appType === "certified") {
   197     this.warning(strings.GetStringFromName("validator.noCertifiedSupport"));
   198   }
   199 };
   201 AppValidator.prototype.validate = function () {
   202   this.errors = [];
   203   this.warnings = [];
   204   return this._getManifest().
   205     then((function (manifest) {
   206       if (manifest) {
   207         this.manifest = manifest;
   208         this.validateManifest(manifest);
   209         this.validateType(manifest);
   210         return this.validateLaunchPath(manifest);
   211       }
   212     }).bind(this));
   213 };
   215 exports.AppValidator = AppValidator;

mercurial