Bug 1477597 - Part 4: Add inspect button. r=jdescottes

Differential Revision: https://phabricator.services.mozilla.com/D2765

--HG--
extra : rebase_source : 490aa5f758c8d7bc9a64d2b3a2ffe6a112bb3cb3
This commit is contained in:
Daisuke Akatsuka 2018-08-06 15:20:13 +09:00
parent 37ff44b1ed
commit d26c328974
9 changed files with 73 additions and 15 deletions

View File

@ -11,6 +11,7 @@ const {
CONNECT_RUNTIME_FAILURE,
CONNECT_RUNTIME_START,
CONNECT_RUNTIME_SUCCESS,
DEBUG_TARGETS,
DISCONNECT_RUNTIME_FAILURE,
DISCONNECT_RUNTIME_START,
DISCONNECT_RUNTIME_SUCCESS,
@ -55,6 +56,17 @@ function disconnectRuntime() {
};
}
function inspectDebugTarget(type, id) {
if (type === DEBUG_TARGETS.TAB) {
window.open(`about:devtools-toolbox?type=tab&id=${ id }`);
} else {
console.error(`Failed to inspect the debug target of type: ${ type } id: ${ id }`);
}
// We cancel the redux flow here since the inspection does not need to update the state.
return () => {};
}
function requestTabs() {
return async (dispatch, getState) => {
dispatch({ type: REQUEST_TABS_START });
@ -74,5 +86,6 @@ function requestTabs() {
module.exports = {
connectRuntime,
disconnectRuntime,
inspectDebugTarget,
requestTabs,
};

View File

@ -23,5 +23,6 @@
.page {
padding-block-start: 60px;
padding-inline-end: 40px;
overflow-y: auto;
}

View File

@ -11,18 +11,18 @@
/*
* The current layout of debug target item is
*
* +--------+--------------------+
* | Icon | Information |
* | |+------------------+|
* | || Name ||
* | |+------------------+|
* | || Detail ||
* | |+------------------+|
* +--------+--------------------+
* +--------+-----------------------------+----------------+
* | Icon | Information | Inspect button |
* | |+---------------------------+| |
* | || Name || |
* | |+---------------------------+| |
* | || Detail || |
* | |+---------------------------+| |
* +--------+-----------------------------+----------------+
*/
.debug-target-item {
display: grid;
grid-template-columns: 54px auto;
grid-template-columns: 54px auto max-content;
grid-template-rows: auto auto;
grid-row-gap: 20px;
}
@ -41,3 +41,12 @@
font-size: 20px;
margin-block-end: 2px;
}
.debug-target-item__inspect-button {
height: 36px;
margin-inline-start: 4px;
margin-inline-end: 4px;
min-width: 100px;
padding-inline-start: 20px;
padding-inline-end: 20px;
}

View File

@ -8,18 +8,28 @@ const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const Actions = require("../actions/index");
/**
* This component displays debug target.
*/
class DebugTargetItem extends PureComponent {
static get propTypes() {
return {
dispatch: PropTypes.func.isRequired,
icon: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
};
}
inspect() {
const { dispatch, type, id } = this.props;
dispatch(Actions.inspectDebugTarget(type, id));
}
renderIcon() {
return dom.img({
className: "debug-target-item__icon",
@ -48,6 +58,16 @@ class DebugTargetItem extends PureComponent {
);
}
renderInspectButton() {
return dom.button(
{
onClick: e => this.inspect(),
className: "debug-target-item__inspect-button",
},
"Inspect"
);
}
render() {
return dom.li(
{
@ -55,6 +75,7 @@ class DebugTargetItem extends PureComponent {
},
this.renderIcon(),
this.renderInfo(),
this.renderInspectButton(),
);
}
}

View File

@ -16,12 +16,13 @@ const DebugTargetItem = createFactory(require("./DebugTargetItem"));
class DebugTargetList extends PureComponent {
static get propTypes() {
return {
dispatch: PropTypes.func.isRequired,
targets: PropTypes.arrayOf(PropTypes.Object).isRequired,
};
}
render() {
const { targets } = this.props;
const { dispatch, targets } = this.props;
return dom.ul(
{
@ -29,8 +30,11 @@ class DebugTargetList extends PureComponent {
},
targets.map(target =>
DebugTargetItem({
dispatch,
icon: target.icon,
id: target.id,
name: target.name,
type: target.type,
url: target.url,
})
),

View File

@ -16,18 +16,19 @@ const DebugTargetList = createFactory(require("./DebugTargetList"));
class DebugTargetPane extends PureComponent {
static get propTypes() {
return {
dispatch: PropTypes.func.isRequired,
name: PropTypes.string.isRequired,
targets: PropTypes.arrayOf(PropTypes.Object).isRequired,
};
}
render() {
const { name, targets } = this.props;
const { dispatch, name, targets } = this.props;
return dom.section(
{},
dom.h2({}, name),
DebugTargetList({ targets }),
DebugTargetList({ dispatch, targets }),
);
}
}

View File

@ -17,12 +17,13 @@ const Services = require("Services");
class RuntimePage extends PureComponent {
static get propTypes() {
return {
dispatch: PropTypes.func.isRequired,
tabs: PropTypes.arrayOf(PropTypes.object).isRequired,
};
}
render() {
const { tabs } = this.props;
const { dispatch, tabs } = this.props;
return dom.article(
{
@ -34,6 +35,7 @@ class RuntimePage extends PureComponent {
version: Services.appinfo.version,
}),
DebugTargetPane({
dispatch,
name: "Tabs",
targets: tabs
}),

View File

@ -17,10 +17,14 @@ const actionTypes = {
PAGE_SELECTED: "PAGE_SELECTED",
};
const DEBUG_TARGETS = {
TAB: "TAB",
};
const PAGES = {
THIS_FIREFOX: "this-firefox",
CONNECT: "connect",
};
// flatten constants
module.exports = Object.assign({}, { PAGES }, actionTypes);
module.exports = Object.assign({}, { PAGES }, actionTypes, { DEBUG_TARGETS });

View File

@ -6,6 +6,7 @@
const {
CONNECT_RUNTIME_SUCCESS,
DEBUG_TARGETS,
DISCONNECT_RUNTIME_SUCCESS,
REQUEST_TABS_SUCCESS,
} = require("../constants");
@ -38,12 +39,14 @@ function runtimeReducer(state = RuntimeState(), action) {
function toTabComponentData(tabs) {
return tabs.map(tab => {
const type = DEBUG_TARGETS.TAB;
const id = tab.outerWindowID;
const icon = tab.favicon
? `data:image/png;base64,${ btoa(String.fromCharCode.apply(String, tab.favicon)) }`
: "chrome://devtools/skin/images/globe.svg";
const name = tab.title || tab.url;
const url = tab.url;
return { icon, name, url };
return { type, id, icon, name, url };
});
}