Skip to content

Commit added98

Browse files
jasonLastercodehag
authored andcommitted
Improve preview (firefox-devtools#3749)
* don't show loading preview * Extract Preview logic * minor nit
1 parent 23526da commit added98

17 files changed

Lines changed: 363 additions & 135 deletions

File tree

src/actions/ast.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
getSelectedLocation,
77
getSelectedSource,
88
getSelectedFrame,
9-
getSelection
9+
getPreview
1010
} from "../selectors";
1111

1212
import { PROMISE } from "../utils/redux/middleware/promise";
@@ -66,9 +66,9 @@ export function setOutOfScopeLocations() {
6666
};
6767
}
6868

69-
export function clearSelection() {
69+
export function clearPreview() {
7070
return ({ dispatch, getState, client }: ThunkArgs) => {
71-
const currentSelection = getSelection(getState());
71+
const currentSelection = getPreview(getState());
7272
if (!currentSelection) {
7373
return;
7474
}
@@ -96,19 +96,19 @@ function findBestMatch(symbols, tokenPos, token) {
9696
}, {});
9797
}
9898

99-
export function setSelection(
99+
export function setPreview(
100100
token: string,
101101
tokenPos: AstLocation,
102102
cursorPos: any
103103
) {
104104
return async ({ dispatch, getState, client }: ThunkArgs) => {
105-
const currentSelection = getSelection(getState());
105+
const currentSelection = getPreview(getState());
106106
if (currentSelection && currentSelection.updating) {
107107
return;
108108
}
109109

110110
await dispatch({
111-
type: "SET_SELECTION",
111+
type: "SET_PREVIEW",
112112
[PROMISE]: (async function() {
113113
const source = getSelectedSource(getState());
114114
const _symbols = await parser.getSymbols(source.toJS());

src/actions/tests/__snapshots__/ast.spec.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Array [
4040
]
4141
`;
4242

43-
exports[`ast setSelection member expression 1`] = `
43+
exports[`ast setPreview member expression 1`] = `
4444
Object {
4545
"cursorPos": undefined,
4646
"expression": "this.bazz",
@@ -66,7 +66,7 @@ Object {
6666
}
6767
`;
6868

69-
exports[`ast setSelection this 1`] = `
69+
exports[`ast setPreview this 1`] = `
7070
Object {
7171
"cursorPos": undefined,
7272
"expression": "this",

src/actions/tests/ast.spec.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ describe("ast", () => {
101101
});
102102
});
103103

104-
describe("setSelection", () => {
104+
describe("setPreview", () => {
105105
let dispatch = undefined;
106106
let getState = undefined;
107107

@@ -123,15 +123,15 @@ describe("ast", () => {
123123
});
124124

125125
it("member expression", async () => {
126-
await dispatch(actions.setSelection("bazz", { line: 1, column: 34 }));
127-
const selection = selectors.getSelection(getState());
128-
expect(selection).toMatchSnapshot();
126+
await dispatch(actions.setPreview("bazz", { line: 1, column: 34 }));
127+
const preview = selectors.getPreview(getState());
128+
expect(preview).toMatchSnapshot();
129129
});
130130

131131
it("this", async () => {
132-
await dispatch(actions.setSelection("this", { line: 1, column: 30 }));
133-
const selection = selectors.getSelection(getState());
134-
expect(selection).toMatchSnapshot();
132+
await dispatch(actions.setPreview("this", { line: 1, column: 30 }));
133+
const preview = selectors.getPreview(getState());
134+
expect(preview).toMatchSnapshot();
135135
});
136136
});
137137
});

src/actions/types.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ type ASTAction =
230230
locations: AstLocation[]
231231
}
232232
| {
233-
type: "SET_SELECTION",
233+
type: "SET_PREVIEW",
234234
value: {
235235
expression: string,
236236
result: any,
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
.popover .preview-popup {
2+
background: var(--theme-body-background);
3+
width: 350px;
4+
min-height: 80px;
5+
border: 1px solid var(--theme-splitter-color);
6+
padding: 10px;
7+
height: auto;
8+
min-height: inherit;
9+
max-height: 200px;
10+
overflow: auto;
11+
box-shadow: 1px 2px 3px var(--popup-shadow-color);
12+
}
13+
14+
.theme-dark .popover .preview-popup {
15+
box-shadow: 1px 2px 3px var(--popup-shadow-color);
16+
}
17+
18+
.popover .preview-popup .header {
19+
width: 100%;
20+
line-height: 20px;
21+
border-bottom: 1px solid #cccccc;
22+
display: flex;
23+
flex-direction: column;
24+
}
25+
26+
.popover .preview-popup .header .link {
27+
align-self: flex-end;
28+
color: var(--theme-highlight-blue);
29+
text-decoration: underline;
30+
}
31+
32+
.preview-selection:hover {
33+
cursor: default;
34+
}
35+
36+
.preview-selection,
37+
.debug-expression.preview-selection {
38+
background-color: var(--theme-highlight-yellow);
39+
}
40+
41+
.theme-dark .preview-selection,
42+
.theme-dark .debug-expression.preview-selection {
43+
background-color: #743884;
44+
}
45+
46+
.theme-dark .cm-s-mozilla .preview-selection,
47+
.theme-dark .cm-s-mozilla .debug-expression.preview-selection {
48+
color: #e7ebee;
49+
}
50+
51+
.popover .preview-popup .function-signature {
52+
padding-top: 10px;
53+
}
54+
55+
.theme-dark .popover .preview-popup {
56+
border-color: var(--theme-body-color);
57+
}
58+
59+
.theme-dark .popover .preview-popup .arrow svg {
60+
fill: var(--theme-content-color3);
61+
}
62+
63+
.tooltip {
64+
position: fixed;
65+
z-index: 100;
66+
}
67+
68+
.tooltip .preview-popup {
69+
background: var(--theme-toolbar-background);
70+
max-width: inherit;
71+
min-height: 80px;
72+
border: 1px solid var(--theme-splitter-color);
73+
box-shadow: 1px 2px 4px 1px var(--theme-toolbar-background-alt);
74+
padding: 5px;
75+
height: auto;
76+
min-height: inherit;
77+
max-height: 200px;
78+
overflow: auto;
79+
}
80+
81+
.theme-dark .tooltip .preview-popup {
82+
border-color: var(--theme-body-color);
83+
}
84+
85+
.tooltip .gap {
86+
height: 4px;
87+
padding-top: 4px;
88+
}
89+
90+
.add-to-expression-bar {
91+
border: 1px solid var(--theme-splitter-color);
92+
border-top: none;
93+
display: -webkit-box;
94+
display: -ms-flexbox;
95+
display: flex;
96+
-webkit-box-align: center;
97+
-ms-flex-align: center;
98+
align-items: center;
99+
font-size: 14px;
100+
line-height: 30px;
101+
background: var(--theme-toolbar-background);
102+
color: var(--theme-comment-alt);
103+
padding: 0 4px;
104+
}
105+
106+
.add-to-expression-bar .prompt {
107+
width: 1em;
108+
}
109+
110+
.add-to-expression-bar .expression-to-save-label {
111+
width: calc(100% - 4em);
112+
}
113+
114+
.add-to-expression-bar .expression-to-save-button {
115+
font-size: 14px;
116+
color: var(--theme-content-color3);
117+
}
Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,33 @@ const { REPS: { Rep }, MODE, ObjectInspectorUtils } = Reps;
1010
const { ObjectInspector } = Reps;
1111
const { getChildren } = ObjectInspectorUtils;
1212

13-
import Popover from "../shared/Popover";
14-
15-
import previewFunction from "../shared/previewFunction";
16-
import { getLoadedObjects } from "../../selectors";
17-
import actions from "../../actions";
18-
import { markText } from "../../utils/editor";
19-
20-
import type { EditorRange } from "../../utils/editor/types";
21-
22-
import "./Preview.css";
23-
24-
export class Preview extends Component {
13+
import actions from "../../../actions";
14+
import { getLoadedObjects } from "../../../selectors";
15+
import Popover from "../../shared/Popover";
16+
import previewFunction from "../../shared/previewFunction";
17+
import { markText } from "../../../utils/editor";
18+
19+
import "./Popup.css";
20+
21+
import type { EditorRange } from "../../../utils/editor/types";
22+
23+
type Props = {
24+
loadObjectProperties: Object => void,
25+
addExpression: (string, ?Object) => void,
26+
loadedObjects: Object,
27+
popoverPos: Object,
28+
value: Object,
29+
expression: string,
30+
onClose: () => void,
31+
range: EditorRange,
32+
editor: any,
33+
selectSourceURL: (string, Object) => void
34+
};
35+
36+
export class Popup extends Component {
2537
marker: any;
2638
pos: any;
27-
props: {
28-
loadObjectProperties: Object => void,
29-
addExpression: (string, ?Object) => void,
30-
loadedObjects: Object,
31-
popoverPos: Object,
32-
value: Object,
33-
expression: string,
34-
onClose: () => void,
35-
range: EditorRange,
36-
editor: any,
37-
selectSourceURL: (string, Object) => void
38-
};
39+
props: Props;
3940

4041
componentDidMount() {
4142
const {
@@ -46,7 +47,7 @@ export class Preview extends Component {
4647
range
4748
} = this.props;
4849

49-
this.marker = markText(editor, "selection", range);
50+
this.marker = markText(editor, "preview-selection", range);
5051

5152
if (!value || !value.type == "object") {
5253
return;
@@ -76,7 +77,7 @@ export class Preview extends Component {
7677
return children;
7778
}
7879

79-
return [root];
80+
return null;
8081
}
8182

8283
renderFunctionPreview(value: Object, root: Object) {
@@ -85,7 +86,7 @@ export class Preview extends Component {
8586

8687
return (
8788
<div
88-
className="preview"
89+
className="preview-popup"
8990
onClick={() => selectSourceURL(location.url, { line: location.line })}
9091
>
9192
{previewFunction(value)}
@@ -95,15 +96,15 @@ export class Preview extends Component {
9596

9697
renderObjectPreview(expression: string, root: Object) {
9798
return (
98-
<div className="preview">
99+
<div className="preview-popup">
99100
{this.renderObjectInspector(root)}
100101
</div>
101102
);
102103
}
103104

104105
renderSimplePreview(value: Object) {
105106
return (
106-
<div className="preview">
107+
<div className="preview-popup">
107108
{Rep({ object: value, mode: MODE.LONG })}
108109
</div>
109110
);
@@ -115,6 +116,10 @@ export class Preview extends Component {
115116
const getObjectProperties = id => loadedObjects[id];
116117
const roots = this.getChildren(root, getObjectProperties);
117118

119+
if (!roots) {
120+
return null;
121+
}
122+
118123
return (
119124
<ObjectInspector
120125
roots={roots}
@@ -201,11 +206,11 @@ export class Preview extends Component {
201206
}
202207
}
203208

204-
Preview.displayName = "Preview";
209+
Popup.displayName = "Popup";
205210

206211
export default connect(
207212
state => ({
208213
loadedObjects: getLoadedObjects(state)
209214
}),
210215
dispatch => bindActionCreators(actions, dispatch)
211-
)(Preview);
216+
)(Popup);

0 commit comments

Comments
 (0)