Skip to content

Commit 7dd0148

Browse files
committed
Add prev/next buttons in the assembly view.
1 parent 2d79656 commit 7dd0148

File tree

7 files changed

+162
-2
lines changed

7 files changed

+162
-2
lines changed

src/actions/profile-view.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,15 @@ export function openAssemblyView(): Action {
19621962
};
19631963
}
19641964

1965+
export function changeAssemblyViewNativeSymbolEntryIndex(
1966+
entryIndex: number
1967+
): Action {
1968+
return {
1969+
type: 'CHANGE_ASSEMBLY_VIEW_NATIVE_SYMBOL_ENTRY_INDEX',
1970+
entryIndex,
1971+
};
1972+
}
1973+
19651974
export function closeAssemblyView(): Action {
19661975
return {
19671976
type: 'CLOSE_ASSEMBLY_VIEW',
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
import React from 'react';
6+
import classNames from 'classnames';
7+
8+
import {
9+
getAssemblyViewCurrentNativeSymbolEntryIndex,
10+
getAssemblyViewNativeSymbolEntryCount,
11+
} from 'firefox-profiler/selectors/url-state';
12+
import { changeAssemblyViewNativeSymbolEntryIndex } from 'firefox-profiler/actions/profile-view';
13+
import explicitConnect from 'firefox-profiler/utils/connect';
14+
15+
import type { ConnectedProps } from 'firefox-profiler/utils/connect';
16+
17+
import { Localized } from '@fluent/react';
18+
19+
type StateProps = {
20+
readonly assemblyViewCurrentNativeSymbolEntryIndex: number | null;
21+
readonly assemblyViewNativeSymbolEntryCount: number;
22+
};
23+
24+
type DispatchProps = {
25+
readonly changeAssemblyViewNativeSymbolEntryIndex: typeof changeAssemblyViewNativeSymbolEntryIndex;
26+
};
27+
28+
type Props = ConnectedProps<{}, StateProps, DispatchProps>;
29+
30+
class AssemblyViewNativeSymbolNavigatorImpl extends React.PureComponent<Props> {
31+
_onPreviousClick = () => {
32+
this._changeIndexBy(-1);
33+
};
34+
35+
_onNextClick = () => {
36+
this._changeIndexBy(1);
37+
};
38+
39+
_changeIndexBy(delta: number) {
40+
const {
41+
assemblyViewCurrentNativeSymbolEntryIndex: index,
42+
assemblyViewNativeSymbolEntryCount: count,
43+
changeAssemblyViewNativeSymbolEntryIndex,
44+
} = this.props;
45+
const newIndex = (index ?? 0) + delta;
46+
if (newIndex >= 0 && newIndex < count) {
47+
changeAssemblyViewNativeSymbolEntryIndex(newIndex);
48+
}
49+
}
50+
51+
override render() {
52+
const {
53+
assemblyViewCurrentNativeSymbolEntryIndex: index,
54+
assemblyViewNativeSymbolEntryCount: count,
55+
} = this.props;
56+
57+
if (index === null || count <= 1) {
58+
return null;
59+
}
60+
61+
return (
62+
<>
63+
<h3 className="bottom-box-title-trailer">
64+
{index !== null && count > 1 ? `${index + 1} of ${count}` : ''}
65+
</h3>
66+
<Localized id="AssemblyView--prev-button" attrs={{ title: true }}>
67+
<button
68+
className={classNames(
69+
'bottom-prev-button',
70+
'photon-button',
71+
'photon-button-ghost'
72+
)}
73+
title="Previous"
74+
type="button"
75+
disabled={index === null || index <= 0}
76+
onClick={this._onPreviousClick}
77+
>
78+
79+
</button>
80+
</Localized>
81+
<Localized id="AssemblyView--next-button" attrs={{ title: true }}>
82+
<button
83+
className={classNames(
84+
'bottom-next-button',
85+
'photon-button',
86+
'photon-button-ghost'
87+
)}
88+
title="Next"
89+
type="button"
90+
disabled={index === null || index >= count - 1}
91+
onClick={this._onNextClick}
92+
>
93+
94+
</button>
95+
</Localized>
96+
</>
97+
);
98+
}
99+
}
100+
101+
export const AssemblyViewNativeSymbolNavigator = explicitConnect<
102+
{},
103+
StateProps,
104+
DispatchProps
105+
>({
106+
mapStateToProps: (state) => ({
107+
assemblyViewCurrentNativeSymbolEntryIndex:
108+
getAssemblyViewCurrentNativeSymbolEntryIndex(state),
109+
assemblyViewNativeSymbolEntryCount:
110+
getAssemblyViewNativeSymbolEntryCount(state),
111+
}),
112+
mapDispatchToProps: {
113+
changeAssemblyViewNativeSymbolEntryIndex,
114+
},
115+
component: AssemblyViewNativeSymbolNavigatorImpl,
116+
});

src/components/app/BottomBox.css

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@
4646
line-height: 18px;
4747
}
4848

49-
.bottom-box-title {
49+
.bottom-box-title,
50+
.bottom-box-title-trailer {
5051
overflow: hidden;
5152
margin: 0 8px;
5253
font: inherit;
5354
text-overflow: ellipsis;
5455
white-space: nowrap;
5556
}
5657

58+
.bottom-box-title-trailer {
59+
margin: 0;
60+
}
61+
5762
.bottom-box-header-trailing-buttons {
5863
display: flex;
5964
height: 100%;
@@ -62,7 +67,9 @@
6267
}
6368

6469
.bottom-close-button,
65-
.bottom-assembly-button {
70+
.bottom-assembly-button,
71+
.bottom-prev-button,
72+
.bottom-next-button {
6673
width: 24px;
6774
height: 24px;
6875
flex-shrink: 0;
@@ -71,6 +78,16 @@
7178
background-size: 16px 16px;
7279
}
7380

81+
.bottom-prev-button,
82+
.bottom-next-button {
83+
width: 16px;
84+
font-size: 9px;
85+
}
86+
87+
.bottom-next-button {
88+
margin-right: 8px;
89+
}
90+
7491
.bottom-close-button {
7592
background-image: url(../../../res/img/svg/close-dark.svg);
7693
}

src/components/app/BottomBox.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import classNames from 'classnames';
99
import { SourceView } from '../shared/SourceView';
1010
import { AssemblyView } from '../shared/AssemblyView';
1111
import { AssemblyViewToggleButton } from './AssemblyViewToggleButton';
12+
import { AssemblyViewNativeSymbolNavigator } from './AssemblyViewNativeSymbolNavigator';
1213
import { IonGraphView } from '../shared/IonGraphView';
1314
import { CodeLoadingOverlay } from './CodeLoadingOverlay';
1415
import { CodeErrorOverlay } from './CodeErrorOverlay';
@@ -192,6 +193,7 @@ class BottomBoxImpl extends React.PureComponent<Props> {
192193
// These trailing header buttons go into the bottom-box-bar of the last pane.
193194
const trailingHeaderButtons = (
194195
<div className="bottom-box-header-trailing-buttons">
196+
{assemblyViewIsOpen ? <AssemblyViewNativeSymbolNavigator /> : null}
195197
<AssemblyViewToggleButton />
196198
<Localized id="SourceView--close-button" attrs={{ title: true }}>
197199
<button

src/reducers/url-state.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,12 @@ const assemblyView: Reducer<AssemblyViewState> = (
617617
isOpen: true,
618618
};
619619
}
620+
case 'CHANGE_ASSEMBLY_VIEW_NATIVE_SYMBOL_ENTRY_INDEX': {
621+
return {
622+
...state,
623+
currentNativeSymbol: action.entryIndex,
624+
};
625+
}
620626
case 'CLOSE_ASSEMBLY_VIEW': {
621627
return {
622628
...state,

src/selectors/url-state.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ export const getAssemblyViewNativeSymbol: Selector<NativeSymbolInfo | null> = (
9292
? nativeSymbols[currentNativeSymbol]
9393
: null;
9494
};
95+
export const getAssemblyViewCurrentNativeSymbolEntryIndex: Selector<
96+
number | null
97+
> = (state) => getProfileSpecificState(state).assemblyView.currentNativeSymbol;
98+
export const getAssemblyViewNativeSymbolEntryCount: Selector<number> = (
99+
state
100+
) => getProfileSpecificState(state).assemblyView.nativeSymbols.length;
95101
export const getAssemblyViewScrollGeneration: Selector<number> = (state) =>
96102
getProfileSpecificState(state).assemblyView.scrollGeneration;
97103
export const getAssemblyViewScrollToInstructionAddress: Selector<

src/types/actions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ type ProfileAction =
351351
| {
352352
readonly type: 'OPEN_ASSEMBLY_VIEW';
353353
}
354+
| {
355+
readonly type: 'CHANGE_ASSEMBLY_VIEW_NATIVE_SYMBOL_ENTRY_INDEX';
356+
readonly entryIndex: number;
357+
}
354358
| {
355359
readonly type: 'CLOSE_ASSEMBLY_VIEW';
356360
}

0 commit comments

Comments
 (0)