chrome-devtools-frontend 1.0.945329 → 1.0.945579
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/gni/devtools_grd_files.gni +1 -0
- package/config/gni/devtools_image_files.gni +1 -0
- package/front_end/Images/src/circled_exclamation_icon.svg +3 -0
- package/front_end/core/sdk/CSSMetadata.ts +0 -1
- package/front_end/generated/protocol.d.ts +0 -4
- package/front_end/models/emulation/EmulatedDevices.ts +2 -4
- package/front_end/panels/application/BackForwardCacheView.ts +8 -1
- package/front_end/panels/elements/StyleEditorWidget.ts +13 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +8 -12
- package/front_end/panels/elements/StylesSidebarPane.ts +35 -9
- package/front_end/ui/components/adorners/Adorner.ts +14 -14
- package/front_end/ui/components/buttons/Button.ts +116 -42
- package/front_end/ui/components/data_grid/DataGrid.ts +122 -122
- package/front_end/ui/components/data_grid/DataGridController.ts +42 -42
- package/front_end/ui/components/diff_view/DiffView.ts +4 -4
- package/front_end/ui/components/docs/button/basic.html +3 -0
- package/front_end/ui/components/docs/button/basic.ts +16 -0
- package/front_end/ui/components/expandable_list/ExpandableList.ts +11 -11
- package/front_end/ui/components/icon_button/Icon.ts +24 -21
- package/front_end/ui/components/icon_button/IconButton.ts +31 -31
- package/front_end/ui/components/issue_counter/IssueCounter.ts +52 -52
- package/front_end/ui/components/issue_counter/IssueLinkIcon.ts +42 -42
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspector.ts +67 -67
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +22 -22
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorPane.ts +36 -36
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryNavigator.ts +19 -19
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryValueInterpreter.ts +25 -25
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.ts +52 -52
- package/front_end/ui/components/linear_memory_inspector/ValueInterpreterDisplay.ts +21 -21
- package/front_end/ui/components/linear_memory_inspector/ValueInterpreterSettings.ts +6 -6
- package/front_end/ui/components/markdown_view/MarkdownImage.ts +14 -14
- package/front_end/ui/components/markdown_view/MarkdownLink.ts +8 -8
- package/front_end/ui/components/markdown_view/MarkdownView.ts +6 -6
- package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +33 -33
- package/front_end/ui/components/report_view/ReportView.ts +18 -18
- package/front_end/ui/components/request_link_icon/RequestLinkIcon.ts +53 -53
- package/front_end/ui/components/settings/SettingCheckbox.ts +15 -15
- package/front_end/ui/components/survey_link/SurveyLink.ts +28 -28
- package/front_end/ui/components/text_editor/TextEditor.ts +51 -51
- package/front_end/ui/components/text_editor/javascript.ts +6 -6
- package/front_end/ui/components/text_prompt/TextPrompt.ts +19 -19
- package/front_end/ui/components/tree_outline/TreeOutline.ts +56 -56
- package/front_end/ui/legacy/Infobar.ts +9 -0
- package/front_end/ui/legacy/tabbedPane.css +1 -1
- package/package.json +1 -1
|
@@ -50,21 +50,21 @@ export class Wrapper extends UI.Widget.VBox {
|
|
|
50
50
|
|
|
51
51
|
export class LinearMemoryInspectorPaneImpl extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.Widget.VBox>(
|
|
52
52
|
UI.Widget.VBox) {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
readonly #tabbedPane: UI.TabbedPane.TabbedPane;
|
|
54
|
+
readonly #tabIdToInspectorView: Map<string, LinearMemoryInspectorView>;
|
|
55
55
|
constructor() {
|
|
56
56
|
super(false);
|
|
57
57
|
const placeholder = document.createElement('div');
|
|
58
58
|
placeholder.textContent = i18nString(UIStrings.noOpenInspections);
|
|
59
59
|
placeholder.style.display = 'flex';
|
|
60
|
-
this
|
|
61
|
-
this
|
|
62
|
-
this
|
|
63
|
-
this
|
|
64
|
-
this
|
|
65
|
-
this
|
|
60
|
+
this.#tabbedPane = new UI.TabbedPane.TabbedPane();
|
|
61
|
+
this.#tabbedPane.setPlaceholderElement(placeholder);
|
|
62
|
+
this.#tabbedPane.setCloseableTabs(true);
|
|
63
|
+
this.#tabbedPane.setAllowTabReorder(true, true);
|
|
64
|
+
this.#tabbedPane.addEventListener(UI.TabbedPane.Events.TabClosed, this.tabClosed, this);
|
|
65
|
+
this.#tabbedPane.show(this.contentElement);
|
|
66
66
|
|
|
67
|
-
this
|
|
67
|
+
this.#tabIdToInspectorView = new Map();
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
static instance(): LinearMemoryInspectorPaneImpl {
|
|
@@ -76,17 +76,17 @@ export class LinearMemoryInspectorPaneImpl extends Common.ObjectWrapper.eventMix
|
|
|
76
76
|
|
|
77
77
|
create(tabId: string, title: string, arrayWrapper: LazyUint8Array, address?: number): void {
|
|
78
78
|
const inspectorView = new LinearMemoryInspectorView(arrayWrapper, address);
|
|
79
|
-
this
|
|
80
|
-
this
|
|
81
|
-
this
|
|
79
|
+
this.#tabIdToInspectorView.set(tabId, inspectorView);
|
|
80
|
+
this.#tabbedPane.appendTab(tabId, title, inspectorView, undefined, false, true);
|
|
81
|
+
this.#tabbedPane.selectTab(tabId);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
close(tabId: string): void {
|
|
85
|
-
this
|
|
85
|
+
this.#tabbedPane.closeTab(tabId, false);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
reveal(tabId: string, address?: number): void {
|
|
89
|
-
const view = this
|
|
89
|
+
const view = this.#tabIdToInspectorView.get(tabId);
|
|
90
90
|
if (!view) {
|
|
91
91
|
throw new Error(`No linear memory inspector view for given tab id: ${tabId}`);
|
|
92
92
|
}
|
|
@@ -95,11 +95,11 @@ export class LinearMemoryInspectorPaneImpl extends Common.ObjectWrapper.eventMix
|
|
|
95
95
|
view.updateAddress(address);
|
|
96
96
|
}
|
|
97
97
|
this.refreshView(tabId);
|
|
98
|
-
this
|
|
98
|
+
this.#tabbedPane.selectTab(tabId);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
refreshView(tabId: string): void {
|
|
102
|
-
const view = this
|
|
102
|
+
const view = this.#tabIdToInspectorView.get(tabId);
|
|
103
103
|
if (!view) {
|
|
104
104
|
throw new Error(`View for specified tab id does not exist: ${tabId}`);
|
|
105
105
|
}
|
|
@@ -108,7 +108,7 @@ export class LinearMemoryInspectorPaneImpl extends Common.ObjectWrapper.eventMix
|
|
|
108
108
|
|
|
109
109
|
private tabClosed(event: Common.EventTarget.EventTargetEvent<UI.TabbedPane.EventData>): void {
|
|
110
110
|
const {tabId} = event.data;
|
|
111
|
-
this
|
|
111
|
+
this.#tabIdToInspectorView.delete(tabId);
|
|
112
112
|
this.dispatchEventToListeners(Events.ViewClosed, tabId);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -122,9 +122,9 @@ export type EventTypes = {
|
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
class LinearMemoryInspectorView extends UI.Widget.VBox {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
#memoryWrapper: LazyUint8Array;
|
|
126
|
+
#address: number;
|
|
127
|
+
#inspector: LinearMemoryInspector;
|
|
128
128
|
firstTimeOpen: boolean;
|
|
129
129
|
constructor(memoryWrapper: LazyUint8Array, address: number|undefined = 0) {
|
|
130
130
|
super(false);
|
|
@@ -133,21 +133,21 @@ class LinearMemoryInspectorView extends UI.Widget.VBox {
|
|
|
133
133
|
throw new Error('Requested address is out of bounds.');
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
this
|
|
137
|
-
this
|
|
138
|
-
this
|
|
139
|
-
this
|
|
136
|
+
this.#memoryWrapper = memoryWrapper;
|
|
137
|
+
this.#address = address;
|
|
138
|
+
this.#inspector = new LinearMemoryInspector();
|
|
139
|
+
this.#inspector.addEventListener('memoryrequest', (event: MemoryRequestEvent) => {
|
|
140
140
|
this.memoryRequested(event);
|
|
141
141
|
});
|
|
142
|
-
this
|
|
142
|
+
this.#inspector.addEventListener('addresschanged', (event: AddressChangedEvent) => {
|
|
143
143
|
this.updateAddress(event.data);
|
|
144
144
|
});
|
|
145
|
-
this
|
|
145
|
+
this.#inspector.addEventListener('settingschanged', (event: SettingsChangedEvent) => {
|
|
146
146
|
// Stop event from bubbling up, since no element further up needs the event.
|
|
147
147
|
event.stopPropagation();
|
|
148
148
|
this.saveSettings(event.data);
|
|
149
149
|
});
|
|
150
|
-
this.contentElement.appendChild(this
|
|
150
|
+
this.contentElement.appendChild(this.#inspector);
|
|
151
151
|
this.firstTimeOpen = true;
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -160,14 +160,14 @@ class LinearMemoryInspectorView extends UI.Widget.VBox {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
updateAddress(address: number): void {
|
|
163
|
-
if (address < 0 || address >= this
|
|
163
|
+
if (address < 0 || address >= this.#memoryWrapper.length()) {
|
|
164
164
|
throw new Error('Requested address is out of bounds.');
|
|
165
165
|
}
|
|
166
|
-
this
|
|
166
|
+
this.#address = address;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
refreshData(): void {
|
|
170
|
-
LinearMemoryInspectorController.getMemoryForAddress(this
|
|
170
|
+
LinearMemoryInspectorController.getMemoryForAddress(this.#memoryWrapper, this.#address).then(({memory, offset}) => {
|
|
171
171
|
let valueTypes;
|
|
172
172
|
let valueTypeModes;
|
|
173
173
|
let endianness;
|
|
@@ -178,11 +178,11 @@ class LinearMemoryInspectorView extends UI.Widget.VBox {
|
|
|
178
178
|
endianness = settings.endianness;
|
|
179
179
|
this.firstTimeOpen = false;
|
|
180
180
|
}
|
|
181
|
-
this
|
|
181
|
+
this.#inspector.data = {
|
|
182
182
|
memory,
|
|
183
|
-
address: this
|
|
183
|
+
address: this.#address,
|
|
184
184
|
memoryOffset: offset,
|
|
185
|
-
outerMemoryLength: this
|
|
185
|
+
outerMemoryLength: this.#memoryWrapper.length(),
|
|
186
186
|
valueTypes,
|
|
187
187
|
valueTypeModes,
|
|
188
188
|
endianness,
|
|
@@ -196,12 +196,12 @@ class LinearMemoryInspectorView extends UI.Widget.VBox {
|
|
|
196
196
|
throw new Error('Requested address is out of bounds.');
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
LinearMemoryInspectorController.getMemoryRange(this
|
|
200
|
-
this
|
|
199
|
+
LinearMemoryInspectorController.getMemoryRange(this.#memoryWrapper, start, end).then(memory => {
|
|
200
|
+
this.#inspector.data = {
|
|
201
201
|
memory: memory,
|
|
202
202
|
address: address,
|
|
203
203
|
memoryOffset: start,
|
|
204
|
-
outerMemoryLength: this
|
|
204
|
+
outerMemoryLength: this.#memoryWrapper.length(),
|
|
205
205
|
};
|
|
206
206
|
});
|
|
207
207
|
}
|
|
@@ -98,26 +98,26 @@ export const enum Mode {
|
|
|
98
98
|
export class LinearMemoryNavigator extends HTMLElement {
|
|
99
99
|
static readonly litTagName = LitHtml.literal`devtools-linear-memory-inspector-navigator`;
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
102
|
+
#address = '0';
|
|
103
|
+
#error: string|undefined = undefined;
|
|
104
|
+
#valid = true;
|
|
105
|
+
#canGoBackInHistory = false;
|
|
106
|
+
#canGoForwardInHistory = false;
|
|
107
107
|
|
|
108
108
|
connectedCallback(): void {
|
|
109
|
-
this
|
|
109
|
+
this.#shadow.adoptedStyleSheets = [linearMemoryNavigatorStyles];
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
set data(data: LinearMemoryNavigatorData) {
|
|
113
|
-
this
|
|
114
|
-
this
|
|
115
|
-
this
|
|
116
|
-
this
|
|
117
|
-
this
|
|
113
|
+
this.#address = data.address;
|
|
114
|
+
this.#error = data.error;
|
|
115
|
+
this.#valid = data.valid;
|
|
116
|
+
this.#canGoBackInHistory = data.canGoBackInHistory;
|
|
117
|
+
this.#canGoForwardInHistory = data.canGoForwardInHistory;
|
|
118
118
|
this.render();
|
|
119
119
|
|
|
120
|
-
const addressInput = this
|
|
120
|
+
const addressInput = this.#shadow.querySelector<HTMLInputElement>('.address-input');
|
|
121
121
|
if (addressInput) {
|
|
122
122
|
if (data.mode === Mode.Submitted) {
|
|
123
123
|
addressInput.blur();
|
|
@@ -134,9 +134,9 @@ export class LinearMemoryNavigator extends HTMLElement {
|
|
|
134
134
|
<div class="navigator">
|
|
135
135
|
<div class="navigator-item">
|
|
136
136
|
${this.createButton({icon: 'ic_undo_16x16_icon', title: i18nString(UIStrings.goBackInAddressHistory),
|
|
137
|
-
event: new HistoryNavigationEvent(Navigation.Backward), enabled: this
|
|
137
|
+
event: new HistoryNavigationEvent(Navigation.Backward), enabled: this.#canGoBackInHistory})}
|
|
138
138
|
${this.createButton({icon: 'ic_redo_16x16_icon', title: i18nString(UIStrings.goForwardInAddressHistory),
|
|
139
|
-
event: new HistoryNavigationEvent(Navigation.Forward), enabled: this
|
|
139
|
+
event: new HistoryNavigationEvent(Navigation.Forward), enabled: this.#canGoForwardInHistory})}
|
|
140
140
|
</div>
|
|
141
141
|
<div class="navigator-item">
|
|
142
142
|
${this.createButton({icon: 'ic_page_prev_16x16_icon', title: i18nString(UIStrings.previousPage),
|
|
@@ -149,18 +149,18 @@ export class LinearMemoryNavigator extends HTMLElement {
|
|
|
149
149
|
event: new RefreshRequestedEvent(), enabled: true})}
|
|
150
150
|
</div>
|
|
151
151
|
`;
|
|
152
|
-
render(result, this
|
|
152
|
+
render(result, this.#shadow, {host: this});
|
|
153
153
|
// clang-format on
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
private createAddressInput(): LitHtml.TemplateResult {
|
|
157
157
|
const classMap = {
|
|
158
158
|
'address-input': true,
|
|
159
|
-
invalid: !this
|
|
159
|
+
invalid: !this.#valid,
|
|
160
160
|
};
|
|
161
161
|
return html`
|
|
162
|
-
<input class=${LitHtml.Directives.classMap(classMap)} data-input="true" .value=${this
|
|
163
|
-
title=${this
|
|
162
|
+
<input class=${LitHtml.Directives.classMap(classMap)} data-input="true" .value=${this.#address}
|
|
163
|
+
title=${this.#valid ? i18nString(UIStrings.enterAddress) : this.#error} @change=${
|
|
164
164
|
this.onAddressChange.bind(this, Mode.Submitted)} @input=${this.onAddressChange.bind(this, Mode.Edit)}/>`;
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -66,31 +66,31 @@ export interface LinearMemoryValueInterpreterData {
|
|
|
66
66
|
export class LinearMemoryValueInterpreter extends HTMLElement {
|
|
67
67
|
static readonly litTagName = LitHtml.literal`devtools-linear-memory-inspector-interpreter`;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
70
|
+
#endianness = Endianness.Little;
|
|
71
|
+
#buffer = new ArrayBuffer(0);
|
|
72
|
+
#valueTypes: Set<ValueType> = new Set();
|
|
73
|
+
#valueTypeModeConfig: Map<ValueType, ValueTypeMode> = new Map();
|
|
74
|
+
#memoryLength = 0;
|
|
75
|
+
#showSettings = false;
|
|
76
76
|
|
|
77
77
|
constructor() {
|
|
78
78
|
super();
|
|
79
|
-
this
|
|
79
|
+
this.#shadow.adoptedStyleSheets = [
|
|
80
80
|
inspectorCommonStyles,
|
|
81
81
|
];
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
connectedCallback(): void {
|
|
85
|
-
this
|
|
85
|
+
this.#shadow.adoptedStyleSheets = [linearMemoryValueInterpreterStyles];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
set data(data: LinearMemoryValueInterpreterData) {
|
|
89
|
-
this
|
|
90
|
-
this
|
|
91
|
-
this
|
|
92
|
-
this
|
|
93
|
-
this
|
|
89
|
+
this.#endianness = data.endianness;
|
|
90
|
+
this.#buffer = data.value;
|
|
91
|
+
this.#valueTypes = data.valueTypes;
|
|
92
|
+
this.#valueTypeModeConfig = data.valueTypeModes || new Map();
|
|
93
|
+
this.#memoryLength = data.memoryLength;
|
|
94
94
|
this.render();
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -101,7 +101,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
|
|
|
101
101
|
<div class="value-interpreter">
|
|
102
102
|
<div class="settings-toolbar">
|
|
103
103
|
${this.renderEndiannessSetting()}
|
|
104
|
-
<button data-settings="true" class="settings-toolbar-button ${this
|
|
104
|
+
<button data-settings="true" class="settings-toolbar-button ${this.#showSettings ? 'active' : ''}" title=${i18nString(UIStrings.toggleValueTypeSettings)} @click=${this.onSettingsToggle}>
|
|
105
105
|
<${IconButton.Icon.Icon.litTagName}
|
|
106
106
|
.data=${{ iconName: 'settings_14x14_icon', color: 'var(--color-text-secondary)', width: '14px' } as IconButton.Icon.IconWithName}>
|
|
107
107
|
</${IconButton.Icon.Icon.litTagName}>
|
|
@@ -109,26 +109,26 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
|
|
|
109
109
|
</div>
|
|
110
110
|
<span class="divider"></span>
|
|
111
111
|
<div>
|
|
112
|
-
${this
|
|
112
|
+
${this.#showSettings ?
|
|
113
113
|
html`
|
|
114
114
|
<${ValueInterpreterSettings.litTagName}
|
|
115
|
-
.data=${{ valueTypes: this
|
|
115
|
+
.data=${{ valueTypes: this.#valueTypes } as ValueInterpreterSettingsData}
|
|
116
116
|
@typetoggle=${this.onTypeToggle}>
|
|
117
117
|
</${ValueInterpreterSettings.litTagName}>` :
|
|
118
118
|
html`
|
|
119
119
|
<${ValueInterpreterDisplay.litTagName}
|
|
120
120
|
.data=${{
|
|
121
|
-
buffer: this
|
|
122
|
-
valueTypes: this
|
|
123
|
-
endianness: this
|
|
124
|
-
valueTypeModes: this
|
|
125
|
-
memoryLength: this
|
|
121
|
+
buffer: this.#buffer,
|
|
122
|
+
valueTypes: this.#valueTypes,
|
|
123
|
+
endianness: this.#endianness,
|
|
124
|
+
valueTypeModes: this.#valueTypeModeConfig,
|
|
125
|
+
memoryLength: this.#memoryLength,
|
|
126
126
|
} as ValueDisplayData}>
|
|
127
127
|
</${ValueInterpreterDisplay.litTagName}>`}
|
|
128
128
|
</div>
|
|
129
129
|
</div>
|
|
130
130
|
`,
|
|
131
|
-
this
|
|
131
|
+
this.#shadow, { host: this },
|
|
132
132
|
);
|
|
133
133
|
// clang-format on
|
|
134
134
|
}
|
|
@@ -150,7 +150,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
|
|
|
150
150
|
style="border: none; background-color: transparent; cursor: pointer;"
|
|
151
151
|
data-endianness="true" @change=${onEnumSettingChange}>
|
|
152
152
|
${[Endianness.Little, Endianness.Big].map(endianness => {
|
|
153
|
-
return html`<option value=${endianness} .selected=${this
|
|
153
|
+
return html`<option value=${endianness} .selected=${this.#endianness === endianness}>${
|
|
154
154
|
i18n.i18n.lockedString(endianness)}</option>`;
|
|
155
155
|
})}
|
|
156
156
|
</select>
|
|
@@ -160,7 +160,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
private onSettingsToggle(): void {
|
|
163
|
-
this
|
|
163
|
+
this.#showSettings = !this.#showSettings;
|
|
164
164
|
this.render();
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -40,21 +40,21 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
40
40
|
|
|
41
41
|
private static readonly BYTE_GROUP_MARGIN = 8;
|
|
42
42
|
private static readonly BYTE_GROUP_SIZE = 4;
|
|
43
|
-
|
|
43
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
readonly #resizeObserver = new ResizeObserver(() => this.resize());
|
|
46
|
+
#isObservingResize = false;
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
#memory = new Uint8Array();
|
|
49
|
+
#address = 0;
|
|
50
|
+
#memoryOffset = 0;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
#numRows = 1;
|
|
53
|
+
#numBytesInRow = LinearMemoryViewer.BYTE_GROUP_SIZE;
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
#focusOnByte = true;
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
#lastKeyUpdateSent: number|undefined = undefined;
|
|
58
58
|
|
|
59
59
|
set data(data: LinearMemoryViewerData) {
|
|
60
60
|
if (data.address < data.memoryOffset || data.address > data.memoryOffset + data.memory.length || data.address < 0) {
|
|
@@ -65,21 +65,21 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
65
65
|
throw new Error('Memory offset has to be greater or equal to zero.');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
this
|
|
69
|
-
this
|
|
70
|
-
this
|
|
71
|
-
this
|
|
68
|
+
this.#memory = data.memory;
|
|
69
|
+
this.#address = data.address;
|
|
70
|
+
this.#memoryOffset = data.memoryOffset;
|
|
71
|
+
this.#focusOnByte = data.focus;
|
|
72
72
|
this.update();
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
connectedCallback(): void {
|
|
76
76
|
ComponentHelpers.SetCSSProperty.set(this, '--byte-group-margin', `${LinearMemoryViewer.BYTE_GROUP_MARGIN}px`);
|
|
77
|
-
this
|
|
77
|
+
this.#shadow.adoptedStyleSheets = [linearMemoryViewerStyles];
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
disconnectedCallback(): void {
|
|
81
|
-
this
|
|
82
|
-
this
|
|
81
|
+
this.#isObservingResize = false;
|
|
82
|
+
this.#resizeObserver.disconnect();
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
private update(): void {
|
|
@@ -90,8 +90,8 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
private focusOnView(): void {
|
|
93
|
-
if (this
|
|
94
|
-
const view = this
|
|
93
|
+
if (this.#focusOnByte) {
|
|
94
|
+
const view = this.#shadow.querySelector<HTMLDivElement>('.view');
|
|
95
95
|
if (view) {
|
|
96
96
|
view.focus();
|
|
97
97
|
}
|
|
@@ -100,14 +100,14 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
100
100
|
|
|
101
101
|
private resize(): void {
|
|
102
102
|
this.update();
|
|
103
|
-
this.dispatchEvent(new ResizeEvent(this
|
|
103
|
+
this.dispatchEvent(new ResizeEvent(this.#numBytesInRow * this.#numRows));
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
/** Recomputes the number of rows and (byte) columns that fit into the current view. */
|
|
107
107
|
private updateDimensions(): void {
|
|
108
108
|
if (this.clientWidth === 0 || this.clientHeight === 0 || !this.shadowRoot) {
|
|
109
|
-
this
|
|
110
|
-
this
|
|
109
|
+
this.#numBytesInRow = LinearMemoryViewer.BYTE_GROUP_SIZE;
|
|
110
|
+
this.#numRows = 1;
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -126,8 +126,8 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
126
126
|
const rowElement = this.shadowRoot.querySelector('.row');
|
|
127
127
|
|
|
128
128
|
if (!firstByteCell || !textCell || !divider || !rowElement) {
|
|
129
|
-
this
|
|
130
|
-
this
|
|
129
|
+
this.#numBytesInRow = LinearMemoryViewer.BYTE_GROUP_SIZE;
|
|
130
|
+
this.#numRows = 1;
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -144,22 +144,22 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
144
144
|
const widthToFill = this.clientWidth - 1 -
|
|
145
145
|
(firstByteCell.getBoundingClientRect().left - this.getBoundingClientRect().left) - dividerWidth;
|
|
146
146
|
if (widthToFill < groupWidth) {
|
|
147
|
-
this
|
|
148
|
-
this
|
|
147
|
+
this.#numBytesInRow = LinearMemoryViewer.BYTE_GROUP_SIZE;
|
|
148
|
+
this.#numRows = 1;
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
this
|
|
153
|
-
this
|
|
152
|
+
this.#numBytesInRow = Math.floor(widthToFill / groupWidth) * LinearMemoryViewer.BYTE_GROUP_SIZE;
|
|
153
|
+
this.#numRows = Math.floor(this.clientHeight / rowElement.clientHeight);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
private engageResizeObserver(): void {
|
|
157
|
-
if (!this
|
|
157
|
+
if (!this.#resizeObserver || this.#isObservingResize) {
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
this
|
|
162
|
-
this
|
|
161
|
+
this.#resizeObserver.observe(this);
|
|
162
|
+
this.#isObservingResize = true;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
private render(): void {
|
|
@@ -169,50 +169,50 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
169
169
|
<div class="view" tabindex="0" @keydown=${this.onKeyDown}>
|
|
170
170
|
${this.renderView()}
|
|
171
171
|
</div>
|
|
172
|
-
`, this
|
|
172
|
+
`, this.#shadow, {host: this});
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
private onKeyDown(event: Event): void {
|
|
176
176
|
const keyboardEvent = event as KeyboardEvent;
|
|
177
177
|
let newAddress = undefined;
|
|
178
178
|
if (keyboardEvent.code === 'ArrowUp') {
|
|
179
|
-
newAddress = this
|
|
179
|
+
newAddress = this.#address - this.#numBytesInRow;
|
|
180
180
|
} else if (keyboardEvent.code === 'ArrowDown') {
|
|
181
|
-
newAddress = this
|
|
181
|
+
newAddress = this.#address + this.#numBytesInRow;
|
|
182
182
|
} else if (keyboardEvent.code === 'ArrowLeft') {
|
|
183
|
-
newAddress = this
|
|
183
|
+
newAddress = this.#address - 1;
|
|
184
184
|
} else if (keyboardEvent.code === 'ArrowRight') {
|
|
185
|
-
newAddress = this
|
|
185
|
+
newAddress = this.#address + 1;
|
|
186
186
|
} else if (keyboardEvent.code === 'PageUp') {
|
|
187
|
-
newAddress = this
|
|
187
|
+
newAddress = this.#address - this.#numBytesInRow * this.#numRows;
|
|
188
188
|
} else if (keyboardEvent.code === 'PageDown') {
|
|
189
|
-
newAddress = this
|
|
189
|
+
newAddress = this.#address + this.#numBytesInRow * this.#numRows;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
if (newAddress !== undefined && newAddress !== this
|
|
193
|
-
this
|
|
192
|
+
if (newAddress !== undefined && newAddress !== this.#lastKeyUpdateSent) {
|
|
193
|
+
this.#lastKeyUpdateSent = newAddress;
|
|
194
194
|
this.dispatchEvent(new ByteSelectedEvent(newAddress));
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
private renderView(): LitHtml.TemplateResult {
|
|
199
199
|
const itemTemplates = [];
|
|
200
|
-
for (let i = 0; i < this
|
|
200
|
+
for (let i = 0; i < this.#numRows; ++i) {
|
|
201
201
|
itemTemplates.push(this.renderRow(i));
|
|
202
202
|
}
|
|
203
203
|
return html`${itemTemplates}`;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
private renderRow(row: number): LitHtml.TemplateResult {
|
|
207
|
-
const {startIndex, endIndex} = {startIndex: row * this
|
|
207
|
+
const {startIndex, endIndex} = {startIndex: row * this.#numBytesInRow, endIndex: (row + 1) * this.#numBytesInRow};
|
|
208
208
|
|
|
209
209
|
const classMap = {
|
|
210
210
|
address: true,
|
|
211
|
-
selected: Math.floor((this
|
|
211
|
+
selected: Math.floor((this.#address - this.#memoryOffset) / this.#numBytesInRow) === row,
|
|
212
212
|
};
|
|
213
213
|
return html`
|
|
214
214
|
<div class="row">
|
|
215
|
-
<span class="${LitHtml.Directives.classMap(classMap)}">${toHexString({number: startIndex + this
|
|
215
|
+
<span class="${LitHtml.Directives.classMap(classMap)}">${toHexString({number: startIndex + this.#memoryOffset, pad: 8, prefix: false})}</span>
|
|
216
216
|
<span class="divider"></span>
|
|
217
217
|
${this.renderByteValues(startIndex, endIndex)}
|
|
218
218
|
<span class="divider"></span>
|
|
@@ -226,16 +226,16 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
226
226
|
for (let i = startIndex; i < endIndex; ++i) {
|
|
227
227
|
// Add margin after each group of bytes of size byteGroupSize.
|
|
228
228
|
const addMargin = i !== startIndex && (i - startIndex) % LinearMemoryViewer.BYTE_GROUP_SIZE === 0;
|
|
229
|
-
const selected = i === this
|
|
229
|
+
const selected = i === this.#address - this.#memoryOffset;
|
|
230
230
|
const classMap = {
|
|
231
231
|
'cell': true,
|
|
232
232
|
'byte-cell': true,
|
|
233
233
|
'byte-group-margin': addMargin,
|
|
234
234
|
selected,
|
|
235
235
|
};
|
|
236
|
-
const isSelectableCell = i < this
|
|
237
|
-
const byteValue = isSelectableCell ? html`${toHexString({number: this
|
|
238
|
-
const actualIndex = i + this
|
|
236
|
+
const isSelectableCell = i < this.#memory.length;
|
|
237
|
+
const byteValue = isSelectableCell ? html`${toHexString({number: this.#memory[i], pad: 2, prefix: false})}` : '';
|
|
238
|
+
const actualIndex = i + this.#memoryOffset;
|
|
239
239
|
const onSelectedByte = isSelectableCell ? this.onSelectedByte.bind(this, actualIndex) : '';
|
|
240
240
|
cells.push(html`<span class="${LitHtml.Directives.classMap(classMap)}" @click=${onSelectedByte}>${byteValue}</span>`);
|
|
241
241
|
}
|
|
@@ -248,11 +248,11 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
|
248
248
|
const classMap = {
|
|
249
249
|
'cell': true,
|
|
250
250
|
'text-cell': true,
|
|
251
|
-
selected: this
|
|
251
|
+
selected: this.#address - this.#memoryOffset === i,
|
|
252
252
|
};
|
|
253
|
-
const isSelectableCell = i < this
|
|
254
|
-
const value = isSelectableCell ? html`${this.toAscii(this
|
|
255
|
-
const onSelectedByte = isSelectableCell ? this.onSelectedByte.bind(this, i + this
|
|
253
|
+
const isSelectableCell = i < this.#memory.length;
|
|
254
|
+
const value = isSelectableCell ? html`${this.toAscii(this.#memory[i])}` : '';
|
|
255
|
+
const onSelectedByte = isSelectableCell ? this.onSelectedByte.bind(this, i + this.#memoryOffset) : '';
|
|
256
256
|
cells.push(html`<span class="${LitHtml.Directives.classMap(classMap)}" @click=${onSelectedByte}>${value}</span>`);
|
|
257
257
|
}
|
|
258
258
|
return html`${cells}`;
|