123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821 |
- /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
- /* 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 window, document, NetMonitorView, gStore, Actions */
- /* exported loader */
- "use strict";
- var { utils: Cu } = Components;
- // Descriptions for what this frontend is currently doing.
- const ACTIVITY_TYPE = {
- // Standing by and handling requests normally.
- NONE: 0,
- // Forcing the target to reload with cache enabled or disabled.
- RELOAD: {
- WITH_CACHE_ENABLED: 1,
- WITH_CACHE_DISABLED: 2,
- WITH_CACHE_DEFAULT: 3
- },
- // Enabling or disabling the cache without triggering a reload.
- ENABLE_CACHE: 3,
- DISABLE_CACHE: 4
- };
- var BrowserLoaderModule = {};
- Cu.import("resource://devtools/client/shared/browser-loader.js", BrowserLoaderModule);
- var { loader, require } = BrowserLoaderModule.BrowserLoader({
- baseURI: "resource://devtools/client/netmonitor/",
- window
- });
- const promise = require("promise");
- const Services = require("Services");
- /* eslint-disable mozilla/reject-some-requires */
- const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
- const EventEmitter = require("devtools/shared/event-emitter");
- const Editor = require("devtools/client/sourceeditor/editor");
- const {TimelineFront} = require("devtools/shared/fronts/timeline");
- const {Task} = require("devtools/shared/task");
- const {Prefs} = require("./prefs");
- const {EVENTS} = require("./events");
- const Actions = require("./actions/index");
- XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
- XPCOMUtils.defineConstant(this, "ACTIVITY_TYPE", ACTIVITY_TYPE);
- XPCOMUtils.defineConstant(this, "Editor", Editor);
- XPCOMUtils.defineConstant(this, "Prefs", Prefs);
- XPCOMUtils.defineLazyModuleGetter(this, "Chart",
- "resource://devtools/client/shared/widgets/Chart.jsm");
- XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
- "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
- Object.defineProperty(this, "NetworkHelper", {
- get: function () {
- return require("devtools/shared/webconsole/network-helper");
- },
- configurable: true,
- enumerable: true
- });
- /**
- * Object defining the network monitor controller components.
- */
- var NetMonitorController = {
- /**
- * Initializes the view and connects the monitor client.
- *
- * @return object
- * A promise that is resolved when the monitor finishes startup.
- */
- startupNetMonitor: Task.async(function* () {
- if (this._startup) {
- return this._startup.promise;
- }
- this._startup = promise.defer();
- {
- NetMonitorView.initialize();
- yield this.connect();
- }
- this._startup.resolve();
- return undefined;
- }),
- /**
- * Destroys the view and disconnects the monitor client from the server.
- *
- * @return object
- * A promise that is resolved when the monitor finishes shutdown.
- */
- shutdownNetMonitor: Task.async(function* () {
- if (this._shutdown) {
- return this._shutdown.promise;
- }
- this._shutdown = promise.defer();
- {
- NetMonitorView.destroy();
- this.TargetEventsHandler.disconnect();
- this.NetworkEventsHandler.disconnect();
- yield this.disconnect();
- }
- this._shutdown.resolve();
- return undefined;
- }),
- /**
- * 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.
- */
- connect: Task.async(function* () {
- if (this._connection) {
- return this._connection.promise;
- }
- 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;
- }
- 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;
- yield connectTimeline();
- this.TargetEventsHandler.connect();
- this.NetworkEventsHandler.connect();
- window.emit(EVENTS.CONNECTED);
- this._connection.resolve();
- this._connected = true;
- return undefined;
- }),
- /**
- * Disconnects the debugger client and removes event handlers as necessary.
- */
- disconnect: Task.async(function* () {
- if (this._disconnection) {
- return this._disconnection.promise;
- }
- this._disconnection = promise.defer();
- // Wait for the connection to finish first.
- if (!this.isConnected()) {
- yield this._connection.promise;
- }
- // 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")) {
- yield this.timelineFront.destroy();
- this.timelineFront = null;
- }
- this._disconnection.resolve();
- this._connected = false;
- return undefined;
- }),
- /**
- * Checks whether the netmonitor connection is active.
- * @return boolean
- */
- isConnected: function () {
- return !!this._connected;
- },
- /**
- * Gets the activity currently performed by the frontend.
- * @return number
- */
- getCurrentActivity: function () {
- return this._currentActivity || ACTIVITY_TYPE.NONE;
- },
- /**
- * Triggers a specific "activity" to be performed by the frontend.
- * This can be, for example, triggering reloads or enabling/disabling cache.
- *
- * @param number type
- * The activity type. See the ACTIVITY_TYPE const.
- * @return object
- * A promise resolved once the activity finishes and the frontend
- * is back into "standby" mode.
- */
- 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 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;
- };
- // 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);
- };
- if (type == ACTIVITY_TYPE.RELOAD.WITH_CACHE_DEFAULT) {
- return reconfigureTabAndWaitForNavigation({}).then(standBy);
- }
- if (type == ACTIVITY_TYPE.RELOAD.WITH_CACHE_ENABLED) {
- this._currentActivity = ACTIVITY_TYPE.ENABLE_CACHE;
- this._target.once("will-navigate", () => {
- this._currentActivity = type;
- });
- return reconfigureTabAndWaitForNavigation({
- cacheDisabled: false,
- performReload: true
- }).then(standBy);
- }
- if (type == ACTIVITY_TYPE.RELOAD.WITH_CACHE_DISABLED) {
- this._currentActivity = ACTIVITY_TYPE.DISABLE_CACHE;
- this._target.once("will-navigate", () => {
- this._currentActivity = type;
- });
- return reconfigureTabAndWaitForNavigation({
- cacheDisabled: true,
- performReload: true
- }).then(standBy);
- }
- if (type == ACTIVITY_TYPE.ENABLE_CACHE) {
- this._currentActivity = type;
- return reconfigureTab({
- cacheDisabled: false,
- performReload: false
- }).then(standBy);
- }
- 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"));
- },
- /**
- * 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 () {
- let predicate = i => i.value === requestId;
- request = NetMonitorView.RequestsMenu.getItemForPredicate(predicate);
- if (!request) {
- // Reset filters so that the request is visible.
- gStore.dispatch(Actions.toggleFilterType("all"));
- request = NetMonitorView.RequestsMenu.getItemForPredicate(predicate);
- }
- // 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);
- NetMonitorView.RequestsMenu.selectedItem = request;
- deferred.resolve();
- }
- };
- 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 &&
- (this.webConsoleClient.traits.customNetworkRequest ||
- !this._target.isApp);
- },
- /**
- * Getter that tells if the server includes the transferred (compressed /
- * encoded) response size.
- * @type boolean
- */
- get supportsTransferredResponseSize() {
- return this.webConsoleClient &&
- this.webConsoleClient.traits.transferredResponseSize;
- },
- /**
- * Getter that tells if the server can do network performance statistics.
- * @type boolean
- */
- get supportsPerfStats() {
- return this.tabClient &&
- (this.tabClient.traits.reconfigure || !this._target.isApp);
- },
- /**
- * Open a given source in Debugger
- */
- viewSourceInDebugger(sourceURL, sourceLine) {
- return this._toolbox.viewSourceInDebugger(sourceURL, sourceLine);
- }
- };
- /**
- * Functions handling target-related lifetime events.
- */
- function TargetEventsHandler() {
- this._onTabNavigated = this._onTabNavigated.bind(this);
- this._onTabDetached = this._onTabDetached.bind(this);
- }
- TargetEventsHandler.prototype = {
- get target() {
- return NetMonitorController._target;
- },
- /**
- * Listen for events emitted by the current tab target.
- */
- connect: function () {
- dumpn("TargetEventsHandler is connecting...");
- this.target.on("close", this._onTabDetached);
- this.target.on("navigate", this._onTabNavigated);
- this.target.on("will-navigate", this._onTabNavigated);
- },
- /**
- * Remove events emitted by the current tab target.
- */
- disconnect: function () {
- if (!this.target) {
- return;
- }
- dumpn("TargetEventsHandler is disconnecting...");
- this.target.off("close", this._onTabDetached);
- this.target.off("navigate", this._onTabNavigated);
- this.target.off("will-navigate", this._onTabNavigated);
- },
- /**
- * Called for each location change in the monitored tab.
- *
- * @param string type
- * Packet type.
- * @param object packet
- * Packet received from the server.
- */
- _onTabNavigated: function (type, packet) {
- switch (type) {
- case "will-navigate": {
- // Reset UI.
- if (!Services.prefs.getBoolPref("devtools.webconsole.persistlog")) {
- NetMonitorView.RequestsMenu.reset();
- NetMonitorView.Sidebar.toggle(false);
- } else {
- // If the log is persistent, just clear some informations.
- NetMonitorView.RequestsMenu.resetNotPersistent();
- }
- // Switch to the default network traffic inspector view.
- if (NetMonitorController.getCurrentActivity() == ACTIVITY_TYPE.NONE) {
- NetMonitorView.showNetworkInspectorView();
- }
- // Clear any accumulated markers.
- NetMonitorController.NetworkEventsHandler.clearMarkers();
- gStore.dispatch(Actions.clearTimingMarkers());
- window.emit(EVENTS.TARGET_WILL_NAVIGATE);
- break;
- }
- case "navigate": {
- window.emit(EVENTS.TARGET_DID_NAVIGATE);
- break;
- }
- }
- },
- /**
- * Called when the monitored tab is closed.
- */
- _onTabDetached: function () {
- NetMonitorController.shutdownNetMonitor();
- }
- };
- /**
- * Functions handling target network events.
- */
- function NetworkEventsHandler() {
- this._markers = [];
- this._onNetworkEvent = this._onNetworkEvent.bind(this);
- this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
- this._onDocLoadingMarker = this._onDocLoadingMarker.bind(this);
- 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);
- }
- NetworkEventsHandler.prototype = {
- get client() {
- return NetMonitorController._target.client;
- },
- get webConsoleClient() {
- return NetMonitorController.webConsoleClient;
- },
- get timelineFront() {
- return NetMonitorController.timelineFront;
- },
- get firstDocumentDOMContentLoadedTimestamp() {
- let marker = this._markers.filter(e => {
- return e.name == "document::DOMContentLoaded";
- })[0];
- return marker ? marker.unixTime / 1000 : -1;
- },
- get firstDocumentLoadTimestamp() {
- let marker = this._markers.filter(e => e.name == "document::Load")[0];
- return marker ? marker.unixTime / 1000 : -1;
- },
- /**
- * Connect to the current target client.
- */
- connect: function () {
- dumpn("NetworkEventsHandler is connecting...");
- this.webConsoleClient.on("networkEvent", this._onNetworkEvent);
- this.webConsoleClient.on("networkEventUpdate", this._onNetworkEventUpdate);
- if (this.timelineFront) {
- this.timelineFront.on("doc-loading", this._onDocLoadingMarker);
- }
- this._displayCachedEvents();
- },
- /**
- * Disconnect from the client.
- */
- disconnect: function () {
- if (!this.client) {
- return;
- }
- dumpn("NetworkEventsHandler is disconnecting...");
- this.webConsoleClient.off("networkEvent", this._onNetworkEvent);
- this.webConsoleClient.off("networkEventUpdate", this._onNetworkEventUpdate);
- if (this.timelineFront) {
- this.timelineFront.off("doc-loading", this._onDocLoadingMarker);
- }
- },
- /**
- * Display any network events already in the cache.
- */
- _displayCachedEvents: function () {
- for (let cachedEvent of this.webConsoleClient.getNetworkEvents()) {
- // First add the request to the timeline.
- this._onNetworkEvent("networkEvent", cachedEvent);
- // Then replay any updates already received.
- for (let update of cachedEvent.updates) {
- this._onNetworkEventUpdate("networkEventUpdate", {
- packet: {
- updateType: update
- },
- networkInfo: cachedEvent
- });
- }
- }
- },
- /**
- * The "DOMContentLoaded" and "Load" events sent by the timeline actor.
- * @param object marker
- */
- _onDocLoadingMarker: function (marker) {
- window.emit(EVENTS.TIMELINE_EVENT, marker);
- this._markers.push(marker);
- gStore.dispatch(Actions.addTimingMarker(marker));
- },
- /**
- * The "networkEvent" message type handler.
- *
- * @param string type
- * Message type.
- * @param object networkInfo
- * The network request information.
- */
- _onNetworkEvent: function (type, networkInfo) {
- let { actor,
- startedDateTime,
- request: { method, url },
- isXHR,
- cause,
- fromCache,
- fromServiceWorker
- } = networkInfo;
- NetMonitorView.RequestsMenu.addRequest(
- actor, startedDateTime, method, url, isXHR, cause, fromCache,
- fromServiceWorker
- );
- window.emit(EVENTS.NETWORK_EVENT, actor);
- },
- /**
- * The "networkEventUpdate" message type handler.
- *
- * @param string type
- * Message type.
- * @param object packet
- * The message received from the server.
- * @param object networkInfo
- * The network request information.
- */
- _onNetworkEventUpdate: function (type, { packet, networkInfo }) {
- let { actor } = networkInfo;
- switch (packet.updateType) {
- case "requestHeaders":
- this.webConsoleClient.getRequestHeaders(actor, this._onRequestHeaders);
- window.emit(EVENTS.UPDATING_REQUEST_HEADERS, actor);
- break;
- case "requestCookies":
- this.webConsoleClient.getRequestCookies(actor, this._onRequestCookies);
- window.emit(EVENTS.UPDATING_REQUEST_COOKIES, actor);
- break;
- case "requestPostData":
- this.webConsoleClient.getRequestPostData(actor,
- this._onRequestPostData);
- window.emit(EVENTS.UPDATING_REQUEST_POST_DATA, actor);
- break;
- case "securityInfo":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
- securityState: networkInfo.securityInfo,
- });
- this.webConsoleClient.getSecurityInfo(actor, this._onSecurityInfo);
- window.emit(EVENTS.UPDATING_SECURITY_INFO, actor);
- break;
- case "responseHeaders":
- this.webConsoleClient.getResponseHeaders(actor,
- this._onResponseHeaders);
- window.emit(EVENTS.UPDATING_RESPONSE_HEADERS, actor);
- break;
- case "responseCookies":
- this.webConsoleClient.getResponseCookies(actor,
- this._onResponseCookies);
- window.emit(EVENTS.UPDATING_RESPONSE_COOKIES, actor);
- break;
- case "responseStart":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
- httpVersion: networkInfo.response.httpVersion,
- remoteAddress: networkInfo.response.remoteAddress,
- remotePort: networkInfo.response.remotePort,
- status: networkInfo.response.status,
- statusText: networkInfo.response.statusText,
- headersSize: networkInfo.response.headersSize
- });
- window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor);
- break;
- case "responseContent":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
- contentSize: networkInfo.response.bodySize,
- transferredSize: networkInfo.response.transferredSize,
- mimeType: networkInfo.response.content.mimeType
- });
- this.webConsoleClient.getResponseContent(actor,
- this._onResponseContent);
- window.emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor);
- break;
- case "eventTimings":
- NetMonitorView.RequestsMenu.updateRequest(actor, {
- totalTime: networkInfo.totalTime
- });
- this.webConsoleClient.getEventTimings(actor, this._onEventTimings);
- window.emit(EVENTS.UPDATING_EVENT_TIMINGS, actor);
- break;
- }
- },
- /**
- * Handles additional information received for a "requestHeaders" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onRequestHeaders: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- requestHeaders: response
- }, () => {
- window.emit(EVENTS.RECEIVED_REQUEST_HEADERS, response.from);
- });
- },
- /**
- * Handles additional information received for a "requestCookies" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onRequestCookies: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- requestCookies: response
- }, () => {
- window.emit(EVENTS.RECEIVED_REQUEST_COOKIES, response.from);
- });
- },
- /**
- * Handles additional information received for a "requestPostData" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onRequestPostData: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- requestPostData: response
- }, () => {
- window.emit(EVENTS.RECEIVED_REQUEST_POST_DATA, response.from);
- });
- },
- /**
- * Handles additional information received for a "securityInfo" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onSecurityInfo: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- securityInfo: response.securityInfo
- }, () => {
- window.emit(EVENTS.RECEIVED_SECURITY_INFO, response.from);
- });
- },
- /**
- * Handles additional information received for a "responseHeaders" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onResponseHeaders: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- responseHeaders: response
- }, () => {
- window.emit(EVENTS.RECEIVED_RESPONSE_HEADERS, response.from);
- });
- },
- /**
- * Handles additional information received for a "responseCookies" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onResponseCookies: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- responseCookies: response
- }, () => {
- window.emit(EVENTS.RECEIVED_RESPONSE_COOKIES, response.from);
- });
- },
- /**
- * Handles additional information received for a "responseContent" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onResponseContent: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- responseContent: response
- }, () => {
- window.emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from);
- });
- },
- /**
- * Handles additional information received for a "eventTimings" packet.
- *
- * @param object response
- * The message received from the server.
- */
- _onEventTimings: function (response) {
- NetMonitorView.RequestsMenu.updateRequest(response.from, {
- eventTimings: response
- }, () => {
- window.emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from);
- });
- },
- /**
- * Clears all accumulated markers.
- */
- clearMarkers: function () {
- this._markers.length = 0;
- },
- /**
- * Fetches the full text of a LongString.
- *
- * @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.
- * @return object Promise
- * A promise that is resolved when the full string contents
- * are available, or rejected if something goes wrong.
- */
- getString: function (stringGrip) {
- return this.webConsoleClient.getString(stringGrip);
- }
- };
- /**
- * Returns true if this is document is in RTL mode.
- * @return boolean
- */
- XPCOMUtils.defineLazyGetter(window, "isRTL", function () {
- return window.getComputedStyle(document.documentElement, null)
- .direction == "rtl";
- });
- /**
- * Convenient way of emitting events from the panel window.
- */
- EventEmitter.decorate(this);
- /**
- * Preliminary setup for the NetMonitorController object.
- */
- NetMonitorController.TargetEventsHandler = new TargetEventsHandler();
- NetMonitorController.NetworkEventsHandler = new NetworkEventsHandler();
- /**
- * Export some properties to the global scope for easier access.
- */
- Object.defineProperties(window, {
- "gNetwork": {
- get: function () {
- return NetMonitorController.NetworkEventsHandler;
- },
- configurable: true
- }
- });
- /**
- * Helper method for debugging.
- * @param string
- */
- function dumpn(str) {
- if (wantLogging) {
- dump("NET-FRONTEND: " + str + "\n");
- }
- }
- var wantLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|