Bug 1340366 - Remove privilege APIs for har-builder, har-collector and clipboard r?honza,gasolin
MozReview-Commit-ID: Eq7IHsd0Ljl
--- a/devtools/client/netmonitor/har/har-automation.js
+++ b/devtools/client/netmonitor/har/har-automation.js
@@ -3,17 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-disable mozilla/reject-some-requires */
"use strict";
const { Ci } = require("chrome");
const { Class } = require("sdk/core/heritage");
-const { resolve } = require("promise");
const Services = require("Services");
loader.lazyRequireGetter(this, "HarCollector", "devtools/client/netmonitor/har/har-collector", true);
loader.lazyRequireGetter(this, "HarExporter", "devtools/client/netmonitor/har/har-exporter", true);
loader.lazyRequireGetter(this, "HarUtils", "devtools/client/netmonitor/har/har-utils", true);
const prefDomain = "devtools.netmonitor.har.";
@@ -117,17 +116,17 @@ var HarAutomation = Class({
}
},
autoExport: function () {
let autoExport = Services.prefs.getBoolPref(prefDomain +
"enableAutoExportToFile");
if (!autoExport) {
- return resolve();
+ return Promise.resolve();
}
// Auto export to file is enabled, so save collected data
// into a file and use all the default options.
let data = {
fileName: Services.prefs.getCharPref(prefDomain + "defaultFileName"),
};
--- a/devtools/client/netmonitor/har/har-builder.js
+++ b/devtools/client/netmonitor/har/har-builder.js
@@ -1,29 +1,25 @@
/* 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 { defer, all } = require("promise");
-const { LocalizationHelper } = require("devtools/shared/l10n");
const Services = require("Services");
const appInfo = Services.appinfo;
+const { LocalizationHelper } = require("devtools/shared/l10n");
const { CurlUtils } = require("devtools/client/shared/curl");
const {
getFormDataSections,
getUrlQuery,
parseQueryString,
} = require("devtools/client/netmonitor/request-utils");
-loader.lazyGetter(this, "L10N", () => {
- return new LocalizationHelper("devtools/client/locales/har.properties");
-});
-
+const L10N = new LocalizationHelper("devtools/client/locales/har.properties");
const HAR_VERSION = "1.1";
/**
* This object is responsible for building HAR file. See HAR spec:
* https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
* http://www.softwareishard.com/blog/har-12-spec/
*
* @param {Object} options configuration object
@@ -63,20 +59,17 @@ HarBuilder.prototype = {
// Build entries.
for (let file of this._options.items) {
log.entries.push(this.buildEntry(log, file));
}
// Some data needs to be fetched from the backend during the
// build process, so wait till all is done.
- let { resolve, promise } = defer();
- all(this.promises).then(results => resolve({ log: log }));
-
- return promise;
+ return Promise.all(this.promises).then(() => ({ log }));
},
// Helpers
buildLog: function () {
return {
version: HAR_VERSION,
creator: {
--- a/devtools/client/netmonitor/har/har-collector.js
+++ b/devtools/client/netmonitor/har/har-collector.js
@@ -1,16 +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 { defer, all } = require("promise");
-const { makeInfallible } = require("devtools/shared/DevToolsUtils");
const Services = require("Services");
// Helper tracer. Should be generic sharable by other modules (bug 1171927)
const trace = {
log: function (...args) {
}
};
@@ -27,18 +25,16 @@ function HarCollector(options) {
this.onRequestHeaders = this.onRequestHeaders.bind(this);
this.onRequestCookies = this.onRequestCookies.bind(this);
this.onRequestPostData = this.onRequestPostData.bind(this);
this.onResponseHeaders = this.onResponseHeaders.bind(this);
this.onResponseCookies = this.onResponseCookies.bind(this);
this.onResponseContent = this.onResponseContent.bind(this);
this.onEventTimings = this.onEventTimings.bind(this);
- this.onPageLoadTimeout = this.onPageLoadTimeout.bind(this);
-
this.clear();
}
HarCollector.prototype = {
// Connection
start: function () {
this.debuggerClient.addListener("networkEvent", this.onNetworkEvent);
@@ -61,23 +57,22 @@ HarCollector.prototype = {
this.lastRequestStart = -1;
this.requests = [];
},
waitForHarLoad: function () {
// There should be yet another timeout e.g.:
// 'devtools.netmonitor.har.pageLoadTimeout'
// that should force export even if page isn't fully loaded.
- let deferred = defer();
- this.waitForResponses().then(() => {
- trace.log("HarCollector.waitForHarLoad; DONE HAR loaded!");
- deferred.resolve(this);
+ return new Promise((resolve) => {
+ this.waitForResponses().then(() => {
+ trace.log("HarCollector.waitForHarLoad; DONE HAR loaded!");
+ resolve(this);
+ });
});
-
- return deferred.promise;
},
waitForResponses: function () {
trace.log("HarCollector.waitForResponses; " + this.requests.length);
// All requests for additional data must be received to have complete
// HTTP info to generate the result HAR file. So, wait for all current
// promises. Note that new promises (requests) can be generated during the
@@ -112,33 +107,25 @@ HarCollector.prototype = {
// The auto-export is not done if the timeout is set to zero (or less).
// This is useful in cases where the export is done manually through
// API exposed to the content.
let timeout = Services.prefs.getIntPref(
"devtools.netmonitor.har.pageLoadedTimeout");
trace.log("HarCollector.waitForTimeout; " + timeout);
- this.pageLoadDeferred = defer();
-
- if (timeout <= 0) {
- this.pageLoadDeferred.resolve();
- return this.pageLoadDeferred.promise;
- }
-
- this.pageLoadTimeout = setTimeout(this.onPageLoadTimeout, timeout);
-
- return this.pageLoadDeferred.promise;
- },
-
- onPageLoadTimeout: function () {
- trace.log("HarCollector.onPageLoadTimeout;");
-
- // Ha, page has been loaded. Resolve the final timeout promise.
- this.pageLoadDeferred.resolve();
+ return new Promise((resolve) => {
+ if (timeout <= 0) {
+ resolve();
+ }
+ this.pageLoadTimeout = setTimeout(() => {
+ trace.log("HarCollector.onPageLoadTimeout;");
+ resolve();
+ }, timeout);
+ });
},
resetPageLoadTimeout: function () {
// Remove the current timeout.
if (this.pageLoadTimeout) {
trace.log("HarCollector.resetPageLoadTimeout;");
clearTimeout(this.pageLoadTimeout);
@@ -268,38 +255,34 @@ HarCollector.prototype = {
if (request) {
this.requests.push(request);
}
this.resetPageLoadTimeout();
},
getData: function (actor, method, callback) {
- let deferred = defer();
+ return new Promise((resolve) => {
+ if (!this.webConsoleClient[method]) {
+ console.error("HarCollector.getData: ERROR Unknown method!");
+ resolve();
+ }
- if (!this.webConsoleClient[method]) {
- console.error("HarCollector.getData; ERROR " +
- "Unknown method!");
- return deferred.resolve();
- }
-
- let file = this.getFile(actor);
+ let file = this.getFile(actor);
- trace.log("HarCollector.getData; REQUEST " + method +
- ", " + file.url, file);
+ trace.log("HarCollector.getData; REQUEST " + method +
+ ", " + file.url, file);
- this.webConsoleClient[method](actor, response => {
- trace.log("HarCollector.getData; RESPONSE " + method +
- ", " + file.url, response);
-
- callback(response);
- deferred.resolve(response);
+ this.webConsoleClient[method](actor, response => {
+ trace.log("HarCollector.getData; RESPONSE " + method +
+ ", " + file.url, response);
+ callback(response);
+ resolve(response);
+ });
});
-
- return deferred.promise;
},
/**
* Handles additional information received for a "requestHeaders" packet.
*
* @param object response
* The message received from the server.
*/
@@ -401,25 +384,29 @@ HarCollector.prototype = {
let totalTime = response.totalTime;
file.totalTime = totalTime;
file.endedMillis = file.startedMillis + totalTime;
},
// Helpers
- getLongHeaders: makeInfallible(function (headers) {
+ getLongHeaders: function (headers) {
for (let header of headers) {
if (typeof header.value == "object") {
- this.getString(header.value).then(value => {
- header.value = value;
- });
+ try {
+ this.getString(header.value).then(value => {
+ header.value = value;
+ });
+ } catch (error) {
+ trace.log("HarCollector.getLongHeaders; ERROR when getString", error);
+ }
}
}
- }),
+ },
/**
* Fetches the full text of a string.
*
* @param object | string stringGrip
* The long string grip containing the corresponding actor.
* If you pass in a plain string (by accident or because you're lazy),
* then a promise of the same string is simply returned.
@@ -442,17 +429,17 @@ HarCollector.prototype = {
* The function will wait even for the newly added promises.
* (this isn't possible with the default Promise.all);
*/
function waitForAll(promises) {
// Remove all from the original array and get clone of it.
let clone = promises.splice(0, promises.length);
// Wait for all promises in the given array.
- return all(clone).then(() => {
+ return Promise.all(clone).then(() => {
// If there are new promises (in the original array)
// to wait for - chain them!
if (promises.length) {
return waitForAll(promises);
}
return undefined;
});
}
--- a/devtools/client/netmonitor/har/har-exporter.js
+++ b/devtools/client/netmonitor/har/har-exporter.js
@@ -1,28 +1,19 @@
/* 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/. */
-/* eslint-disable mozilla/reject-some-requires */
-
"use strict";
-const { Cc, Ci } = require("chrome");
const Services = require("Services");
-const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
-const { resolve } = require("promise");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
const { HarUtils } = require("./har-utils.js");
const { HarBuilder } = require("./har-builder.js");
-XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function () {
- return Cc["@mozilla.org/widget/clipboardhelper;1"]
- .getService(Ci.nsIClipboardHelper);
-});
-
var uid = 1;
// Helper tracer. Should be generic sharable by other modules (bug 1171927)
const trace = {
log: function (...args) {
}
};
@@ -78,17 +69,17 @@ const HarExporter = {
"devtools.netmonitor.har.compress");
// Get target file for exported data. Bail out, if the user
// presses cancel.
let file = HarUtils.getTargetFile(options.defaultFileName,
options.jsonp, options.compress);
if (!file) {
- return resolve();
+ return Promise.resolve();
}
trace.log("HarExporter.save; " + options.defaultFileName, options);
return this.fetchHarData(options).then(jsonString => {
if (!HarUtils.saveToFile(file, jsonString, options.compress)) {
let msg = "Failed to save HAR file at: " + options.defaultFileName;
console.error(msg);
@@ -127,22 +118,22 @@ const HarExporter = {
options.forceExport = options.forceExport ||
Services.prefs.getBoolPref("devtools.netmonitor.har.forceExport");
// Build HAR object.
return this.buildHarData(options).then(har => {
// Do not export an empty HAR file, unless the user
// explicitly says so (using the forceExport option).
if (!har.log.entries.length && !options.forceExport) {
- return resolve();
+ return Promise.resolve();
}
let jsonString = this.stringify(har);
if (!jsonString) {
- return resolve();
+ return Promise.resolve();
}
// If JSONP is wanted, wrap the string in a function call
if (options.jsonp) {
// This callback name is also used in HAR Viewer by default.
// http://www.softwareishard.com/har/viewer/
let callbackName = options.jsonpCallback || "onInputData";
jsonString = callbackName + "(" + jsonString + ");";
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -1,15 +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 promise = require("promise");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
const { TimelineFront } = require("devtools/shared/fronts/timeline");
const { CurlUtils } = require("devtools/client/shared/curl");
const { ACTIVITY_TYPE } = require("./constants");
const { EVENTS } = require("./events");
const { configureStore } = require("./store");
const Actions = require("./actions/index");
@@ -29,119 +28,122 @@ const gStore = window.gStore = configure
*/
var NetMonitorController = {
/**
* Initializes the view and connects the monitor client.
*
* @return object
* A promise that is resolved when the monitor finishes startup.
*/
- async startupNetMonitor() {
+ startupNetMonitor() {
if (this._startup) {
- return this._startup.promise;
+ return this._startup;
}
- this._startup = promise.defer();
- await this.connect();
- this._startup.resolve();
- return undefined;
+ this._startup = new Promise(async (resolve) => {
+ await this.connect();
+ resolve();
+ });
+ return this._startup;
},
/**
* Destroys the view and disconnects the monitor client from the server.
*
* @return object
* A promise that is resolved when the monitor finishes shutdown.
*/
- async shutdownNetMonitor() {
+ shutdownNetMonitor() {
if (this._shutdown) {
- return this._shutdown.promise;
+ return this._shutdown;
}
- this._shutdown = promise.defer();
- gStore.dispatch(Actions.batchReset());
- this.TargetEventsHandler.disconnect();
- this.NetworkEventsHandler.disconnect();
- await this.disconnect();
- this._shutdown.resolve();
- return undefined;
+ this._shutdown = new Promise(async (resolve) => {
+ gStore.dispatch(Actions.batchReset());
+ this.TargetEventsHandler.disconnect();
+ this.NetworkEventsHandler.disconnect();
+ await this.disconnect();
+ resolve();
+ });
+
+ return this._shutdown;
},
/**
* Initiates remote or chrome network monitoring based on the current target,
* wiring event handlers as necessary. Since the TabTarget will have already
* started listening to network requests by now, this is largely
* netmonitor-specific initialization.
*
* @return object
* A promise that is resolved when the monitor finishes connecting.
*/
- async connect() {
+ connect() {
if (this._connection) {
- return this._connection.promise;
+ return this._connection;
}
- this._connection = promise.defer();
-
- // Some actors like AddonActor or RootActor for chrome debugging
- // aren't actual tabs.
- if (this._target.isTabActor) {
- this.tabClient = this._target.activeTab;
- }
+ this._connection = new Promise(async (resolve) => {
+ // Some actors like AddonActor or RootActor for chrome debugging
+ // aren't actual tabs.
+ if (this._target.isTabActor) {
+ this.tabClient = this._target.activeTab;
+ }
- let connectTimeline = () => {
- // Don't start up waiting for timeline markers if the server isn't
- // recent enough to emit the markers we're interested in.
- if (this._target.getTrait("documentLoadingMarkers")) {
- this.timelineFront = new TimelineFront(this._target.client,
- this._target.form);
- return this.timelineFront.start({ withDocLoadingEvents: true });
- }
- return undefined;
- };
+ let connectTimeline = () => {
+ // Don't start up waiting for timeline markers if the server isn't
+ // recent enough to emit the markers we're interested in.
+ if (this._target.getTrait("documentLoadingMarkers")) {
+ this.timelineFront = new TimelineFront(this._target.client,
+ this._target.form);
+ return this.timelineFront.start({ withDocLoadingEvents: true });
+ }
+ return undefined;
+ };
- this.webConsoleClient = this._target.activeConsole;
- await connectTimeline();
+ this.webConsoleClient = this._target.activeConsole;
+ await connectTimeline();
- this.TargetEventsHandler.connect();
- this.NetworkEventsHandler.connect();
+ this.TargetEventsHandler.connect();
+ this.NetworkEventsHandler.connect();
- window.emit(EVENTS.CONNECTED);
+ window.emit(EVENTS.CONNECTED);
- this._connection.resolve();
- this._connected = true;
- return undefined;
+ resolve();
+ this._connected = true;
+ });
+ return this._connection;
},
/**
* Disconnects the debugger client and removes event handlers as necessary.
*/
- async disconnect() {
+ disconnect() {
if (this._disconnection) {
- return this._disconnection.promise;
+ return this._disconnection;
}
- this._disconnection = promise.defer();
-
- // Wait for the connection to finish first.
- if (!this.isConnected()) {
- await this._connection.promise;
- }
+ this._disconnection = new Promise(async (resolve) => {
+ // Wait for the connection to finish first.
+ if (!this.isConnected()) {
+ await this._connection;
+ }
- // When debugging local or a remote instance, the connection is closed by
- // the RemoteTarget. The webconsole actor is stopped on disconnect.
- this.tabClient = null;
- this.webConsoleClient = null;
+ // When debugging local or a remote instance, the connection is closed by
+ // the RemoteTarget. The webconsole actor is stopped on disconnect.
+ this.tabClient = null;
+ this.webConsoleClient = null;
- // The timeline front wasn't initialized and started if the server wasn't
- // recent enough to emit the markers we were interested in.
- if (this._target.getTrait("documentLoadingMarkers")) {
- await this.timelineFront.destroy();
- this.timelineFront = null;
- }
+ // The timeline front wasn't initialized and started if the server wasn't
+ // recent enough to emit the markers we were interested in.
+ if (this._target.getTrait("documentLoadingMarkers")) {
+ await this.timelineFront.destroy();
+ this.timelineFront = null;
+ }
- this._disconnection.resolve();
- this._connected = false;
- return undefined;
+ resolve();
+ this._connected = false;
+ });
+ return this._disconnection;
},
/**
* Checks whether the netmonitor connection is active.
* @return boolean
*/
isConnected: function () {
return !!this._connected;
@@ -168,30 +170,30 @@ var NetMonitorController = {
triggerActivity: function (type) {
// Puts the frontend into "standby" (when there's no particular activity).
let standBy = () => {
this._currentActivity = ACTIVITY_TYPE.NONE;
};
// Waits for a series of "navigation start" and "navigation stop" events.
let waitForNavigation = () => {
- let deferred = promise.defer();
- this._target.once("will-navigate", () => {
- this._target.once("navigate", () => {
- deferred.resolve();
+ return new Promise((resolve) => {
+ this._target.once("will-navigate", () => {
+ this._target.once("navigate", () => {
+ resolve();
+ });
});
});
- return deferred.promise;
};
// Reconfigures the tab, optionally triggering a reload.
let reconfigureTab = options => {
- let deferred = promise.defer();
- this._target.activeTab.reconfigure(options, deferred.resolve);
- return deferred.promise;
+ return new Promise((resolve) => {
+ this._target.activeTab.reconfigure(options, resolve);
+ });
};
// Reconfigures the tab and waits for the target to finish navigating.
let reconfigureTabAndWaitForNavigation = options => {
options.performReload = true;
let navigationFinished = waitForNavigation();
return reconfigureTab(options).then(() => navigationFinished);
};
@@ -228,54 +230,54 @@ var NetMonitorController = {
if (type == ACTIVITY_TYPE.DISABLE_CACHE) {
this._currentActivity = type;
return reconfigureTab({
cacheDisabled: true,
performReload: false
}).then(standBy);
}
this._currentActivity = ACTIVITY_TYPE.NONE;
- return promise.reject(new Error("Invalid activity type"));
+ return Promise.reject(new Error("Invalid activity type"));
},
/**
* Selects the specified request in the waterfall and opens the details view.
*
* @param string requestId
* The actor ID of the request to inspect.
* @return object
* A promise resolved once the task finishes.
*/
inspectRequest: function (requestId) {
// Look for the request in the existing ones or wait for it to appear, if
// the network monitor is still loading.
- let deferred = promise.defer();
- let request = null;
- let inspector = function () {
- request = getDisplayedRequestById(gStore.getState(), requestId);
- if (!request) {
- // Reset filters so that the request is visible.
- gStore.dispatch(Actions.toggleRequestFilterType("all"));
+ return new Promise((resolve) => {
+ let request = null;
+ let inspector = function () {
request = getDisplayedRequestById(gStore.getState(), requestId);
- }
+ if (!request) {
+ // Reset filters so that the request is visible.
+ gStore.dispatch(Actions.toggleRequestFilterType("all"));
+ request = getDisplayedRequestById(gStore.getState(), requestId);
+ }
- // If the request was found, select it. Otherwise this function will be
- // called again once new requests arrive.
- if (request) {
- window.off(EVENTS.REQUEST_ADDED, inspector);
- gStore.dispatch(Actions.selectRequest(request.id));
- deferred.resolve();
+ // If the request was found, select it. Otherwise this function will be
+ // called again once new requests arrive.
+ if (request) {
+ window.off(EVENTS.REQUEST_ADDED, inspector);
+ gStore.dispatch(Actions.selectRequest(request.id));
+ resolve();
+ }
+ };
+
+ inspector();
+ if (!request) {
+ window.on(EVENTS.REQUEST_ADDED, inspector);
}
- };
-
- inspector();
- if (!request) {
- window.on(EVENTS.REQUEST_ADDED, inspector);
- }
- return deferred.promise;
+ });
},
/**
* Getter that tells if the server supports sending custom network requests.
* @type boolean
*/
get supportsCustomRequest() {
return this.webConsoleClient &&
--- a/devtools/client/netmonitor/request-list-context-menu.js
+++ b/devtools/client/netmonitor/request-list-context-menu.js
@@ -4,34 +4,30 @@
"use strict";
const Services = require("Services");
const { Curl } = require("devtools/client/shared/curl");
const { gDevTools } = require("devtools/client/framework/devtools");
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
+const { HarExporter } = require("./har/har-exporter");
const { L10N } = require("./l10n");
const {
formDataURI,
getFormDataSections,
getUrlQuery,
parseQueryString,
} = require("./request-utils");
const {
getSelectedRequest,
getSortedRequests,
} = require("./selectors/index");
-loader.lazyRequireGetter(this, "HarExporter",
- "devtools/client/netmonitor/har/har-exporter", true);
-
-loader.lazyServiceGetter(this, "clipboardHelper",
- "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
-
function RequestListContextMenu({
cloneSelectedRequest,
openStatistics,
}) {
this.cloneSelectedRequest = cloneSelectedRequest;
this.openStatistics = openStatistics;
}