--- a/.eslintignore
+++ b/.eslintignore
@@ -119,24 +119,16 @@ devtools/server/actors/**
!devtools/server/actors/webbrowser.js
!devtools/server/actors/webextension.js
!devtools/server/actors/webextension-inspected-window.js
devtools/server/performance/**
devtools/server/tests/browser/**
!devtools/server/tests/browser/browser_webextension_inspected_window.js
devtools/server/tests/mochitest/**
devtools/server/tests/unit/**
-devtools/shared/*.js
-!devtools/shared/async-storage.js
-!devtools/shared/async-utils.js
-!devtools/shared/defer.js
-!devtools/shared/event-emitter.js
-!devtools/shared/indentation.js
-!devtools/shared/loader-plugin-raw.jsm
-!devtools/shared/task.js
devtools/shared/apps/**
devtools/shared/client/**
devtools/shared/discovery/**
devtools/shared/gcli/**
!devtools/shared/gcli/templater.js
devtools/shared/heapsnapshot/**
devtools/shared/layout/**
devtools/shared/locales/**
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -1,119 +1,125 @@
/* 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/. */
+/* globals setImmediate, rpc */
+
"use strict";
/* General utilities used throughout devtools. */
-var { Ci, Cu, Cc, components } = require("chrome");
+var { Ci, Cu, components } = require("chrome");
var Services = require("Services");
var promise = require("promise");
var defer = require("devtools/shared/defer");
var flags = require("./flags");
var {getStack, callFunctionWithAsyncStack} = require("devtools/shared/platform/stack");
loader.lazyRequireGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm", true);
+// Using this name lets the eslint plugin know about lazy defines in
+// this file.
+var DevToolsUtils = exports;
+
// Re-export the thread-safe utils.
const ThreadSafeDevToolsUtils = require("./ThreadSafeDevToolsUtils.js");
for (let key of Object.keys(ThreadSafeDevToolsUtils)) {
exports[key] = ThreadSafeDevToolsUtils[key];
}
/**
* Waits for the next tick in the event loop to execute a callback.
*/
-exports.executeSoon = function executeSoon(aFn) {
+exports.executeSoon = function (fn) {
if (isWorker) {
- setImmediate(aFn);
+ setImmediate(fn);
} else {
let executor;
// Only enable async stack reporting when DEBUG_JS_MODULES is set
// (customized local builds) to avoid a performance penalty.
if (AppConstants.DEBUG_JS_MODULES || flags.testing) {
let stack = getStack();
executor = () => {
- callFunctionWithAsyncStack(aFn, stack, "DevToolsUtils.executeSoon");
+ callFunctionWithAsyncStack(fn, stack, "DevToolsUtils.executeSoon");
};
} else {
- executor = aFn;
+ executor = fn;
}
Services.tm.mainThread.dispatch({
run: exports.makeInfallible(executor)
}, Ci.nsIThread.DISPATCH_NORMAL);
}
};
/**
* Waits for the next tick in the event loop.
*
* @return Promise
* A promise that is resolved after the next tick in the event loop.
*/
-exports.waitForTick = function waitForTick() {
+exports.waitForTick = function () {
let deferred = defer();
exports.executeSoon(deferred.resolve);
return deferred.promise;
};
/**
* Waits for the specified amount of time to pass.
*
- * @param number aDelay
+ * @param number delay
* The amount of time to wait, in milliseconds.
* @return Promise
* A promise that is resolved after the specified amount of time passes.
*/
-exports.waitForTime = function waitForTime(aDelay) {
+exports.waitForTime = function (delay) {
let deferred = defer();
- setTimeout(deferred.resolve, aDelay);
+ setTimeout(deferred.resolve, delay);
return deferred.promise;
};
/**
* Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
* very large arrays by yielding to the browser and continuing execution on the
* next tick.
*
- * @param Array aArray
+ * @param Array array
* The array being iterated over.
- * @param Function aFn
+ * @param Function fn
* The function called on each item in the array. If a promise is
* returned by this function, iterating over the array will be paused
* until the respective promise is resolved.
* @returns Promise
* A promise that is resolved once the whole array has been iterated
- * over, and all promises returned by the aFn callback are resolved.
+ * over, and all promises returned by the fn callback are resolved.
*/
-exports.yieldingEach = function yieldingEach(aArray, aFn) {
+exports.yieldingEach = function (array, fn) {
const deferred = defer();
let i = 0;
- let len = aArray.length;
+ let len = array.length;
let outstanding = [deferred.promise];
(function loop() {
const start = Date.now();
while (i < len) {
// Don't block the main thread for longer than 16 ms at a time. To
// maintain 60fps, you have to render every frame in at least 16ms; we
// aren't including time spent in non-JS here, but this is Good
// Enough(tm).
if (Date.now() - start > 16) {
exports.executeSoon(loop);
return;
}
try {
- outstanding.push(aFn(aArray[i], i++));
+ outstanding.push(fn(array[i], i++));
} catch (e) {
deferred.reject(e);
return;
}
}
deferred.resolve();
}());
@@ -121,126 +127,127 @@ exports.yieldingEach = function yielding
return promise.all(outstanding);
};
/**
* Like XPCOMUtils.defineLazyGetter, but with a |this| sensitive getter that
* allows the lazy getter to be defined on a prototype and work correctly with
* instances.
*
- * @param Object aObject
+ * @param Object object
* The prototype object to define the lazy getter on.
- * @param String aKey
+ * @param String key
* The key to define the lazy getter on.
- * @param Function aCallback
+ * @param Function callback
* The callback that will be called to determine the value. Will be
* called with the |this| value of the current instance.
*/
-exports.defineLazyPrototypeGetter =
-function defineLazyPrototypeGetter(aObject, aKey, aCallback) {
- Object.defineProperty(aObject, aKey, {
+exports.defineLazyPrototypeGetter = function (object, key, callback) {
+ Object.defineProperty(object, key, {
configurable: true,
get: function () {
- const value = aCallback.call(this);
+ const value = callback.call(this);
- Object.defineProperty(this, aKey, {
+ Object.defineProperty(this, key, {
configurable: true,
writable: true,
value: value
});
return value;
}
});
};
/**
* Safely get the property value from a Debugger.Object for a given key. Walks
* the prototype chain until the property is found.
*
- * @param Debugger.Object aObject
+ * @param Debugger.Object object
* The Debugger.Object to get the value from.
- * @param String aKey
+ * @param String key
* The key to look for.
* @return Any
*/
-exports.getProperty = function getProperty(aObj, aKey) {
- let root = aObj;
+exports.getProperty = function (object, key) {
+ let root = object;
try {
do {
- const desc = aObj.getOwnPropertyDescriptor(aKey);
+ const desc = object.getOwnPropertyDescriptor(key);
if (desc) {
if ("value" in desc) {
return desc.value;
}
// Call the getter if it's safe.
return exports.hasSafeGetter(desc) ? desc.get.call(root).return : undefined;
}
- aObj = aObj.proto;
- } while (aObj);
+ object = object.proto;
+ } while (object);
} catch (e) {
// If anything goes wrong report the error and return undefined.
exports.reportException("getProperty", e);
}
return undefined;
};
/**
* Determines if a descriptor has a getter which doesn't call into JavaScript.
*
- * @param Object aDesc
+ * @param Object desc
* The descriptor to check for a safe getter.
* @return Boolean
* Whether a safe getter was found.
*/
-exports.hasSafeGetter = function hasSafeGetter(aDesc) {
+exports.hasSafeGetter = function (desc) {
// Scripted functions that are CCWs will not appear scripted until after
// unwrapping.
try {
- let fn = aDesc.get.unwrap();
+ let fn = desc.get.unwrap();
return fn && fn.callable && fn.class == "Function" && fn.script === undefined;
} catch (e) {
// Avoid exception 'Object in compartment marked as invisible to Debugger'
return false;
}
};
/**
* Check if it is safe to read properties and execute methods from the given JS
* object. Safety is defined as being protected from unintended code execution
* from content scripts (or cross-compartment code).
*
* See bugs 945920 and 946752 for discussion.
*
- * @type Object aObj
+ * @type Object obj
* The object to check.
* @return Boolean
- * True if it is safe to read properties from aObj, or false otherwise.
+ * True if it is safe to read properties from obj, or false otherwise.
*/
-exports.isSafeJSObject = function isSafeJSObject(aObj) {
+exports.isSafeJSObject = function (obj) {
// If we are running on a worker thread, Cu is not available. In this case,
// we always return false, just to be on the safe side.
if (isWorker) {
return false;
}
- if (Cu.getGlobalForObject(aObj) ==
+ if (Cu.getGlobalForObject(obj) ==
Cu.getGlobalForObject(exports.isSafeJSObject)) {
- return true; // aObj is not a cross-compartment wrapper.
+ // obj is not a cross-compartment wrapper.
+ return true;
}
- let principal = Cu.getObjectPrincipal(aObj);
+ let principal = Cu.getObjectPrincipal(obj);
if (Services.scriptSecurityManager.isSystemPrincipal(principal)) {
- return true; // allow chrome objects
+ // allow chrome objects
+ return true;
}
- return Cu.isXrayWrapper(aObj);
+ return Cu.isXrayWrapper(obj);
};
-exports.dumpn = function dumpn(str) {
+exports.dumpn = function (str) {
if (flags.wantLogging) {
dump("DBG-SERVER: " + str + "\n");
}
};
/**
* A verbose logger for low-level tracing.
*/
@@ -248,36 +255,37 @@ exports.dumpv = function (msg) {
if (flags.wantVerbose) {
exports.dumpn(msg);
}
};
/**
* Defines a getter on a specified object that will be created upon first use.
*
- * @param aObject
+ * @param object
* The object to define the lazy getter on.
- * @param aName
- * The name of the getter to define on aObject.
- * @param aLambda
+ * @param name
+ * The name of the getter to define on object.
+ * @param lambda
* A function that returns what the getter should return. This will
* only ever be called once.
*/
-exports.defineLazyGetter = function defineLazyGetter(aObject, aName, aLambda) {
- Object.defineProperty(aObject, aName, {
+exports.defineLazyGetter = function (object, name, lambda) {
+ Object.defineProperty(object, name, {
get: function () {
- delete aObject[aName];
- return aObject[aName] = aLambda.apply(aObject);
+ delete object[name];
+ object[name] = lambda.apply(object);
+ return object[name];
},
configurable: true,
enumerable: true
});
};
-exports.defineLazyGetter(this, "AppConstants", () => {
+DevToolsUtils.defineLazyGetter(this, "AppConstants", () => {
if (isWorker) {
return {};
}
const scope = {};
Cu.import("resource://gre/modules/AppConstants.jsm", scope);
return scope.AppConstants;
});
@@ -324,57 +332,54 @@ Object.defineProperty(exports, "assert",
? reallyAssert
: exports.noop,
});
/**
* Defines a getter on a specified object for a module. The module will not
* be imported until first use.
*
- * @param aObject
+ * @param object
* The object to define the lazy getter on.
- * @param aName
- * The name of the getter to define on aObject for the module.
- * @param aResource
+ * @param name
+ * The name of the getter to define on object for the module.
+ * @param resource
* The URL used to obtain the module.
- * @param aSymbol
+ * @param symbol
* The name of the symbol exported by the module.
- * This parameter is optional and defaults to aName.
+ * This parameter is optional and defaults to name.
*/
-exports.defineLazyModuleGetter = function defineLazyModuleGetter(aObject, aName,
- aResource,
- aSymbol)
-{
- this.defineLazyGetter(aObject, aName, function XPCU_moduleLambda() {
- var temp = {};
- Cu.import(aResource, temp);
- return temp[aSymbol || aName];
+exports.defineLazyModuleGetter = function (object, name, resource, symbol) {
+ this.defineLazyGetter(object, name, function () {
+ let temp = {};
+ Cu.import(resource, temp);
+ return temp[symbol || name];
});
};
-exports.defineLazyGetter(this, "NetUtil", () => {
+DevToolsUtils.defineLazyGetter(this, "NetUtil", () => {
return Cu.import("resource://gre/modules/NetUtil.jsm", {}).NetUtil;
});
-exports.defineLazyGetter(this, "OS", () => {
+DevToolsUtils.defineLazyGetter(this, "OS", () => {
return Cu.import("resource://gre/modules/osfile.jsm", {}).OS;
});
-exports.defineLazyGetter(this, "TextDecoder", () => {
+DevToolsUtils.defineLazyGetter(this, "TextDecoder", () => {
return Cu.import("resource://gre/modules/osfile.jsm", {}).TextDecoder;
});
-exports.defineLazyGetter(this, "NetworkHelper", () => {
+DevToolsUtils.defineLazyGetter(this, "NetworkHelper", () => {
return require("devtools/shared/webconsole/network-helper");
});
/**
* Performs a request to load the desired URL and returns a promise.
*
- * @param aURL String
+ * @param urlIn String
* The URL we will request.
* @param aOptions Object
* An object with the following optional properties:
* - loadFromCache: if false, will bypass the cache and
* always load fresh from the network (default: true)
* - policy: the nsIContentPolicy type to apply when fetching the URL
* (only works when loading from system principal)
* - window: the window to get the loadGroup from
@@ -391,24 +396,24 @@ exports.defineLazyGetter(this, "NetworkH
* - contentType: the content type of the document
*
* If an error occurs, the promise is rejected with that error.
*
* XXX: It may be better to use nsITraceableChannel to get to the sources
* without relying on caching when we can (not for eval, etc.):
* http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
*/
-function mainThreadFetch(aURL, aOptions = { loadFromCache: true,
+function mainThreadFetch(urlIn, aOptions = { loadFromCache: true,
policy: Ci.nsIContentPolicy.TYPE_OTHER,
window: null,
charset: null,
principal: null,
cacheKey: null }) {
// Create a channel.
- let url = aURL.split(" -> ").pop();
+ let url = urlIn.split(" -> ").pop();
let channel;
try {
channel = newChannelForURL(url, aOptions);
} catch (ex) {
return promise.reject(ex);
}
// Set the channel options.
@@ -521,17 +526,17 @@ function mainThreadFetch(aURL, aOptions
/**
* Opens a channel for given URL. Tries a bit harder than NetUtil.newChannel.
*
* @param {String} url - The URL to open a channel for.
* @param {Object} options - The options object passed to @method fetch.
* @return {nsIChannel} - The newly created channel. Throws on failure.
*/
function newChannelForURL(url, { policy, window, principal }) {
- var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
+ let securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
let uri;
try {
uri = Services.io.newURI(url, null, null);
} catch (e) {
// In the xpcshell tests, the script url is the absolute path of the test
// file, which will make a malformed URI error be thrown. Add the file
// scheme to see if it helps.
@@ -565,25 +570,25 @@ function newChannelForURL(url, { policy,
// supported by Windows, so we also need to handle the exception here if
// parsing the URL above doesn't throw.
return newChannelForURL("file://" + url, { policy, window, principal });
}
}
// Fetch is defined differently depending on whether we are on the main thread
// or a worker thread.
-if (!this.isWorker) {
- exports.fetch = mainThreadFetch;
-} else {
+if (this.isWorker) {
// Services is not available in worker threads, nor is there any other way
// to fetch a URL. We need to enlist the help from the main thread here, by
// issuing an rpc request, to fetch the URL on our behalf.
exports.fetch = function (url, options) {
return rpc("fetch", url, options);
};
+} else {
+ exports.fetch = mainThreadFetch;
}
/**
* Open the file at the given path for reading.
*
* @param {String} filePath
*
* @returns Promise<nsIInputStream>
@@ -628,17 +633,17 @@ function errorOnFlag(exports, name) {
}
errorOnFlag(exports, "testing");
errorOnFlag(exports, "wantLogging");
errorOnFlag(exports, "wantVerbose");
// Calls the property with the given `name` on the given `object`, where
// `name` is a string, and `object` a Debugger.Object instance.
-///
+//
// This function uses only the Debugger.Object API to call the property. It
// avoids the use of unsafeDeference. This is useful for example in workers,
// where unsafeDereference will return an opaque security wrapper to the
// referent.
function callPropertyOnObject(object, name) {
// Find the property.
let descriptor;
let proto = object;
@@ -663,10 +668,9 @@ function callPropertyOnObject(object, na
throw new Error("Code was terminated.");
}
if ("throw" in result) {
throw result.throw;
}
return result.return;
}
-
exports.callPropertyOnObject = callPropertyOnObject;
--- a/devtools/shared/ThreadSafeDevToolsUtils.js
+++ b/devtools/shared/ThreadSafeDevToolsUtils.js
@@ -91,17 +91,17 @@ exports.reportException = function repor
* @param aName string
* A name for handler, for use in error messages. If omitted, we use
* handler.name.
*
* (SpiderMonkey does generate good names for anonymous functions, but we
* don't have a way to get at them from JavaScript at the moment.)
*/
exports.makeInfallible = function (handler, name = handler.name) {
- return function (/* arguments */) {
+ return function () {
try {
return handler.apply(this, arguments);
} catch (ex) {
let who = "Handler function";
if (name) {
who += " " + name;
}
exports.reportException(who, ex);
@@ -123,27 +123,31 @@ exports.safeErrorString = function (erro
// isn't a string, don't use it.
try {
if (error.stack) {
let stack = error.stack.toString();
if (typeof stack == "string") {
errorString += "\nStack: " + stack;
}
}
- } catch (ee) { }
+ } catch (ee) {
+ // Ignore.
+ }
// Append additional line and column number information to the output,
// since it might not be part of the stringified error.
if (typeof error.lineNumber == "number" && typeof error.columnNumber == "number") {
errorString += "Line: " + error.lineNumber + ", column: " + error.columnNumber;
}
return errorString;
}
- } catch (ee) { }
+ } catch (ee) {
+ // Ignore.
+ }
// We failed to find a good error description, so do the next best thing.
return Object.prototype.toString.call(error);
};
/**
* Interleaves two arrays element by element, returning the combined array, like
* a zip. In the case of arrays with different sizes, undefined values will be
@@ -289,17 +293,17 @@ exports.settleAll = values => {
values = Array.isArray(values) ? values : [...values];
let countdown = values.length;
let resolutionValues = new Array(countdown);
let rejectionValue;
let rejectionOccurred = false;
if (!countdown) {
resolve(resolutionValues);
- return deferred.promise;
+ return;
}
function checkForCompletion() {
if (--countdown > 0) {
return;
}
if (!rejectionOccurred) {
resolve(resolutionValues);
--- a/devtools/shared/builtin-modules.js
+++ b/devtools/shared/builtin-modules.js
@@ -15,122 +15,119 @@
const { Cu, CC, Cc, Ci } = require("chrome");
const { Loader } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
const jsmScope = Cu.import("resource://gre/modules/Services.jsm", {});
const { Services } = jsmScope;
// Steal various globals only available in JSM scope (and not Sandbox one)
const { PromiseDebugging, ChromeUtils, ThreadSafeChromeUtils, HeapSnapshot,
- atob, btoa, Iterator } = jsmScope;
+ atob, btoa } = jsmScope;
const { URL } = Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
{wantGlobalProperties: ["URL"]});
/**
* Defines a getter on a specified object that will be created upon first use.
*
- * @param aObject
+ * @param object
* The object to define the lazy getter on.
- * @param aName
- * The name of the getter to define on aObject.
- * @param aLambda
+ * @param name
+ * The name of the getter to define on object.
+ * @param lambda
* A function that returns what the getter should return. This will
* only ever be called once.
*/
-function defineLazyGetter(aObject, aName, aLambda)
-{
- Object.defineProperty(aObject, aName, {
+function defineLazyGetter(object, name, lambda) {
+ Object.defineProperty(object, name, {
get: function () {
// Redefine this accessor property as a data property.
- // Delete it first, to rule out "too much recursion" in case aObject is
+ // Delete it first, to rule out "too much recursion" in case object is
// a proxy whose defineProperty handler might unwittingly trigger this
// getter again.
- delete aObject[aName];
- let value = aLambda.apply(aObject);
- Object.defineProperty(aObject, aName, {
+ delete object[name];
+ let value = lambda.apply(object);
+ Object.defineProperty(object, name, {
value,
writable: true,
configurable: true,
enumerable: true
});
return value;
},
configurable: true,
enumerable: true
});
}
/**
* Defines a getter on a specified object for a service. The service will not
* be obtained until first use.
*
- * @param aObject
+ * @param object
* The object to define the lazy getter on.
- * @param aName
- * The name of the getter to define on aObject for the service.
- * @param aContract
+ * @param name
+ * The name of the getter to define on object for the service.
+ * @param contract
* The contract used to obtain the service.
- * @param aInterfaceName
+ * @param interfaceName
* The name of the interface to query the service to.
*/
-function defineLazyServiceGetter(aObject, aName, aContract, aInterfaceName)
-{
- defineLazyGetter(aObject, aName, function XPCU_serviceLambda() {
- return Cc[aContract].getService(Ci[aInterfaceName]);
+function defineLazyServiceGetter(object, name, contract, interfaceName) {
+ defineLazyGetter(object, name, function () {
+ return Cc[contract].getService(Ci[interfaceName]);
});
}
/**
* Defines a getter on a specified object for a module. The module will not
* be imported until first use. The getter allows to execute setup and
* teardown code (e.g. to register/unregister to services) and accepts
* a proxy object which acts on behalf of the module until it is imported.
*
- * @param aObject
+ * @param object
* The object to define the lazy getter on.
- * @param aName
- * The name of the getter to define on aObject for the module.
- * @param aResource
+ * @param name
+ * The name of the getter to define on object for the module.
+ * @param resource
* The URL used to obtain the module.
- * @param aSymbol
+ * @param symbol
* The name of the symbol exported by the module.
- * This parameter is optional and defaults to aName.
- * @param aPreLambda
+ * This parameter is optional and defaults to name.
+ * @param preLambda
* A function that is executed when the proxy is set up.
* This will only ever be called once.
- * @param aPostLambda
+ * @param postLambda
* A function that is executed when the module has been imported to
* run optional teardown procedures on the proxy object.
* This will only ever be called once.
- * @param aProxy
+ * @param proxy
* An object which acts on behalf of the module to be imported until
* the module has been imported.
*/
-function defineLazyModuleGetter(aObject, aName, aResource, aSymbol,
- aPreLambda, aPostLambda, aProxy)
-{
- let proxy = aProxy || {};
+function defineLazyModuleGetter(object, name, resource, symbol,
+ preLambda, postLambda, proxy) {
+ proxy = proxy || {};
- if (typeof (aPreLambda) === "function") {
- aPreLambda.apply(proxy);
+ if (typeof (preLambda) === "function") {
+ preLambda.apply(proxy);
}
- defineLazyGetter(aObject, aName, function XPCU_moduleLambda() {
- var temp = {};
+ defineLazyGetter(object, name, function () {
+ let temp = {};
try {
- Cu.import(aResource, temp);
+ Cu.import(resource, temp);
- if (typeof (aPostLambda) === "function") {
- aPostLambda.apply(proxy);
+ if (typeof (postLambda) === "function") {
+ postLambda.apply(proxy);
}
} catch (ex) {
- Cu.reportError("Failed to load module " + aResource + ".");
+ Cu.reportError("Failed to load module " + resource + ".");
throw ex;
}
- return temp[aSymbol || aName];
+ return temp[symbol || name];
});
}
/**
* Define a getter property on the given object that requires the given
* module. This enables delaying importing modules until the module is
* actually used.
*
@@ -219,17 +216,18 @@ exports.globals = {
atob: atob,
btoa: btoa,
URL,
loader: {
lazyGetter: defineLazyGetter,
lazyImporter: defineLazyModuleGetter,
lazyServiceGetter: defineLazyServiceGetter,
lazyRequireGetter: lazyRequireGetter,
- id: null // Defined by Loader.jsm
+ // Defined by Loader.jsm
+ id: null
},
// Let new XMLHttpRequest do the right thing.
XMLHttpRequest: function () {
return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
},
--- a/devtools/shared/content-observer.js
+++ b/devtools/shared/content-observer.js
@@ -1,14 +1,14 @@
/* 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/. */
"use strict";
-const {Cc, Ci, Cu, Cr} = require("chrome");
+const {Ci} = require("chrome");
const Services = require("Services");
const events = require("sdk/event/core");
/**
* Handles adding an observer for the creation of content document globals,
* event sent immediately after a web content document window has been set up,
* but before any script code has been executed.
--- a/devtools/shared/deprecated-sync-thenables.js
+++ b/devtools/shared/deprecated-sync-thenables.js
@@ -1,16 +1,18 @@
/* 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/. */
/**
* THIS MODULE IS DEPRECATED. IMPORT "Promise.jsm" INSTEAD.
*/
+/* eslint-disable */
+
"use strict";
this.Promise = {};
if (typeof (require) === "function") {
module.exports = Promise;
} else {
this.EXPORTED_SYMBOLS = ["Promise"];
--- a/devtools/shared/dom-node-constants.js
+++ b/devtools/shared/dom-node-constants.js
@@ -1,13 +1,15 @@
/* 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/. */
"use strict";
+/* globals define */
+
// Make this available to both AMD and CJS environments
define(function (require, exports, module) {
module.exports = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
--- a/devtools/shared/flags.js
+++ b/devtools/shared/flags.js
@@ -1,19 +1,24 @@
+"use strict";
/*
* Create a writable property by tracking it with a private variable.
* We cannot make a normal property writeable on `exports` because
* the module system freezes it.
*/
function makeWritableFlag(exports, name) {
let flag = false;
Object.defineProperty(exports, name, {
- get: function () { return flag; },
- set: function (state) { flag = state; }
+ get: function () {
+ return flag;
+ },
+ set: function (state) {
+ flag = state;
+ }
});
}
makeWritableFlag(exports, "wantLogging");
makeWritableFlag(exports, "wantVerbose");
// When the testing flag is set, various behaviors may be altered from
// production mode, typically to enable easier testing or enhanced
--- a/devtools/shared/path.js
+++ b/devtools/shared/path.js
@@ -8,19 +8,18 @@
* Join all the arguments together and normalize the resulting URI.
* The initial path must be an full URI with a protocol (i.e. http://).
*/
exports.joinURI = (initialPath, ...paths) => {
let url;
try {
url = new URL(initialPath);
- }
- catch (e) {
- return;
+ } catch (e) {
+ return null;
}
for (let path of paths) {
if (path) {
url = new URL(path, url);
}
}
--- a/devtools/shared/protocol.js
+++ b/devtools/shared/protocol.js
@@ -60,17 +60,19 @@ types.getType = function (type) {
}
if (typeof (type) !== "string") {
return type;
}
// If already registered, we're done here.
let reg = registeredTypes.get(type);
- if (reg) return reg;
+ if (reg) {
+ return reg;
+ }
// New type, see if it's a collection/lifetime type:
let sep = type.indexOf(":");
if (sep >= 0) {
let collection = type.substring(0, sep);
let subtype = types.getType(type.substring(sep + 1));
if (collection === "array") {
@@ -141,17 +143,19 @@ function identityWrite(v) {
* @returns a type object that can be used in protocol definitions.
*/
types.addType = function (name, typeObject = {}, options = {}) {
if (registeredTypes.has(name)) {
throw Error("Type '" + name + "' already exists.");
}
let type = object.merge({
- toString() { return "[protocol type:" + name + "]";},
+ toString() {
+ return "[protocol type:" + name + "]";
+ },
name: name,
primitive: !(typeObject.read || typeObject.write),
read: identityWrite,
write: identityWrite
}, typeObject);
registeredTypes.set(name, type);
@@ -165,17 +169,19 @@ types.addType = function (name, typeObje
types.removeType = function (name) {
// This type may still be referenced by other types, make sure
// those references don't work.
let type = registeredTypes.get(name);
type.name = "DEFUNCT:" + name;
type.category = "defunct";
type.primitive = false;
- type.read = type.write = function () { throw new Error("Using defunct type: " + name); };
+ type.read = type.write = function () {
+ throw new Error("Using defunct type: " + name);
+ };
registeredTypes.delete(name);
};
/**
* Add an array type to the type system.
*
* getType() will call this function if provided an "array:<type>"
@@ -269,17 +275,17 @@ types.addActorType = function (name) {
}
// Reading a response on the client side, check for an
// existing front on the connection, and create the front
// if it isn't found.
let actorID = typeof (v) === "string" ? v : v.actor;
let front = ctx.conn.getActor(actorID);
if (!front) {
- front = new type.frontClass(ctx.conn);
+ front = new type.frontClass(ctx.conn); // eslint-disable-line new-cap
front.actorID = actorID;
ctx.marshallPool().manage(front);
}
v = type.formType(detail).read(v, front, detail);
front.form(v, detail, ctx);
return front;
@@ -348,17 +354,18 @@ types.addNullableType = function (subtyp
* @param type actorType
* The actor type you'll be detailing.
* @param string detail
* The detail to pass.
*/
types.addActorDetail = function (name, actorType, detail) {
actorType = types.getType(actorType);
if (!actorType._actor) {
- throw Error("Details only apply to actor types, tried to add detail '" + detail + "'' to " + actorType.name + "\n");
+ throw Error(`Details only apply to actor types, tried to add detail '${detail}' ` +
+ `to ${actorType.name}`);
}
return types.addType(name, {
_actor: true,
category: "detail",
read: (v, ctx) => actorType.read(v, ctx, detail),
write: (v, ctx) => actorType.write(v, ctx, detail)
});
};
@@ -397,17 +404,18 @@ types.removeLifetime = function (name) {
* @param string lifetime
* A lifetime string previously regisered with addLifetime()
* @param type subtype
* An actor type
*/
types.addLifetimeType = function (lifetime, subtype) {
subtype = types.getType(subtype);
if (!subtype._actor) {
- throw Error("Lifetimes only apply to actor types, tried to apply lifetime '" + lifetime + "'' to " + subtype.name);
+ throw Error(`Lifetimes only apply to actor types, tried to apply ` +
+ `lifetime '${lifetime}' to ${subtype.name}`);
}
let prop = registeredLifetimes.get(lifetime);
return types.addType(lifetime + ":" + subtype.name, {
category: "lifetime",
read: (value, ctx) => subtype.read(value, ctx[prop]),
write: (value, ctx) => subtype.write(value, ctx[prop])
});
};
@@ -575,17 +583,16 @@ function findPlaceholders(template, cons
path.push(name);
findPlaceholders(template[name], constructor, path, placeholders);
path.pop();
}
return placeholders;
}
-
function describeTemplate(template) {
return JSON.parse(JSON.stringify(template, (key, value) => {
if (value.describe) {
return value.describe();
}
return value;
}));
}
@@ -639,17 +646,19 @@ var Request = Class({
let arg = templateArg.placeholder;
let path = templateArg.path;
let name = path[path.length - 1];
arg.read(getPath(packet, path), ctx, fnArgs, name);
}
return fnArgs;
},
- describe: function () { return describeTemplate(this.template); }
+ describe: function () {
+ return describeTemplate(this.template);
+ }
});
/**
* Manages a response template.
*
* @param object template
* The response template.
* @construcor
@@ -696,17 +705,19 @@ var Response = Class({
read: function (packet, ctx) {
if (!this.retVal) {
return undefined;
}
let v = getPath(packet, this.path);
return this.retVal.read(v, ctx);
},
- describe: function () { return describeTemplate(this.template); }
+ describe: function () {
+ return describeTemplate(this.template);
+ }
});
/**
* Actor and Front implementations
*/
/**
* A protocol object that can manage the lifetime of other protocol
@@ -729,32 +740,38 @@ var Pool = Class({
if (conn) {
this.conn = conn;
}
},
/**
* Return the parent pool for this client.
*/
- parent: function () { return this.conn.poolFor(this.actorID); },
+ parent: function () {
+ return this.conn.poolFor(this.actorID);
+ },
/**
* Override this if you want actors returned by this actor
* to belong to a different actor by default.
*/
- marshallPool: function () { return this; },
+ marshallPool: function () {
+ return this;
+ },
/**
* Pool is the base class for all actors, even leaf nodes.
* If the child map is actually referenced, go ahead and create
* the stuff needed by the pool.
*/
__poolMap: null,
get _poolMap() {
- if (this.__poolMap) return this.__poolMap;
+ if (this.__poolMap) {
+ return this.__poolMap;
+ }
this.__poolMap = new Map();
this.conn.addActorPool(this);
return this.__poolMap;
},
/**
* Add an actor as a child of this pool.
*/
@@ -878,17 +895,19 @@ var Actor = Class({
let sendEvent = this._sendEvent.bind(this, name);
this.on(name, (...args) => {
sendEvent.apply(null, args);
});
}
}
},
- toString: function () { return "[Actor " + this.typeName + "/" + this.actorID + "]"; },
+ toString: function () {
+ return "[Actor " + this.typeName + "/" + this.actorID + "]";
+ },
_sendEvent: function (name, ...args) {
if (!this._actorSpec.events.has(name)) {
// It's ok to emit events that don't go over the wire.
return;
}
let request = this._actorSpec.events.get(name);
let packet;
@@ -945,18 +964,22 @@ exports.Actor = Actor;
* @param spec
* The method specification, with the following (optional) properties:
* request (object): a request template.
* response (object): a response template.
* oneway (bool): 'true' if no response should be sent.
*/
exports.method = function (fn, spec = {}) {
fn._methodSpec = Object.freeze(spec);
- if (spec.request) Object.freeze(spec.request);
- if (spec.response) Object.freeze(spec.response);
+ if (spec.request) {
+ Object.freeze(spec.request);
+ }
+ if (spec.response) {
+ Object.freeze(spec.response);
+ }
return fn;
};
/**
* Generates an actor specification from an actor description.
*/
var generateActorSpec = function (actorDesc) {
let actorSpec = {
@@ -981,33 +1004,35 @@ var generateActorSpec = function (actorD
actorSpec[name] = types.addDictType(actorDesc.typeName + "__" + name, desc.value);
}
}
if (desc.value._methodSpec) {
let methodSpec = desc.value._methodSpec;
let spec = {};
spec.name = methodSpec.name || name;
- spec.request = Request(object.merge({type: spec.name}, methodSpec.request || undefined));
+ spec.request = Request(object.merge({type: spec.name},
+ methodSpec.request || undefined));
spec.response = Response(methodSpec.response || undefined);
spec.release = methodSpec.release;
spec.oneway = methodSpec.oneway;
actorSpec.methods.push(spec);
}
}
// Find additional method specifications
if (actorDesc.methods) {
for (let name in actorDesc.methods) {
let methodSpec = actorDesc.methods[name];
let spec = {};
spec.name = methodSpec.name || name;
- spec.request = Request(object.merge({type: spec.name}, methodSpec.request || undefined));
+ spec.request = Request(object.merge({type: spec.name},
+ methodSpec.request || undefined));
spec.response = Response(methodSpec.response || undefined);
spec.release = methodSpec.release;
spec.oneway = methodSpec.oneway;
actorSpec.methods.push(spec);
}
}
@@ -1051,25 +1076,25 @@ var generateRequestHandlers = function (
args = spec.request.read(packet, this);
} catch (ex) {
console.error("Error reading request: " + packet.type);
throw ex;
}
let ret = this[spec.name].apply(this, args);
- let sendReturn = (ret) => {
+ let sendReturn = (retToSend) => {
if (spec.oneway) {
// No need to send a response.
return;
}
let response;
try {
- response = spec.response.write(ret, this);
+ response = spec.response.write(retToSend, this);
} catch (ex) {
console.error("Error writing response to: " + spec.name);
throw ex;
}
response.from = this.actorID;
// If spec.release has been specified, destroy the object.
if (spec.release) {
try {
@@ -1197,19 +1222,23 @@ var Front = Class({
}
return Pool.prototype.manage.call(this, front);
},
/**
* @returns a promise that will resolve to the actorID this front
* represents.
*/
- actor: function () { return promise.resolve(this.actorID); },
+ actor: function () {
+ return promise.resolve(this.actorID);
+ },
- toString: function () { return "[Front for " + this.typeName + "/" + this.actorID + "]"; },
+ toString: function () {
+ return "[Front for " + this.typeName + "/" + this.actorID + "]";
+ },
/**
* Update the actor from its representation.
* Subclasses should override this.
*/
form: function (form) {},
/**
@@ -1260,17 +1289,19 @@ var Front = Class({
throw ex;
}
if (event.pre) {
let results = event.pre.map(pre => pre.apply(this, args));
// Check to see if any of the preEvents returned a promise -- if so,
// wait for their resolution before emitting. Otherwise, emit synchronously.
if (results.some(result => result && typeof result.then === "function")) {
- promise.all(results).then(() => events.emit.apply(null, [this, event.name].concat(args)));
+ promise.all(results).then(() => {
+ return events.emit.apply(null, [this, event.name].concat(args));
+ });
return;
}
}
events.emit.apply(null, [this, event.name].concat(args));
return;
}
@@ -1363,17 +1394,18 @@ var generateRequestMethods = function (a
methods.forEach(spec => {
let name = spec.name;
// If there's already a property by this name in the front, it must
// be a custom front method.
if (name in frontProto) {
let custom = frontProto[spec.name]._customFront;
if (custom === undefined) {
- throw Error("Existing method for " + spec.name + " not marked customFront while processing " + actorType.typeName + ".");
+ throw Error(`Existing method for ${spec.name} not marked customFront while ` +
+ ` processing ${actorSpec.typeName}.`);
}
// If the user doesn't need the impl don't generate it.
if (!custom.impl) {
return;
}
name = custom.impl;
}
@@ -1410,46 +1442,45 @@ var generateRequestMethods = function (a
return fn.apply(this, args).then(result => {
this.destroy();
return result;
});
};
}
});
-
// Process event specifications
frontProto._clientSpec = {};
- let events = actorSpec.events;
- if (events) {
+ let actorEvents = actorSpec.events;
+ if (actorEvents) {
// This actor has events, scan the prototype for preEvent handlers...
let preHandlers = new Map();
for (let name of Object.getOwnPropertyNames(frontProto)) {
let desc = Object.getOwnPropertyDescriptor(frontProto, name);
if (!desc.value) {
continue;
}
if (desc.value._preEvent) {
let preEvent = desc.value._preEvent;
- if (!events.has(preEvent)) {
+ if (!actorEvents.has(preEvent)) {
throw Error("preEvent for event that doesn't exist: " + preEvent);
}
let handlers = preHandlers.get(preEvent);
if (!handlers) {
handlers = [];
preHandlers.set(preEvent, handlers);
}
handlers.push(desc.value);
}
}
frontProto._clientSpec.events = new Map();
- for (let [name, request] of events) {
+ for (let [name, request] of actorEvents) {
frontProto._clientSpec.events.set(request.type, {
name: name,
request: request,
pre: preHandlers.get(name)
});
}
}
@@ -1513,17 +1544,16 @@ exports.dumpActorSpec = function (type)
}
if (actorSpec.events) {
for (let [name, request] of actorSpec.events) {
ret.events[name] = request.describe();
}
}
-
JSON.stringify(ret);
return ret;
};
exports.dumpProtocolSpec = function () {
let ret = {
types: {},
--- a/devtools/shared/system.js
+++ b/devtools/shared/system.js
@@ -1,14 +1,14 @@
/* 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/. */
"use strict";
-const { Cc, Ci, Cu } = require("chrome");
+const { Cc, Ci } = require("chrome");
const { Task } = require("devtools/shared/task");
loader.lazyRequireGetter(this, "Services");
loader.lazyRequireGetter(this, "promise");
loader.lazyRequireGetter(this, "defer", "devtools/shared/defer");
loader.lazyRequireGetter(this, "OS", "resource://gre/modules/commonjs/node/os.js");
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "AppConstants",
@@ -59,33 +59,34 @@ function* getSystemInfo() {
if (apptype === "b2g") {
os = "B2G";
// `getSetting` does not work in child processes on b2g.
// TODO bug 1205797, make this work in child processes.
try {
hardware = yield exports.getSetting("deviceinfo.hardware");
version = yield exports.getSetting("deviceinfo.os");
} catch (e) {
+ // Ignore.
}
- }
- // Not B2G
- else {
+ } else {
+ // Not B2G
os = appInfo.OS;
version = appInfo.version;
}
let bundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
if (bundle) {
brandName = bundle.GetStringFromName("brandFullName");
} else {
brandName = null;
}
if (win) {
- let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+ let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
dpi = utils.displayDPI;
useragent = win.navigator.userAgent;
width = win.screen.width;
height = win.screen.height;
physicalWidth = win.screen.width * win.devicePixelRatio;
physicalHeight = win.screen.height * win.devicePixelRatio;
}
@@ -126,17 +127,18 @@ function* getSystemInfo() {
// The version of Gecko or XULRunner platform, for example "1.8.1.19" or
// "1.9.3pre". In "Firefox 3.7 alpha 1" the application version is "3.7a1pre"
// while the platform version is "1.9.3pre"
platformversion: geckoVersion,
geckoversion: geckoVersion,
// Locale used in this build
- locale: Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
+ locale: Cc["@mozilla.org/chrome/chrome-registry;1"]
+ .getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
/**
* Information regarding the operating system.
*/
// Returns the endianness of the architecture: either "LE" or "BE"
endianness: OS.endianness(),
@@ -181,22 +183,23 @@ function* getSystemInfo() {
CACHED_INFO = info;
return info;
}
function getProfileLocation() {
// In child processes, we cannot access the profile location.
try {
let profd = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
- let profservice = Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);
- var profiles = profservice.profiles;
+ let profservice = Cc["@mozilla.org/toolkit/profile-service;1"]
+ .getService(Ci.nsIToolkitProfileService);
+ let profiles = profservice.profiles;
while (profiles.hasMoreElements()) {
let profile = profiles.getNext().QueryInterface(Ci.nsIToolkitProfile);
if (profile.rootDir.path == profd.path) {
- return profile = profile.name;
+ return profile.name;
}
}
return profd.leafName;
} catch (e) {
return "";
}
}
@@ -209,17 +212,18 @@ function getAppIniString(section, key) {
inifile = Services.dirsvc.get("CurProcD", Ci.nsIFile);
inifile.append("application.ini");
}
if (!inifile.exists()) {
return undefined;
}
- let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(Ci.nsIINIParserFactory).createINIParser(inifile);
+ let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"]
+ .getService(Ci.nsIINIParserFactory).createINIParser(inifile);
try {
return iniParser.getString(section, key);
} catch (e) {
return undefined;
}
}
/**
@@ -311,23 +315,24 @@ function getSetting(name) {
let deferred = defer();
if ("@mozilla.org/settingsService;1" in Cc) {
let settingsService;
// settingsService fails in b2g child processes
// TODO bug 1205797, make this work in child processes.
try {
- settingsService = Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);
+ settingsService = Cc["@mozilla.org/settingsService;1"]
+ .getService(Ci.nsISettingsService);
} catch (e) {
return promise.reject(e);
}
- let req = settingsService.createLock().get(name, {
- handle: (name, value) => deferred.resolve(value),
+ settingsService.createLock().get(name, {
+ handle: (_, value) => deferred.resolve(value),
handleError: (error) => deferred.reject(error),
});
} else {
deferred.reject(new Error("No settings service"));
}
return deferred.promise;
}