зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1419083 - Add an "Open in sidebar" context menu entry on ObjectInspector. r=nchevobbe
MozReview-Commit-ID: 9a2fBjpZ6zE --HG-- extra : rebase_source : f533989d8f01a4f96133efbc98ef57e31806da46
This commit is contained in:
Родитель
33d26976c8
Коммит
35bbe45a57
|
@ -251,6 +251,12 @@ webconsole.menu.copyObject.accesskey=o
|
|||
webconsole.menu.selectAll.label=Select all
|
||||
webconsole.menu.selectAll.accesskey=A
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.menu.openInSidebar.label)
|
||||
# Label used for a context-menu item displayed for object/variable logs. Clicking on it
|
||||
# opens the webconsole sidebar for the logged variable.
|
||||
webconsole.menu.openInSidebar.label=Open in sidebar
|
||||
webconsole.menu.openInSidebar.accesskey=V
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.clearButton.tooltip)
|
||||
# Label used for the tooltip on the clear logs button in the console top toolbar bar.
|
||||
# Clicking on it will clear the content of the console.
|
||||
|
|
|
@ -1217,6 +1217,7 @@ body #output-container {
|
|||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.webconsole-sidebar-toolbar {
|
||||
|
@ -1228,6 +1229,7 @@ body #output-container {
|
|||
|
||||
.sidebar-contents {
|
||||
grid-row: 2 / 3;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.webconsole-sidebar-toolbar .sidebar-close-button {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"use strict";
|
||||
|
||||
const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui");
|
||||
const { getMessage } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const Services = require("Services");
|
||||
|
||||
const {
|
||||
|
@ -15,7 +16,8 @@ const {
|
|||
PERSIST_TOGGLE,
|
||||
PREFS,
|
||||
SELECT_NETWORK_MESSAGE_TAB,
|
||||
SIDEBAR_TOGGLE,
|
||||
SIDEBAR_CLOSE,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
TIMESTAMPS_TOGGLE,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
|
@ -59,9 +61,26 @@ function initialize() {
|
|||
};
|
||||
}
|
||||
|
||||
function sidebarToggle(show) {
|
||||
function sidebarClose(show) {
|
||||
return {
|
||||
type: SIDEBAR_TOGGLE,
|
||||
type: SIDEBAR_CLOSE,
|
||||
};
|
||||
}
|
||||
|
||||
function showObjectInSidebar(actorId, messageId) {
|
||||
return (dispatch, getState) => {
|
||||
let { parameters } = getMessage(getState(), messageId);
|
||||
if (Array.isArray(parameters)) {
|
||||
for (let parameter of parameters) {
|
||||
if (parameter.actor === actorId) {
|
||||
dispatch({
|
||||
type: SHOW_OBJECT_IN_SIDEBAR,
|
||||
grip: parameter
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -70,6 +89,7 @@ module.exports = {
|
|||
initialize,
|
||||
persistToggle,
|
||||
selectNetworkMessageTab,
|
||||
sidebarToggle,
|
||||
sidebarClose,
|
||||
showObjectInSidebar,
|
||||
timestampsToggle,
|
||||
};
|
||||
|
|
|
@ -32,7 +32,6 @@ class FilterBar extends Component {
|
|||
filterBarVisible: PropTypes.bool.isRequired,
|
||||
persistLogs: PropTypes.bool.isRequired,
|
||||
filteredMessagesCount: PropTypes.object.isRequired,
|
||||
sidebarToggle: PropTypes.bool,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -40,7 +39,6 @@ class FilterBar extends Component {
|
|||
super(props);
|
||||
this.onClickMessagesClear = this.onClickMessagesClear.bind(this);
|
||||
this.onClickFilterBarToggle = this.onClickFilterBarToggle.bind(this);
|
||||
this.onClickSidebarToggle = this.onClickSidebarToggle.bind(this);
|
||||
this.onClickRemoveAllFilters = this.onClickRemoveAllFilters.bind(this);
|
||||
this.onClickRemoveTextFilter = this.onClickRemoveTextFilter.bind(this);
|
||||
this.onSearchInput = this.onSearchInput.bind(this);
|
||||
|
@ -87,10 +85,6 @@ class FilterBar extends Component {
|
|||
this.props.dispatch(actions.filterBarToggle());
|
||||
}
|
||||
|
||||
onClickSidebarToggle() {
|
||||
this.props.dispatch(actions.sidebarToggle());
|
||||
}
|
||||
|
||||
onClickRemoveAllFilters() {
|
||||
this.props.dispatch(actions.defaultFiltersReset());
|
||||
}
|
||||
|
@ -226,7 +220,6 @@ class FilterBar extends Component {
|
|||
filterBarVisible,
|
||||
persistLogs,
|
||||
filteredMessagesCount,
|
||||
sidebarToggle,
|
||||
} = this.props;
|
||||
|
||||
let children = [
|
||||
|
@ -261,13 +254,6 @@ class FilterBar extends Component {
|
|||
onChange: this.onChangePersistToggle,
|
||||
checked: persistLogs,
|
||||
}),
|
||||
sidebarToggle ?
|
||||
dom.button({
|
||||
className: "devtools-button webconsole-sidebar-button",
|
||||
title: l10n.getStr("webconsole.toggleFilterButton.tooltip"),
|
||||
onClick: this.onClickSidebarToggle
|
||||
}, "Toggle Sidebar")
|
||||
: null,
|
||||
)
|
||||
];
|
||||
|
||||
|
@ -298,7 +284,6 @@ function mapStateToProps(state) {
|
|||
filterBarVisible: uiState.filterBarVisible,
|
||||
persistLogs: uiState.persistLogs,
|
||||
filteredMessagesCount: getFilteredMessagesCount(state),
|
||||
sidebarToggle: state.prefs.sidebarToggle,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,22 +14,24 @@ class SideBar extends Component {
|
|||
static get propTypes() {
|
||||
return {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
sidebarVisible: PropTypes.bool
|
||||
sidebarVisible: PropTypes.bool,
|
||||
grip: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onClickSidebarToggle = this.onClickSidebarToggle.bind(this);
|
||||
this.onClickSidebarClose = this.onClickSidebarClose.bind(this);
|
||||
}
|
||||
|
||||
onClickSidebarToggle() {
|
||||
this.props.dispatch(actions.sidebarToggle());
|
||||
onClickSidebarClose() {
|
||||
this.props.dispatch(actions.sidebarClose());
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
sidebarVisible,
|
||||
grip,
|
||||
} = this.props;
|
||||
|
||||
let endPanel = dom.aside({
|
||||
|
@ -40,12 +42,12 @@ class SideBar extends Component {
|
|||
},
|
||||
dom.button({
|
||||
className: "devtools-button sidebar-close-button",
|
||||
onClick: this.onClickSidebarToggle
|
||||
onClick: this.onClickSidebarClose
|
||||
})
|
||||
),
|
||||
dom.aside({
|
||||
className: "sidebar-contents"
|
||||
}, "Sidebar WIP")
|
||||
}, JSON.stringify(grip, null, 2))
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -66,6 +68,7 @@ class SideBar extends Component {
|
|||
function mapStateToProps(state, props) {
|
||||
return {
|
||||
sidebarVisible: state.ui.sidebarVisible,
|
||||
grip: state.ui.gripInSidebar,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ function ConsoleApiCall(props) {
|
|||
indent,
|
||||
timeStamp,
|
||||
timestampsVisible,
|
||||
parameters,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ const actionTypes = {
|
|||
PERSIST_TOGGLE: "PERSIST_TOGGLE",
|
||||
REMOVED_ACTORS_CLEAR: "REMOVED_ACTORS_CLEAR",
|
||||
SELECT_NETWORK_MESSAGE_TAB: "SELECT_NETWORK_MESSAGE_TAB",
|
||||
SIDEBAR_TOGGLE: "SIDEBAR_TOGGLE",
|
||||
SIDEBAR_CLOSE: "SIDEBAR_CLOSE",
|
||||
SHOW_OBJECT_IN_SIDEBAR: "SHOW_OBJECT_IN_SIDEBAR",
|
||||
TIMESTAMPS_TOGGLE: "TIMESTAMPS_TOGGLE",
|
||||
};
|
||||
|
||||
|
|
|
@ -119,11 +119,23 @@ NewConsoleOutputWrapper.prototype = {
|
|||
? messageVariable.textContent : null;
|
||||
|
||||
// Retrieve closes actor id from the DOM.
|
||||
let actorEl = target.closest("[data-link-actor-id]");
|
||||
let actorEl = target.closest("[data-link-actor-id]") ||
|
||||
target.querySelector("[data-link-actor-id]");
|
||||
let actor = actorEl ? actorEl.dataset.linkActorId : null;
|
||||
|
||||
let rootObjectInspector = target.closest(".object-inspector");
|
||||
let rootActor = rootObjectInspector ?
|
||||
rootObjectInspector.querySelector("[data-link-actor-id]") : null;
|
||||
let rootActorId = rootActor ? rootActor.dataset.linkActorId : null;
|
||||
|
||||
let sidebarTogglePref = store.getState().prefs.sidebarToggle;
|
||||
let openSidebar = sidebarTogglePref ? (messageId) => {
|
||||
store.dispatch(actions.showObjectInSidebar(rootActorId, messageId));
|
||||
} : null;
|
||||
|
||||
let menu = createContextMenu(this.jsterm, this.parentNode,
|
||||
{ actor, clipboardText, variableText, message, serviceContainer });
|
||||
{ actor, clipboardText, variableText, message,
|
||||
serviceContainer, openSidebar, rootActorId });
|
||||
|
||||
// Emit the "menu-open" event for testing.
|
||||
menu.once("open", () => this.emit("menu-open"));
|
||||
|
|
|
@ -10,7 +10,8 @@ const {
|
|||
INITIALIZE,
|
||||
PERSIST_TOGGLE,
|
||||
SELECT_NETWORK_MESSAGE_TAB,
|
||||
SIDEBAR_TOGGLE,
|
||||
SIDEBAR_CLOSE,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
TIMESTAMPS_TOGGLE,
|
||||
MESSAGES_CLEAR,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
@ -26,6 +27,7 @@ const UiState = (overrides) => Object.freeze(Object.assign({
|
|||
persistLogs: false,
|
||||
sidebarVisible: false,
|
||||
timestampsVisible: true,
|
||||
gripInSidebar: null
|
||||
}, overrides));
|
||||
|
||||
function ui(state = UiState(), action) {
|
||||
|
@ -38,12 +40,20 @@ function ui(state = UiState(), action) {
|
|||
return Object.assign({}, state, {timestampsVisible: action.visible});
|
||||
case SELECT_NETWORK_MESSAGE_TAB:
|
||||
return Object.assign({}, state, {networkMessageActiveTabId: action.id});
|
||||
case SIDEBAR_TOGGLE:
|
||||
return Object.assign({}, state, {sidebarVisible: !state.sidebarVisible});
|
||||
case SIDEBAR_CLOSE:
|
||||
return Object.assign({}, state, {
|
||||
sidebarVisible: !state.sidebarVisible,
|
||||
gripInSidebar: null
|
||||
});
|
||||
case INITIALIZE:
|
||||
return Object.assign({}, state, {initialized: true});
|
||||
case MESSAGES_CLEAR:
|
||||
return Object.assign({}, state, {sidebarVisible: false});
|
||||
return Object.assign({}, state, {sidebarVisible: false, gripInSidebar: null});
|
||||
case SHOW_OBJECT_IN_SIDEBAR:
|
||||
if (action.grip === state.gripInSidebar) {
|
||||
return state;
|
||||
}
|
||||
return Object.assign({}, state, {sidebarVisible: true, gripInSidebar: action.grip});
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -260,6 +260,7 @@ subsuite = clipboard
|
|||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_webconsole_context_menu_copy_object.js]
|
||||
subsuite = clipboard
|
||||
[browser_webconsole_context_menu_object_in_sidebar.js]
|
||||
[browser_webconsole_context_menu_open_url.js]
|
||||
[browser_webconsole_context_menu_store_as_global.js]
|
||||
[browser_webconsole_csp_ignore_reflected_xss_message.js]
|
||||
|
|
|
@ -63,9 +63,19 @@ add_task(async function () {
|
|||
});
|
||||
|
||||
async function showSidebar(hud) {
|
||||
let toggleButton = hud.ui.document.querySelector(".webconsole-sidebar-button");
|
||||
let onMessage = waitForMessage(hud, "Object");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
|
||||
content.wrappedJSObject.console.log({a: 1});
|
||||
});
|
||||
await onMessage;
|
||||
|
||||
let objectNode = hud.ui.outputNode.querySelector(".object-inspector .objectBox");
|
||||
let wrapper = hud.ui.document.querySelector(".webconsole-output-wrapper");
|
||||
let onSidebarShown = waitForNodeMutation(wrapper, { childList: true });
|
||||
toggleButton.click();
|
||||
|
||||
let contextMenu = await openContextMenu(hud, objectNode);
|
||||
let openInSidebar = contextMenu.querySelector("#console-menu-open-sidebar");
|
||||
openInSidebar.click();
|
||||
await onSidebarShown;
|
||||
await hideContextMenu(hud);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the "Open in sidebar" context menu entry is active for
|
||||
// the correct objects and opens the sidebar when clicked.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI =
|
||||
"data:text/html;charset=utf8," +
|
||||
"<script>console.log({a:1},100,{b:1},'foo',false,null,undefined);</script>";
|
||||
|
||||
add_task(async function () {
|
||||
// Should be removed when sidebar work is complete
|
||||
await pushPref("devtools.webconsole.sidebarToggle", true);
|
||||
|
||||
let hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
let message = findMessage(hud, "foo");
|
||||
let [objectA, objectB] =
|
||||
message.querySelectorAll(".object-inspector .objectBox-object");
|
||||
let number = findMessage(hud, "100", ".objectBox");
|
||||
let string = findMessage(hud, "foo", ".objectBox");
|
||||
let bool = findMessage(hud, "false", ".objectBox");
|
||||
let nullMessage = findMessage(hud, "null", ".objectBox");
|
||||
let undefinedMsg = findMessage(hud, "undefined", ".objectBox");
|
||||
|
||||
info("Showing sidebar for {a:1}");
|
||||
await showSidebarWithContextMenu(hud, objectA, true);
|
||||
|
||||
let sidebarText = hud.ui.document.querySelector(".sidebar-contents").textContent;
|
||||
ok(sidebarText.includes('"a":'), "Sidebar is shown for {a:1}");
|
||||
|
||||
info("Showing sidebar for {a:1} again");
|
||||
await showSidebarWithContextMenu(hud, objectA, false);
|
||||
ok(hud.ui.document.querySelector(".sidebar"),
|
||||
"Sidebar is still shown after clicking on same object");
|
||||
is(hud.ui.document.querySelector(".sidebar-contents").textContent, sidebarText,
|
||||
"Sidebar is not updated after clicking on same object");
|
||||
|
||||
info("Showing sidebar for {b:1}");
|
||||
await showSidebarWithContextMenu(hud, objectB, false);
|
||||
isnot(hud.ui.document.querySelector(".sidebar-contents").textContent, sidebarText,
|
||||
"Sidebar is updated for {b:1}");
|
||||
sidebarText = hud.ui.document.querySelector(".sidebar-contents").textContent;
|
||||
ok(sidebarText.includes('"b":'), "Sidebar contents shown for {b:1}");
|
||||
|
||||
info("Checking context menu entry is disabled for number");
|
||||
let numberContextMenuEnabled = await isContextMenuEntryEnabled(hud, number);
|
||||
ok(!numberContextMenuEnabled, "Context menu entry is disabled for number");
|
||||
|
||||
info("Checking context menu entry is disabled for string");
|
||||
let stringContextMenuEnabled = await isContextMenuEntryEnabled(hud, string);
|
||||
ok(!stringContextMenuEnabled, "Context menu entry is disabled for string");
|
||||
|
||||
info("Checking context menu entry is disabled for bool");
|
||||
let boolContextMenuEnabled = await isContextMenuEntryEnabled(hud, bool);
|
||||
ok(!boolContextMenuEnabled, "Context menu entry is disabled for bool");
|
||||
|
||||
info("Checking context menu entry is disabled for null message");
|
||||
let nullContextMenuEnabled = await isContextMenuEntryEnabled(hud, nullMessage);
|
||||
ok(!nullContextMenuEnabled, "Context menu entry is disabled for nullMessage");
|
||||
|
||||
info("Checking context menu entry is disabled for undefined message");
|
||||
let undefinedContextMenuEnabled = await isContextMenuEntryEnabled(hud, undefinedMsg);
|
||||
ok(!undefinedContextMenuEnabled, "Context menu entry is disabled for undefinedMsg");
|
||||
});
|
||||
|
||||
async function showSidebarWithContextMenu(hud, node, expectMutation) {
|
||||
let wrapper = hud.ui.document.querySelector(".webconsole-output-wrapper");
|
||||
let onSidebarShown = waitForNodeMutation(wrapper, { childList: true });
|
||||
|
||||
let contextMenu = await openContextMenu(hud, node);
|
||||
let openInSidebar = contextMenu.querySelector("#console-menu-open-sidebar");
|
||||
openInSidebar.click();
|
||||
if (expectMutation) {
|
||||
await onSidebarShown;
|
||||
}
|
||||
await hideContextMenu(hud);
|
||||
}
|
||||
|
||||
async function isContextMenuEntryEnabled(hud, node) {
|
||||
let contextMenu = await openContextMenu(hud, node);
|
||||
let openInSidebar = contextMenu.querySelector("#console-menu-open-sidebar");
|
||||
let enabled = !openInSidebar.attributes.disabled;
|
||||
await hideContextMenu(hud);
|
||||
return enabled;
|
||||
}
|
|
@ -7,6 +7,8 @@ const expect = require("expect");
|
|||
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
const { getAllMessagesById } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const { stubPackets, stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
||||
describe("Testing UI", () => {
|
||||
let store;
|
||||
|
@ -17,16 +19,16 @@ describe("Testing UI", () => {
|
|||
|
||||
describe("Toggle sidebar", () => {
|
||||
it("sidebar is toggled on and off", () => {
|
||||
store.dispatch(actions.sidebarToggle());
|
||||
store.dispatch(actions.sidebarClose());
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
store.dispatch(actions.sidebarToggle());
|
||||
store.dispatch(actions.sidebarClose());
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Hide sidebar on clear", () => {
|
||||
it("sidebar is hidden on clear", () => {
|
||||
store.dispatch(actions.sidebarToggle());
|
||||
store.dispatch(actions.sidebarClose());
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
store.dispatch(actions.messagesClear());
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(false);
|
||||
|
@ -34,4 +36,64 @@ describe("Testing UI", () => {
|
|||
expect(store.getState().ui.sidebarVisible).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Show object in sidebar", () => {
|
||||
it("sidebar is shown with correct object", () => {
|
||||
const packet = stubPackets.get("inspect({a: 1})");
|
||||
const message = stubPreparedMessages.get("inspect({a: 1})");
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const messages = getAllMessagesById(store.getState());
|
||||
const actorId = message.parameters[0].actor;
|
||||
const messageId = messages.first().id;
|
||||
store.dispatch(actions.showObjectInSidebar(actorId, messageId));
|
||||
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]);
|
||||
});
|
||||
|
||||
it("sidebar is not updated for the same object", () => {
|
||||
const packet = stubPackets.get("inspect({a: 1})");
|
||||
const message = stubPreparedMessages.get("inspect({a: 1})");
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const messages = getAllMessagesById(store.getState());
|
||||
const actorId = message.parameters[0].actor;
|
||||
const messageId = messages.first().id;
|
||||
store.dispatch(actions.showObjectInSidebar(actorId, messageId));
|
||||
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]);
|
||||
let state = store.getState().ui;
|
||||
|
||||
store.dispatch(actions.showObjectInSidebar(actorId, messageId));
|
||||
expect(store.getState().ui).toEqual(state);
|
||||
});
|
||||
|
||||
it("sidebar shown and updated for new object", () => {
|
||||
const packet = stubPackets.get("inspect({a: 1})");
|
||||
const message = stubPreparedMessages.get("inspect({a: 1})");
|
||||
store.dispatch(actions.messageAdd(packet));
|
||||
|
||||
const messages = getAllMessagesById(store.getState());
|
||||
const actorId = message.parameters[0].actor;
|
||||
const messageId = messages.first().id;
|
||||
store.dispatch(actions.showObjectInSidebar(actorId, messageId));
|
||||
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]);
|
||||
|
||||
const newPacket = stubPackets.get("new Date(0)");
|
||||
const newMessage = stubPreparedMessages.get("new Date(0)");
|
||||
store.dispatch(actions.messageAdd(newPacket));
|
||||
|
||||
const newMessages = getAllMessagesById(store.getState());
|
||||
const newActorId = newMessage.parameters[0].actor;
|
||||
const newMessageId = newMessages.last().id;
|
||||
store.dispatch(actions.showObjectInSidebar(newActorId, newMessageId));
|
||||
|
||||
expect(store.getState().ui.sidebarVisible).toEqual(true);
|
||||
expect(store.getState().ui.gripInSidebar).toEqual(newMessage.parameters[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,13 +32,18 @@ const { l10n } = require("devtools/client/webconsole/new-console-output/utils/me
|
|||
* - {Object} message (optional) message object containing metadata such as:
|
||||
* - {String} source
|
||||
* - {String} request
|
||||
* - {Function} openSidebar (optional) function that will open the object
|
||||
* inspector sidebar
|
||||
* - {String} rootActorId (optional) actor id for the root object being clicked on
|
||||
*/
|
||||
function createContextMenu(jsterm, parentNode, {
|
||||
actor,
|
||||
clipboardText,
|
||||
variableText,
|
||||
message,
|
||||
serviceContainer
|
||||
serviceContainer,
|
||||
openSidebar,
|
||||
rootActorId,
|
||||
}) {
|
||||
let win = parentNode.ownerDocument.defaultView;
|
||||
let selection = win.getSelection();
|
||||
|
@ -165,6 +170,17 @@ function createContextMenu(jsterm, parentNode, {
|
|||
},
|
||||
}));
|
||||
|
||||
// Open object in sidebar.
|
||||
if (openSidebar) {
|
||||
menu.append(new MenuItem({
|
||||
id: "console-menu-open-sidebar",
|
||||
label: l10n.getStr("webconsole.menu.openInSidebar.label"),
|
||||
acesskey: l10n.getStr("webconsole.menu.openInSidebar.accesskey"),
|
||||
disabled: !rootActorId,
|
||||
click: () => openSidebar(message.messageId),
|
||||
}));
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче