Back out 28f2f39068ad (bug 1166405) for b2g mochitest-6 bustage
authorPhil Ringnalda <philringnalda@gmail.com>
Mon, 25 May 2015 18:47:41 -0700
changeset 277927 70768c4ba85772a9cbd9fd29b4fcfa22985bc663
parent 277926 12ce98475c6e15c4eada2807bb7ec7003711ab9f
child 277928 c8053cb8ac32ea639e6b3d7df1fdd07f95e0a51f
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1166405
milestone41.0a1
backs out28f2f39068ade786254128bd5e1ad9404476f7b8
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 28f2f39068ad (bug 1166405) for b2g mochitest-6 bustage CLOSED TREE
dom/ipc/manifestMessages.js
dom/manifest/ImageObjectProcessor.js
dom/manifest/ManifestImageObjectProcessor.jsm
dom/manifest/ManifestObtainer.js
dom/manifest/ManifestObtainer.jsm
dom/manifest/ManifestProcessor.js
dom/manifest/ManifestProcessor.jsm
dom/manifest/ManifestValueExtractor.jsm
dom/manifest/ValueExtractor.js
dom/manifest/WebManifest.jsm
dom/manifest/moz.build
dom/manifest/test/browser_ManifestObtainer_obtain.js
dom/manifest/test/common.js
--- a/dom/ipc/manifestMessages.js
+++ b/dom/ipc/manifestMessages.js
@@ -1,29 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.*/
 /*
  * Manifest obtainer frame script implementation of:
- * http://www.w3.org/TR/appmanifest/#obtaining
+ * http://w3c.github.io/manifest/#obtaining
  *
  * It searches a top-level browsing context for
  * a <link rel=manifest> element. Then fetches
  * and processes the linked manifest.
  *
  * BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1083410
+ * exported ManifestObtainer
  */
-/*globals content, sendAsyncMessage, addMessageListener, Components*/
+/*globals content, ManifestProcessor, XPCOMUtils, sendAsyncMessage, addMessageListener, Components*/
 'use strict';
 const {
   utils: Cu
 } = Components;
-const {
-  ManifestProcessor
-} = Cu.import('resource://gre/modules/WebManifest.jsm', {});
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+XPCOMUtils.defineLazyModuleGetter(this, 'ManifestProcessor',
+  'resource://gre/modules/ManifestProcessor.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'ManifestObtainer',
+  'resource://gre/modules/ManifestObtainer.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'BrowserUtils',
+  'resource://gre/modules/BrowserUtils.jsm');
 
 addMessageListener('DOM:ManifestObtainer:Obtain', (aMsg) => {
   fetchManifest()
     .then(
       manifest => sendAsyncMessage('DOM:ManifestObtainer:Obtain', {
         success: true,
         result: manifest,
         msgId: aMsg.data.msgId
rename from dom/manifest/ImageObjectProcessor.js
rename to dom/manifest/ManifestImageObjectProcessor.jsm
--- a/dom/manifest/ImageObjectProcessor.js
+++ b/dom/manifest/ManifestImageObjectProcessor.jsm
@@ -1,60 +1,62 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 /*
- * ImageObjectProcessor
+ * ManifestImageObjectProcessor
  * Implementation of Image Object processing algorithms from:
- * http://www.w3.org/TR/appmanifest/#image-object-and-its-members
+ * http://www.w3.org/2008/webapps/manifest/#image-object-and-its-members
  *
- * This is intended to be used in conjunction with ManifestProcessor.js
+ * This is intended to be used in conjunction with ManifestProcessor.jsm
  *
  * Creates an object to process Image Objects as defined by the
  * W3C specification. This is used to process things like the
  * icon member and the splash_screen member.
  *
  * Usage:
  *
  *   .process(aManifest, aBaseURL, aMemberName);
  *
  */
 /*exported EXPORTED_SYMBOLS*/
-/*globals Components */
+/*globals Components*/
 'use strict';
+this.EXPORTED_SYMBOLS = ['ManifestImageObjectProcessor']; // jshint ignore:line
+const imports = {};
 const {
   utils: Cu,
-  interfaces: Ci,
-  classes: Cc
+  classes: Cc,
+  interfaces: Ci
 } = Components;
-
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.importGlobalProperties(['URL']);
-const netutil = Cc['@mozilla.org/network/util;1']
+imports.netutil = Cc['@mozilla.org/network/util;1']
   .getService(Ci.nsINetUtil);
 
-function ImageObjectProcessor(aConsole, aExtractor) {
+function ManifestImageObjectProcessor(aConsole, aExtractor) {
   this.console = aConsole;
   this.extractor = aExtractor;
 }
 
 // Static getters
-Object.defineProperties(ImageObjectProcessor, {
+Object.defineProperties(ManifestImageObjectProcessor, {
   'decimals': {
     get: function() {
       return /^\d+$/;
     }
   },
   'anyRegEx': {
     get: function() {
       return new RegExp('any', 'i');
     }
   }
 });
 
-ImageObjectProcessor.prototype.process = function(
+ManifestImageObjectProcessor.prototype.process = function(
   aManifest, aBaseURL, aMemberName
 ) {
   const spec = {
     objectName: 'manifest',
     object: aManifest,
     property: aMemberName,
     expectedType: 'array',
     trim: false
@@ -87,17 +89,17 @@ ImageObjectProcessor.prototype.process =
       objectName: 'image',
       object: aImage,
       property: 'type',
       expectedType: 'string',
       trim: true
     };
     let value = extractor.extractValue(spec);
     if (value) {
-      value = netutil.parseContentType(value, charset, hadCharset);
+      value = imports.netutil.parseContentType(value, charset, hadCharset);
     }
     return value || undefined;
   }
 
   function processDensityMember(aImage) {
     const value = parseFloat(aImage.density);
     const validNum = Number.isNaN(value) || value === +Infinity || value <=
       0;
@@ -137,37 +139,36 @@ ImageObjectProcessor.prototype.process =
       value.split(/\s+/)
         .filter(isValidSizeValue)
         .forEach(size => sizes.add(size));
     }
     return sizes;
     // Implementation of HTML's link@size attribute checker.
     function isValidSizeValue(aSize) {
       const size = aSize.toLowerCase();
-      if (ImageObjectProcessor.anyRegEx.test(aSize)) {
+      if (ManifestImageObjectProcessor.anyRegEx.test(aSize)) {
         return true;
       }
       if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
         return false;
       }
       // Split left of x for width, after x for height.
       const widthAndHeight = size.split('x');
       const w = widthAndHeight.shift();
       const h = widthAndHeight.join('x');
       const validStarts = !w.startsWith('0') && !h.startsWith('0');
-      const validDecimals = ImageObjectProcessor.decimals.test(w + h);
+      const validDecimals = ManifestImageObjectProcessor.decimals.test(w + h);
       return (validStarts && validDecimals);
     }
   }
 
   function processBackgroundColorMember(aImage) {
     const spec = {
       objectName: 'image',
       object: aImage,
       property: 'background_color',
       expectedType: 'string',
       trim: true
     };
     return extractor.extractColorValue(spec);
   }
 };
-this.ImageObjectProcessor = ImageObjectProcessor; // jshint ignore:line
-this.EXPORTED_SYMBOLS = ['ImageObjectProcessor']; // jshint ignore:line
+this.ManifestImageObjectProcessor = ManifestImageObjectProcessor; // jshint ignore:line
rename from dom/manifest/ManifestObtainer.js
rename to dom/manifest/ManifestObtainer.jsm
--- a/dom/manifest/ManifestObtainer.js
+++ b/dom/manifest/ManifestObtainer.jsm
@@ -16,16 +16,18 @@
  *   'chrome://global/content/manifestMessages.js'
  *
  * Which is injected into every browser instance via browser.js.
  *
  * BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1083410
  * exported ManifestObtainer
  */
 'use strict';
+this.EXPORTED_SYMBOLS = ['ManifestObtainer'];
+
 const MSG_KEY = 'DOM:ManifestObtainer:Obtain';
 let messageCounter = 0;
 // FIXME: Ideally, we would store a reference to the
 //        message manager in a weakmap instead of needing a
 //        browserMap. However, trying to store a messageManager
 //        results in a TypeError because of:
 //        https://bugzilla.mozilla.org/show_bug.cgi?id=888600
 const browsersMap = new WeakMap();
@@ -76,10 +78,8 @@ ManifestObtainer.prototype = {
     function toError(aErrorClone) {
       const error = new Error();
       Object.getOwnPropertyNames(aErrorClone)
         .forEach(name => error[name] = aErrorClone[name]);
       return error;
     }
   }
 };
-this.ManifestObtainer = ManifestObtainer; // jshint ignore:line
-this.EXPORTED_SYMBOLS = ['ManifestObtainer']; // jshint ignore:line
rename from dom/manifest/ManifestProcessor.js
rename to dom/manifest/ManifestProcessor.jsm
--- a/dom/manifest/ManifestProcessor.js
+++ b/dom/manifest/ManifestProcessor.jsm
@@ -7,48 +7,53 @@
  * http://www.w3.org/2008/webapps/manifest/
  *
  * Creates manifest processor that lets you process a JSON file
  * or individual parts of a manifest object. A manifest is just a
  * standard JS object that has been cleaned up.
  *
  *   .process({jsonText,manifestURL,docURL});
  *
- * Depends on ImageObjectProcessor to process things like
+ * Depends on ManifestImageObjectProcessor to process things like
  * icons and splash_screens.
  *
  * TODO: The constructor should accept the UA's supported orientations.
  * TODO: The constructor should accept the UA's supported display modes.
  * TODO: hook up developer tools to console. (1086997).
  */
-/*globals Components*/
+/*exported EXPORTED_SYMBOLS */
+/*JSLint options in comment below: */
+/*globals Components, XPCOMUtils, Intl*/
 'use strict';
+this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line
+const imports = {};
 const {
   utils: Cu
 } = Components;
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.importGlobalProperties(['URL']);
+XPCOMUtils.defineLazyModuleGetter(imports, 'Services',
+  'resource://gre/modules/Services.jsm');
 const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
   'browser'
 ]);
 const orientationTypes = new Set(['any', 'natural', 'landscape', 'portrait',
   'portrait-primary', 'portrait-secondary', 'landscape-primary',
   'landscape-secondary'
 ]);
 const {
   ConsoleAPI
-} = Cu.import('resource://gre/modules/devtools/Console.jsm', {});
-// ValueExtractor is used by the various processors to get values
-// from the manifest and to report errors.
+} = Cu.import('resource://gre/modules/devtools/Console.jsm');
 const {
-  ValueExtractor
-} = Cu.import('resource://gre/modules/ValueExtractor.js', {});
-// ImageObjectProcessor is used to process things like icons and images
+  ManifestImageObjectProcessor: ImgObjProcessor
+} = Cu.import('resource://gre/modules/ManifestImageObjectProcessor.jsm');
+
 const {
-  ImageObjectProcessor
-} = Cu.import('resource://gre/modules/ImageObjectProcessor.js', {});
+  ManifestValueExtractor
+} = Cu.import('resource://gre/modules/ManifestValueExtractor.jsm');
 
 function ManifestProcessor() {}
 
 // Static getters
 Object.defineProperties(ManifestProcessor, {
   'defaultDisplayMode': {
     get: function() {
       return 'browser';
@@ -65,192 +70,193 @@ Object.defineProperties(ManifestProcesso
     }
   }
 });
 
 ManifestProcessor.prototype = {
   // process() method processes JSON text into a clean manifest
   // that conforms with the W3C specification. Takes an object
   // expecting the following dictionary items:
-  //  * jsonText: the JSON string to be processed.
-  //  * manifestURL: the URL of the manifest, to resolve URLs.
-  //  * docURL: the URL of the owner doc, for security checks
+  //  * aJsonText: the JSON string to be processed.
+  //  * aManifestURL: the URL of the manifest, to resolve URLs.
+  //  * aDocURL: the URL of the owner doc, for security checks
   process({
-    jsonText,
+    jsonText: aJsonText,
     manifestURL: aManifestURL,
     docURL: aDocURL
   }) {
     const console = new ConsoleAPI({
       prefix: 'Web Manifest: '
     });
     const manifestURL = new URL(aManifestURL);
     const docURL = new URL(aDocURL);
     let rawManifest = {};
     try {
-      rawManifest = JSON.parse(jsonText);
+      rawManifest = JSON.parse(aJsonText);
     } catch (e) {}
     if (typeof rawManifest !== 'object' || rawManifest === null) {
       let msg = 'Manifest needs to be an object.';
       console.warn(msg);
       rawManifest = {};
     }
-    const extractor = new ValueExtractor(console);
-    const imgObjProcessor = new ImageObjectProcessor(console, extractor);
+    const extractor = new ManifestValueExtractor(console);
+    const imgObjProcessor = new ImgObjProcessor(console, extractor);
     const processedManifest = {
-      'lang': processLangMember(),
-      'start_url': processStartURLMember(),
-      'display': processDisplayMember(),
-      'orientation': processOrientationMember(),
-      'name': processNameMember(),
+      'lang': processLangMember(rawManifest),
+      'start_url': processStartURLMember(rawManifest, manifestURL, docURL),
+      'display': processDisplayMember(rawManifest),
+      'orientation': processOrientationMember(rawManifest),
+      'name': processNameMember(rawManifest),
       'icons': imgObjProcessor.process(
         rawManifest, manifestURL, 'icons'
       ),
       'splash_screens': imgObjProcessor.process(
         rawManifest, manifestURL, 'splash_screens'
       ),
-      'short_name': processShortNameMember(),
-      'theme_color': processThemeColorMember(),
+      'short_name': processShortNameMember(rawManifest),
+      'theme_color': processThemeColorMember(rawManifest),
     };
-    processedManifest.scope = processScopeMember();
+    processedManifest.scope = processScopeMember(rawManifest, manifestURL,
+      docURL, new URL(processedManifest['start_url'])); // jshint ignore:line
+
     return processedManifest;
 
-    function processNameMember() {
+    function processNameMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'name',
         expectedType: 'string',
         trim: true
       };
       return extractor.extractValue(spec);
     }
 
-    function processShortNameMember() {
+    function processShortNameMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'short_name',
         expectedType: 'string',
         trim: true
       };
       return extractor.extractValue(spec);
     }
 
-    function processOrientationMember() {
+    function processOrientationMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'orientation',
         expectedType: 'string',
         trim: true
       };
       const value = extractor.extractValue(spec);
       if (ManifestProcessor.orientationTypes.has(value)) {
         return value;
       }
       // The spec special-cases orientation to return the empty string.
       return '';
     }
 
-    function processDisplayMember() {
+    function processDisplayMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'display',
         expectedType: 'string',
         trim: true
       };
       const value = extractor.extractValue(spec);
       if (ManifestProcessor.displayModes.has(value)) {
         return value;
       }
       return ManifestProcessor.defaultDisplayMode;
     }
 
-    function processScopeMember() {
+    function processScopeMember(aManifest, aManifestURL, aDocURL, aStartURL) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'scope',
         expectedType: 'string',
         trim: false
       };
       let scopeURL;
-      const startURL = new URL(processedManifest.start_url);
       const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return undefined;
       }
       try {
-        scopeURL = new URL(value, manifestURL);
+        scopeURL = new URL(value, aManifestURL);
       } catch (e) {
         let msg = 'The URL of scope is invalid.';
         console.warn(msg);
         return undefined;
       }
-      if (scopeURL.origin !== docURL.origin) {
+      if (scopeURL.origin !== aDocURL.origin) {
         let msg = 'Scope needs to be same-origin as Document.';
         console.warn(msg);
         return undefined;
       }
       // If start URL is not within scope of scope URL:
-      let isSameOrigin = startURL && startURL.origin !== scopeURL.origin;
-      if (isSameOrigin || !startURL.pathname.startsWith(scopeURL.pathname)) {
+      let isSameOrigin = aStartURL && aStartURL.origin !== scopeURL.origin;
+      if (isSameOrigin || !aStartURL.pathname.startsWith(scopeURL.pathname)) {
         let msg =
           'The start URL is outside the scope, so scope is invalid.';
         console.warn(msg);
         return undefined;
       }
       return scopeURL.href;
     }
 
-    function processStartURLMember() {
+    function processStartURLMember(aManifest, aManifestURL, aDocURL) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'start_url',
         expectedType: 'string',
         trim: false
       };
-      let result = new URL(docURL).href;
+      let result = new URL(aDocURL).href;
       const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return result;
       }
       let potentialResult;
       try {
-        potentialResult = new URL(value, manifestURL);
+        potentialResult = new URL(value, aManifestURL);
       } catch (e) {
         console.warn('Invalid URL.');
         return result;
       }
-      if (potentialResult.origin !== docURL.origin) {
+      if (potentialResult.origin !== aDocURL.origin) {
         let msg = 'start_url must be same origin as document.';
         console.warn(msg);
       } else {
         result = potentialResult.href;
       }
       return result;
     }
 
-    function processThemeColorMember() {
+    function processThemeColorMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'theme_color',
         expectedType: 'string',
         trim: true
       };
       return extractor.extractColorValue(spec);
     }
 
-    function processLangMember() {
+    function processLangMember(aManifest) {
       const spec = {
         objectName: 'manifest',
-        object: rawManifest,
+        object: aManifest,
         property: 'lang',
         expectedType: 'string',
         trim: true
       };
       let tag = extractor.extractValue(spec);
       // TODO: Check if tag is structurally valid.
       //       Cannot do this because we don't support Intl API on Android.
       //       https://bugzilla.mozilla.org/show_bug.cgi?id=864843
@@ -259,9 +265,8 @@ ManifestProcessor.prototype = {
       //       Can't do this today because there is no direct means to
       //       access canonicalization algorithms through Intl API.
       //       https://github.com/tc39/ecma402/issues/5
       return tag;
     }
   }
 };
 this.ManifestProcessor = ManifestProcessor; // jshint ignore:line
-this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line
rename from dom/manifest/ValueExtractor.js
rename to dom/manifest/ManifestValueExtractor.jsm
--- a/dom/manifest/ValueExtractor.js
+++ b/dom/manifest/ManifestValueExtractor.jsm
@@ -1,38 +1,43 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+ * file, You can obtain one at https://www.mozilla.org/MPL/2.0/. */
 /*
  * Helper functions extract values from manifest members
  * and reports conformance violations.
  */
 /*globals Components*/
 'use strict';
+const imports = {};
 const {
   classes: Cc,
   interfaces: Ci
 } = Components;
+imports.DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
+  .getService(Ci.inIDOMUtils);
 
-function ValueExtractor(aConsole) {
+this.EXPORTED_SYMBOLS = ['ManifestValueExtractor']; // jshint ignore:line
+
+function ManifestValueExtractor(aConsole) {
   this.console = aConsole;
 }
 
-ValueExtractor.prototype = {
+ManifestValueExtractor.prototype = {
   // This function takes a 'spec' object and destructures
   // it to extract a value. If the value is of th wrong type, it
   // warns the developer and returns undefined.
   //  expectType: is the type of a JS primitive (string, number, etc.)
   //  object: is the object from which to extract the value.
   //  objectName: string used to construct the developer warning.
   //  property: the name of the property being extracted.
   //  trim: boolean, if the value should be trimmed (used by string type).
   extractValue({
-      expectedType, object, objectName, property, trim
-    }) {
+    expectedType, object, objectName, property, trim
+  }) {
     const value = object[property];
     const isArray = Array.isArray(value);
     // We need to special-case "array", as it's not a JS primitive.
     const type = (isArray) ? 'array' : typeof value;
     if (type !== expectedType) {
       if (type !== 'undefined') {
         let msg = `Expected the ${objectName}'s ${property} `;
         msg += `member to be a ${expectedType}.`;
@@ -44,22 +49,20 @@ ValueExtractor.prototype = {
     const shouldTrim = expectedType === 'string' && value && trim;
     if (shouldTrim) {
       return value.trim() || undefined;
     }
     return value;
   },
   extractColorValue(spec) {
     const value = this.extractValue(spec);
-    const DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
-      .getService(Ci.inIDOMUtils);
     let color;
-    if (DOMUtils.isValidCSSColor(value)) {
+    if (imports.DOMUtils.isValidCSSColor(value)) {
       color = value;
-    } else if (value) {
+    } else {
       const msg = `background_color: ${value} is not a valid CSS color.`;
       this.console.warn(msg);
     }
     return color;
   }
 };
-this.ValueExtractor = ValueExtractor; // jshint ignore:line
-this.EXPORTED_SYMBOLS = ['ValueExtractor']; // jshint ignore:line
+
+this.ManifestValueExtractor = ManifestValueExtractor; // jshint ignore:line
deleted file mode 100644
--- a/dom/manifest/WebManifest.jsm
+++ /dev/null
@@ -1,19 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-/*exported EXPORTED_SYMBOLS, ManifestProcessor, ManifestObtainer*/
-/*globals Components */
-'use strict';
-const {
-  utils: Cu
-} = Components;
-
-const EXPORTED_SYMBOLS = [
-  'ManifestObtainer',
-  'ManifestProcessor'
-];
-
-// Export public interfaces
-for (let symbl of EXPORTED_SYMBOLS) {
-  Cu.import(`resource://gre/modules/${symbl}.js`);
-}
--- a/dom/manifest/moz.build
+++ b/dom/manifest/moz.build
@@ -1,16 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXTRA_JS_MODULES += [
-    'ImageObjectProcessor.js',
-    'ManifestObtainer.js',
-    'ManifestProcessor.js',
-    'ValueExtractor.js',
-    'WebManifest.jsm'
+    'ManifestImageObjectProcessor.jsm',
+    'ManifestObtainer.jsm',
+    'ManifestProcessor.jsm',
+    'ManifestValueExtractor.jsm'
 ]
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/dom/manifest/test/browser_ManifestObtainer_obtain.js
+++ b/dom/manifest/test/browser_ManifestObtainer_obtain.js
@@ -1,15 +1,12 @@
 //Used by JSHint:
-/*global Cu, BrowserTestUtils, add_task, SpecialPowers, gBrowser, Assert*/
+/*global Cu, ManifestObtainer, BrowserTestUtils, add_task, SpecialPowers, todo_is, gBrowser, Assert*/
 'use strict';
-const {
-  ManifestObtainer
-} = Cu.import('resource://gre/modules/WebManifest.jsm', {});
-
+Cu.import('resource://gre/modules/ManifestObtainer.jsm', this);
 requestLongerTimeout(4); // e10s tests take time.
 const defaultURL =
   'http://example.org/tests/dom/manifest/test/resource.sjs';
 const remoteURL =
   'http://mochi.test:8888/tests/dom/manifest/test/resource.sjs';
 const tests = [
   // Fetch tests.
   {
--- a/dom/manifest/test/common.js
+++ b/dom/manifest/test/common.js
@@ -1,22 +1,20 @@
 /**
  * Common infrastructure for manifest tests.
  **/
 
 'use strict';
-const {
-  ManifestProcessor
-} = SpecialPowers.Cu.import('resource://gre/modules/WebManifest.jsm');
-const processor = new ManifestProcessor();
-const manifestURL = new URL(document.location.origin + '/manifest.json');
-const docURL = document.location;
-const seperators = '\u2028\u2029\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000';
-const lineTerminators = '\u000D\u000A\u2028\u2029';
-const whiteSpace = `${seperators}${lineTerminators}`;
-const typeTests = [1, null, {},
-  [], false
-];
-const data = {
-  jsonText: '{}',
-  manifestURL: manifestURL,
-  docURL: docURL
-};
+const bsp = SpecialPowers.Cu.import('resource://gre/modules/ManifestProcessor.jsm'),
+  processor = new bsp.ManifestProcessor(),
+  manifestURL = new URL(document.location.origin + '/manifest.json'),
+  docURL = document.location,
+  seperators = '\u2028\u2029\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000',
+  lineTerminators = '\u000D\u000A\u2028\u2029',
+  whiteSpace = `${seperators}${lineTerminators}`,
+  typeTests = [1, null, {},
+    [], false
+  ],
+  data = {
+    jsonText: '{}',
+    manifestURL: manifestURL,
+    docURL: docURL
+  };