Bug 1456129 - Extend HAR toolbar with import; r=davidwalsh

MozReview-Commit-ID: 2g5sVon7xpk

--HG--
extra : rebase_source : 8044e25d9af8367c430ad1e0b3ebeaba14993a47
This commit is contained in:
Jan Odvarko 2018-04-26 19:28:10 +02:00
parent b6d8525bcf
commit 5e3f95c227
7 changed files with 112 additions and 21 deletions

View File

@ -959,6 +959,26 @@ netmonitor.context.saveAllAsHar=Save All As HAR
# for the Save All As HAR menu item displayed in the context menu for a network panel
netmonitor.context.saveAllAsHar.accesskey=H
# LOCALIZATION NOTE (netmonitor.context.importHar): This is the label displayed
# on the context menu that imports HAR files
netmonitor.context.importHar=Import…
# LOCALIZATION NOTE (netmonitor.context.importHar.accesskey): This is the access key
# for the Import HAR menu item displayed in the context menu for a network panel
netmonitor.context.importHar.accesskey=I
# LOCALIZATION NOTE (netmonitor.har.importHarDialogTitle): This is a label
# used for import file open dialog
netmonitor.har.importHarDialogTitle=Import HAR File
# LOCALIZATION NOTE (netmonitor.har.importDialogHARFilter):
# This string is displayed as a filter for importing HAR file
netmonitor.har.importDialogHARFilter=HAR Files
# LOCALIZATION NOTE (netmonitor.har.importDialogAllFilter):
# This string is displayed as a filter for importing HAR file
netmonitor.har.importDialogAllFilter=All Files
# LOCALIZATION NOTE (netmonitor.context.editAndResend): This is the label displayed
# on the context menu that opens a form to edit and resend the currently
# displayed request

View File

@ -64,7 +64,9 @@ class App extends Component {
openSplitConsole,
},
MonitorPanel({
actions,
connector,
openSplitConsole,
sourceMapService,
openLink,
})

View File

@ -10,9 +10,8 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const { L10N } = require("../utils/l10n");
loader.lazyGetter(this, "HarImporter", function() {
return require("../har/har-importer").HarImporter;
});
loader.lazyRequireGetter(this, "HarMenuUtils",
"devtools/client/netmonitor/src/har/har-menu-utils", true);
const { div } = dom;
@ -70,6 +69,11 @@ class DropHarHandler extends Component {
return;
}
let {
actions,
openSplitConsole,
} = this.props;
// Import only the first dragged file for now
// See also:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1438792
@ -77,27 +81,12 @@ class DropHarHandler extends Component {
let file = files[0];
readFile(file).then(har => {
if (har) {
this.appendPreview(har);
HarMenuUtils.appendPreview(har, actions, openSplitConsole);
}
});
}
}
appendPreview(har) {
let {
openSplitConsole
} = this.props;
try {
let importer = new HarImporter(this.props.actions);
importer.import(har);
} catch (err) {
if (openSplitConsole) {
openSplitConsole("Error while processing HAR file: " + err.message);
}
}
}
// Rendering
render() {

View File

@ -42,10 +42,13 @@ const MediaQuerySingleRow = window.matchMedia("(min-width: 920px)");
class MonitorPanel extends Component {
static get propTypes() {
return {
actions: PropTypes.object.isRequired,
connector: PropTypes.object.isRequired,
isEmpty: PropTypes.bool.isRequired,
networkDetailsOpen: PropTypes.bool.isRequired,
openNetworkDetails: PropTypes.func.isRequired,
// Callback for opening split console.
openSplitConsole: PropTypes.func,
onNetworkDetailsResized: PropTypes.func.isRequired,
request: PropTypes.object,
selectedRequestVisible: PropTypes.bool.isRequired,
@ -118,10 +121,12 @@ class MonitorPanel extends Component {
render() {
let {
actions,
connector,
isEmpty,
networkDetailsOpen,
openLink,
openSplitConsole,
sourceMapService,
} = this.props;
@ -133,7 +138,9 @@ class MonitorPanel extends Component {
return (
div({ className: "monitor-panel" },
Toolbar({
actions,
connector,
openSplitConsole,
singleRow: this.state.isSingleRow,
}),
SplitBox({

View File

@ -58,6 +58,7 @@ loader.lazyRequireGetter(this, "HarMenuUtils", "devtools/client/netmonitor/src/h
class Toolbar extends Component {
static get propTypes() {
return {
actions: PropTypes.object.isRequired,
connector: PropTypes.object.isRequired,
toggleRecording: PropTypes.func.isRequired,
recording: PropTypes.bool.isRequired,
@ -77,6 +78,8 @@ class Toolbar extends Component {
// Set to true if there is enough horizontal space
// and the toolbar needs just one row.
singleRow: PropTypes.bool.isRequired,
// Callback for opening split console.
openSplitConsole: PropTypes.func,
};
}
@ -274,12 +277,23 @@ class Toolbar extends Component {
showHarMenu(menuButton) {
const {
actions,
connector,
displayedRequests
displayedRequests,
openSplitConsole,
} = this.props;
let menuItems = [];
menuItems.push({
id: "request-list-context-import-har",
label: L10N.getStr("netmonitor.context.importHar"),
accesskey: L10N.getStr("netmonitor.context.importHar.accesskey"),
click: () => HarMenuUtils.openHarFile(actions, openSplitConsole),
});
menuItems.push("-");
menuItems.push({
id: "request-list-context-save-all-as-har",
label: L10N.getStr("netmonitor.context.saveAllAsHar"),

View File

@ -6,7 +6,14 @@
"use strict";
loader.lazyRequireGetter(this, "HarExporter", "devtools/client/netmonitor/src/har/har-exporter", true);
const { L10N } = require("../utils/l10n");
loader.lazyRequireGetter(this, "HarExporter",
"devtools/client/netmonitor/src/har/har-exporter", true);
loader.lazyGetter(this, "HarImporter", function() {
return require("../har/har-importer").HarImporter;
});
/**
* Helper object with HAR related context menu actions.
@ -30,6 +37,42 @@ var HarMenuUtils = {
return HarExporter.save(this.getDefaultHarOptions(requests, connector));
},
/**
* Import HAR file and preview its content in the Network panel.
*/
openHarFile(actions, openSplitConsole) {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, L10N.getStr("netmonitor.har.importHarDialogTitle"),
Ci.nsIFilePicker.modeOpen);
// Append file filters
fp.appendFilter(L10N.getStr("netmonitor.har.importDialogHARFilter"), "*.har");
fp.appendFilter(L10N.getStr("netmonitor.har.importDialogAllFilter"), "*.*");
fp.open(rv => {
if (rv == Ci.nsIFilePicker.returnOK) {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(fp.file.path);
readFile(file).then(har => {
if (har) {
this.appendPreview(har, actions, openSplitConsole);
}
});
}
});
},
appendPreview(har, actions, openSplitConsole) {
try {
let importer = new HarImporter(actions);
importer.import(har);
} catch (err) {
if (openSplitConsole) {
openSplitConsole("Error while processing HAR file: " + err.message);
}
}
},
getDefaultHarOptions(requests, connector) {
return {
connector: connector,
@ -38,5 +81,17 @@ var HarMenuUtils = {
},
};
// Helpers
function readFile(file) {
return new Promise(resolve => {
const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
OS.File.read(file.path).then(data => {
let decoder = new TextDecoder();
resolve(decoder.decode(data));
});
});
}
// Exports from this module
exports.HarMenuUtils = HarMenuUtils;

View File

@ -24,6 +24,10 @@ function showMenu(items, options) {
// Build the menu object from provided menu items.
let menu = new Menu();
items.forEach((item) => {
if (item == "-") {
item = { type: "separator" };
}
let menuItem = new MenuItem(item);
let subItems = item.submenu;