chrome-devtools-frontend 1.0.944903 → 1.0.945884
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/host/InspectorFrontendHostAPI.ts +5 -5
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/i18n/i18nImpl.ts +7 -4
- package/front_end/core/i18n/locales/en-US.json +9 -45
- package/front_end/core/i18n/locales/en-XL.json +9 -45
- package/front_end/core/sdk/CSSMetadata.ts +0 -1
- package/front_end/core/sdk/sdk-meta.ts +20 -8
- package/front_end/entrypoints/main/MainImpl.ts +6 -0
- package/front_end/generated/protocol.d.ts +0 -4
- package/front_end/models/emulation/EmulatedDevices.ts +2 -4
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +6 -10
- package/front_end/models/timeline_model/TimelineJSProfile.ts +16 -3
- package/front_end/models/timeline_model/TimelineModel.ts +1 -0
- package/front_end/models/workspace_diff/WorkspaceDiff.ts +20 -6
- package/front_end/panels/animation/AnimationTimeline.ts +1 -1
- package/front_end/panels/application/BackForwardCacheStrings.ts +15 -75
- package/front_end/panels/application/BackForwardCacheView.ts +8 -1
- package/front_end/panels/changes/ChangesView.ts +8 -7
- package/front_end/panels/elements/StyleEditorWidget.ts +7 -7
- package/front_end/panels/elements/StylePropertyTreeElement.ts +8 -15
- package/front_end/panels/elements/StylesSidebarPane.ts +35 -9
- package/front_end/panels/emulation/DeviceModeView.ts +3 -0
- package/front_end/panels/help/ReleaseNoteText.ts +3 -1
- package/front_end/panels/network/NetworkItemView.ts +7 -1
- package/front_end/panels/profiler/heapProfiler.css +2 -5
- package/front_end/panels/timeline/TimelineController.ts +3 -0
- package/front_end/panels/webauthn/WebauthnPane.ts +31 -32
- package/front_end/third_party/acorn/README.chromium +2 -2
- package/front_end/third_party/acorn/acorn.ts +1 -1
- package/front_end/third_party/acorn/package/CHANGELOG.md +31 -1
- package/front_end/third_party/acorn/package/README.md +1 -1
- package/front_end/third_party/acorn/package/dist/acorn.d.ts +3 -0
- package/front_end/third_party/acorn/package/dist/acorn.js +772 -708
- package/front_end/third_party/acorn/package/dist/acorn.mjs +767 -703
- package/front_end/third_party/acorn/package/dist/bin.js +47 -21
- package/front_end/third_party/acorn/package/package.json +1 -1
- package/front_end/third_party/acorn-loose/README.chromium +2 -2
- package/front_end/third_party/acorn-loose/package/CHANGELOG.md +12 -0
- package/front_end/third_party/acorn-loose/package/dist/acorn-loose.js +27 -7
- package/front_end/third_party/acorn-loose/package/dist/acorn-loose.mjs +28 -8
- package/front_end/third_party/acorn-loose/package/package.json +2 -2
- package/front_end/third_party/i18n/i18n-impl.ts +1 -1
- package/front_end/ui/components/adorners/Adorner.ts +14 -14
- package/front_end/ui/components/buttons/Button.ts +133 -42
- package/front_end/ui/components/buttons/button.css +31 -0
- package/front_end/ui/components/data_grid/DataGrid.ts +131 -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 +58 -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 +24 -32
- 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 +55 -52
- 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/InspectorView.ts +1 -1
- package/front_end/ui/legacy/ListWidget.ts +2 -2
- package/front_end/ui/legacy/tabbedPane.css +1 -1
- package/inspector_overlay/main.ts +3 -0
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/l10n_filename_matches.js +17 -4
- package/scripts/eslint_rules/tests/l10n_filename_matches_test.js +21 -0
|
@@ -83,84 +83,84 @@ export function getIssueCountsEnumeration(
|
|
|
83
83
|
|
|
84
84
|
export class IssueCounter extends HTMLElement {
|
|
85
85
|
static readonly litTagName = LitHtml.literal`issue-counter`;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
87
|
+
#clickHandler: undefined|(() => void) = undefined;
|
|
88
|
+
#tooltipCallback: undefined|(() => void) = undefined;
|
|
89
|
+
#leadingText: string = '';
|
|
90
|
+
#throttler: undefined|Common.Throttler.Throttler;
|
|
91
|
+
#counts: [number, number, number] = [0, 0, 0];
|
|
92
|
+
#displayMode: DisplayMode = DisplayMode.OmitEmpty;
|
|
93
|
+
#issuesManager: IssuesManager.IssuesManager.IssuesManager|undefined = undefined;
|
|
94
|
+
#accessibleName: string|undefined = undefined;
|
|
95
|
+
#throttlerTimeout: number|undefined;
|
|
96
|
+
#compact = false;
|
|
97
97
|
|
|
98
98
|
scheduleUpdate(): void {
|
|
99
|
-
if (this
|
|
100
|
-
this
|
|
99
|
+
if (this.#throttler) {
|
|
100
|
+
this.#throttler.schedule(async () => this.render());
|
|
101
101
|
} else {
|
|
102
102
|
this.render();
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
connectedCallback(): void {
|
|
107
|
-
this
|
|
107
|
+
this.#shadow.adoptedStyleSheets = [issueCounterStyles];
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
set data(data: IssueCounterData) {
|
|
111
|
-
this
|
|
112
|
-
this
|
|
113
|
-
this
|
|
114
|
-
this
|
|
115
|
-
this
|
|
116
|
-
this
|
|
117
|
-
this
|
|
118
|
-
if (this
|
|
119
|
-
this
|
|
111
|
+
this.#clickHandler = data.clickHandler;
|
|
112
|
+
this.#leadingText = data.leadingText ?? '';
|
|
113
|
+
this.#tooltipCallback = data.tooltipCallback;
|
|
114
|
+
this.#displayMode = data.displayMode ?? DisplayMode.OmitEmpty;
|
|
115
|
+
this.#accessibleName = data.accessibleName;
|
|
116
|
+
this.#throttlerTimeout = data.throttlerTimeout;
|
|
117
|
+
this.#compact = Boolean(data.compact);
|
|
118
|
+
if (this.#issuesManager !== data.issuesManager) {
|
|
119
|
+
this.#issuesManager?.removeEventListener(
|
|
120
120
|
IssuesManager.IssuesManager.Events.IssuesCountUpdated, this.scheduleUpdate, this);
|
|
121
|
-
this
|
|
122
|
-
this
|
|
121
|
+
this.#issuesManager = data.issuesManager;
|
|
122
|
+
this.#issuesManager.addEventListener(
|
|
123
123
|
IssuesManager.IssuesManager.Events.IssuesCountUpdated, this.scheduleUpdate, this);
|
|
124
124
|
}
|
|
125
125
|
if (data.throttlerTimeout !== 0) {
|
|
126
|
-
this
|
|
126
|
+
this.#throttler = new Common.Throttler.Throttler(data.throttlerTimeout ?? 100);
|
|
127
127
|
} else {
|
|
128
|
-
this
|
|
128
|
+
this.#throttler = undefined;
|
|
129
129
|
}
|
|
130
130
|
this.scheduleUpdate();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
get data(): IssueCounterData {
|
|
134
134
|
return {
|
|
135
|
-
clickHandler: this
|
|
136
|
-
leadingText: this
|
|
137
|
-
tooltipCallback: this
|
|
138
|
-
displayMode: this
|
|
139
|
-
accessibleName: this
|
|
140
|
-
throttlerTimeout: this
|
|
141
|
-
compact: this
|
|
142
|
-
issuesManager: this
|
|
135
|
+
clickHandler: this.#clickHandler,
|
|
136
|
+
leadingText: this.#leadingText,
|
|
137
|
+
tooltipCallback: this.#tooltipCallback,
|
|
138
|
+
displayMode: this.#displayMode,
|
|
139
|
+
accessibleName: this.#accessibleName,
|
|
140
|
+
throttlerTimeout: this.#throttlerTimeout,
|
|
141
|
+
compact: this.#compact,
|
|
142
|
+
issuesManager: this.#issuesManager as IssuesManager.IssuesManager.IssuesManager,
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
private render(): void {
|
|
147
|
-
if (!this
|
|
147
|
+
if (!this.#issuesManager) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
this
|
|
151
|
-
this
|
|
152
|
-
this
|
|
153
|
-
this
|
|
150
|
+
this.#counts = [
|
|
151
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.PageError),
|
|
152
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.BreakingChange),
|
|
153
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.Improvement),
|
|
154
154
|
];
|
|
155
155
|
const importance = [
|
|
156
156
|
IssuesManager.Issue.IssueKind.PageError,
|
|
157
157
|
IssuesManager.Issue.IssueKind.BreakingChange,
|
|
158
158
|
IssuesManager.Issue.IssueKind.Improvement,
|
|
159
159
|
];
|
|
160
|
-
const mostImportant = importance[this
|
|
160
|
+
const mostImportant = importance[this.#counts.findIndex(x => x > 0) ?? 2];
|
|
161
161
|
|
|
162
162
|
const countToString = (kind: IssuesManager.Issue.IssueKind, count: number): string|undefined => {
|
|
163
|
-
switch (this
|
|
163
|
+
switch (this.#displayMode) {
|
|
164
164
|
case DisplayMode.OmitEmpty:
|
|
165
165
|
return count > 0 ? `${count}` : undefined;
|
|
166
166
|
case DisplayMode.ShowAlways:
|
|
@@ -174,29 +174,29 @@ export class IssueCounter extends HTMLElement {
|
|
|
174
174
|
groups: [
|
|
175
175
|
{
|
|
176
176
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.PageError), iconSize),
|
|
177
|
-
text: countToString(IssuesManager.Issue.IssueKind.PageError, this
|
|
177
|
+
text: countToString(IssuesManager.Issue.IssueKind.PageError, this.#counts[0]),
|
|
178
178
|
},
|
|
179
179
|
{
|
|
180
180
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.BreakingChange), iconSize),
|
|
181
|
-
text: countToString(IssuesManager.Issue.IssueKind.BreakingChange, this
|
|
181
|
+
text: countToString(IssuesManager.Issue.IssueKind.BreakingChange, this.#counts[1]),
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.Improvement), iconSize),
|
|
185
|
-
text: countToString(IssuesManager.Issue.IssueKind.Improvement, this
|
|
185
|
+
text: countToString(IssuesManager.Issue.IssueKind.Improvement, this.#counts[2]),
|
|
186
186
|
},
|
|
187
187
|
],
|
|
188
|
-
clickHandler: this
|
|
189
|
-
leadingText: this
|
|
190
|
-
accessibleName: this
|
|
191
|
-
compact: this
|
|
188
|
+
clickHandler: this.#clickHandler,
|
|
189
|
+
leadingText: this.#leadingText,
|
|
190
|
+
accessibleName: this.#accessibleName,
|
|
191
|
+
compact: this.#compact,
|
|
192
192
|
};
|
|
193
193
|
LitHtml.render(
|
|
194
194
|
LitHtml.html`
|
|
195
195
|
<icon-button .data=${data as IconButton.IconButton.IconButtonData} .accessibleName="${
|
|
196
|
-
this
|
|
196
|
+
this.#accessibleName}"></icon-button>
|
|
197
197
|
`,
|
|
198
|
-
this
|
|
199
|
-
this
|
|
198
|
+
this.#shadow, {host: this});
|
|
199
|
+
this.#tooltipCallback?.();
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -51,79 +51,79 @@ const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
|
|
|
51
51
|
|
|
52
52
|
export class IssueLinkIcon extends HTMLElement {
|
|
53
53
|
static readonly litTagName = LitHtml.literal`devtools-issue-link-icon`;
|
|
54
|
-
|
|
54
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
55
55
|
// The value `null` indicates that the issue is not available,
|
|
56
56
|
// `undefined` that it is still being resolved.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
#issue?: IssuesManager.Issue.Issue|null;
|
|
58
|
+
#issueTitle: string|null = null;
|
|
59
|
+
#issueTitlePromise = Promise.resolve<void>(undefined);
|
|
60
|
+
#issueId?: Protocol.Audits.IssueId;
|
|
61
|
+
#issueResolver?: IssuesManager.IssueResolver.IssueResolver;
|
|
62
|
+
#additionalOnClickAction?: () => void;
|
|
63
|
+
#reveal = Common.Revealer.reveal;
|
|
64
|
+
#issueResolvedPromise = Promise.resolve<void>(undefined);
|
|
65
65
|
|
|
66
66
|
set data(data: IssueLinkIconData) {
|
|
67
|
-
this
|
|
68
|
-
this
|
|
69
|
-
if (!this
|
|
67
|
+
this.#issue = data.issue;
|
|
68
|
+
this.#issueId = data.issueId;
|
|
69
|
+
if (!this.#issue && !this.#issueId) {
|
|
70
70
|
throw new Error('Either `issue` or `issueId` must be provided');
|
|
71
71
|
}
|
|
72
|
-
this
|
|
73
|
-
this
|
|
72
|
+
this.#issueResolver = data.issueResolver;
|
|
73
|
+
this.#additionalOnClickAction = data.additionalOnClickAction;
|
|
74
74
|
if (data.revealOverride) {
|
|
75
|
-
this
|
|
75
|
+
this.#reveal = data.revealOverride;
|
|
76
76
|
}
|
|
77
|
-
if (!this
|
|
78
|
-
this
|
|
79
|
-
this
|
|
77
|
+
if (!this.#issue && this.#issueId) {
|
|
78
|
+
this.#issueResolvedPromise = this.resolveIssue(this.#issueId);
|
|
79
|
+
this.#issueTitlePromise = this.#issueResolvedPromise.then(() => this.fetchIssueTitle());
|
|
80
80
|
} else {
|
|
81
|
-
this
|
|
81
|
+
this.#issueTitlePromise = this.fetchIssueTitle();
|
|
82
82
|
}
|
|
83
83
|
this.render();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
private async fetchIssueTitle(): Promise<void> {
|
|
87
|
-
const description = this
|
|
87
|
+
const description = this.#issue?.getDescription();
|
|
88
88
|
if (!description) {
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
const title = await IssuesManager.MarkdownIssueDescription.getIssueTitleFromMarkdownDescription(description);
|
|
92
92
|
if (title) {
|
|
93
|
-
this
|
|
93
|
+
this.#issueTitle = title;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
connectedCallback(): void {
|
|
98
|
-
this
|
|
98
|
+
this.#shadow.adoptedStyleSheets = [IssueLinkIconStyles];
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
private resolveIssue(issueId: Protocol.Audits.IssueId): Promise<void> {
|
|
102
|
-
if (!this
|
|
102
|
+
if (!this.#issueResolver) {
|
|
103
103
|
throw new Error('An `IssueResolver` must be provided if an `issueId` is provided.');
|
|
104
104
|
}
|
|
105
|
-
return this
|
|
105
|
+
return this.#issueResolver.waitFor(issueId)
|
|
106
106
|
.then(issue => {
|
|
107
|
-
this
|
|
107
|
+
this.#issue = issue;
|
|
108
108
|
})
|
|
109
109
|
.catch(() => {
|
|
110
|
-
this
|
|
110
|
+
this.#issue = null;
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
get data(): IssueLinkIconData {
|
|
115
115
|
return {
|
|
116
|
-
issue: this
|
|
117
|
-
issueId: this
|
|
118
|
-
issueResolver: this
|
|
119
|
-
additionalOnClickAction: this
|
|
120
|
-
revealOverride: this
|
|
116
|
+
issue: this.#issue,
|
|
117
|
+
issueId: this.#issueId,
|
|
118
|
+
issueResolver: this.#issueResolver,
|
|
119
|
+
additionalOnClickAction: this.#additionalOnClickAction,
|
|
120
|
+
revealOverride: this.#reveal !== Common.Revealer.reveal ? this.#reveal : undefined,
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
iconData(): IconButton.Icon.IconData {
|
|
125
|
-
if (this
|
|
126
|
-
return getIssueKindIconData(this
|
|
125
|
+
if (this.#issue) {
|
|
126
|
+
return getIssueKindIconData(this.#issue.getKind());
|
|
127
127
|
}
|
|
128
128
|
return {iconName: 'issue-questionmark-icon', color: 'var(--color-text-secondary)', width: '16px', height: '16px'};
|
|
129
129
|
}
|
|
@@ -132,17 +132,17 @@ export class IssueLinkIcon extends HTMLElement {
|
|
|
132
132
|
if (event.button !== 0) {
|
|
133
133
|
return; // Only handle left-click for now.
|
|
134
134
|
}
|
|
135
|
-
if (this
|
|
136
|
-
this
|
|
135
|
+
if (this.#issue) {
|
|
136
|
+
this.#reveal(this.#issue);
|
|
137
137
|
}
|
|
138
|
-
this
|
|
138
|
+
this.#additionalOnClickAction?.();
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
private getTooltip(): Platform.UIString.LocalizedString {
|
|
142
|
-
if (this
|
|
143
|
-
return i18nString(UIStrings.clickToShowIssueWithTitle, {title: this
|
|
142
|
+
if (this.#issueTitle) {
|
|
143
|
+
return i18nString(UIStrings.clickToShowIssueWithTitle, {title: this.#issueTitle});
|
|
144
144
|
}
|
|
145
|
-
if (this
|
|
145
|
+
if (this.#issue) {
|
|
146
146
|
return i18nString(UIStrings.clickToShowIssue);
|
|
147
147
|
}
|
|
148
148
|
return i18nString(UIStrings.issueUnavailable);
|
|
@@ -152,9 +152,9 @@ export class IssueLinkIcon extends HTMLElement {
|
|
|
152
152
|
return coordinator.write(() => {
|
|
153
153
|
// clang-format off
|
|
154
154
|
LitHtml.render(LitHtml.html`
|
|
155
|
-
${LitHtml.Directives.until(this
|
|
155
|
+
${LitHtml.Directives.until(this.#issueTitlePromise.then(() => this.renderComponent()), this.#issueResolvedPromise.then(() => this.renderComponent()), this.renderComponent())}
|
|
156
156
|
`,
|
|
157
|
-
this
|
|
157
|
+
this.#shadow, {host: this});
|
|
158
158
|
// clang-format on
|
|
159
159
|
});
|
|
160
160
|
}
|
|
@@ -162,7 +162,7 @@ export class IssueLinkIcon extends HTMLElement {
|
|
|
162
162
|
private renderComponent(): LitHtml.TemplateResult {
|
|
163
163
|
// clang-format off
|
|
164
164
|
return LitHtml.html`
|
|
165
|
-
<span class=${LitHtml.Directives.classMap({'link': Boolean(this
|
|
165
|
+
<span class=${LitHtml.Directives.classMap({'link': Boolean(this.#issue)})}
|
|
166
166
|
tabindex="0"
|
|
167
167
|
@click=${this.handleClick}>
|
|
168
168
|
<${IconButton.Icon.Icon.litTagName} .data=${this.iconData() as IconButton.Icon.IconData}
|
|
@@ -82,15 +82,15 @@ export class SettingsChangedEvent extends Event {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
class AddressHistoryEntry implements Common.SimpleHistoryManager.HistoryEntry {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
#address = 0;
|
|
86
|
+
#callback;
|
|
87
87
|
|
|
88
88
|
constructor(address: number, callback: (x: number) => void) {
|
|
89
89
|
if (address < 0) {
|
|
90
90
|
throw new Error('Address should be a greater or equal to zero');
|
|
91
91
|
}
|
|
92
|
-
this
|
|
93
|
-
this
|
|
92
|
+
this.#address = address;
|
|
93
|
+
this.#callback = callback;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
valid(): boolean {
|
|
@@ -98,32 +98,32 @@ class AddressHistoryEntry implements Common.SimpleHistoryManager.HistoryEntry {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
reveal(): void {
|
|
101
|
-
this
|
|
101
|
+
this.#callback(this.#address);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
export class LinearMemoryInspector extends HTMLElement {
|
|
106
106
|
static readonly litTagName = LitHtml.literal`devtools-linear-memory-inspector-inspector`;
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
108
|
+
readonly #history = new Common.SimpleHistoryManager.SimpleHistoryManager(10);
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
#memory = new Uint8Array();
|
|
111
|
+
#memoryOffset = 0;
|
|
112
|
+
#outerMemoryLength = 0;
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
#address = -1;
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
#currentNavigatorMode = Mode.Submitted;
|
|
117
|
+
#currentNavigatorAddressLine = `${this.#address}`;
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
#numBytesPerPage = 4;
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
#valueTypeModes = getDefaultValueTypeMapping();
|
|
122
|
+
#valueTypes = new Set(this.#valueTypeModes.keys());
|
|
123
|
+
#endianness = Endianness.Little;
|
|
124
124
|
|
|
125
125
|
connectedCallback(): void {
|
|
126
|
-
this
|
|
126
|
+
this.#shadow.adoptedStyleSheets = [linearMemoryInspectorStyles];
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
set data(data: LinearMemoryInspectorData) {
|
|
@@ -135,43 +135,43 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
135
135
|
throw new Error('Memory offset has to be greater or equal to zero.');
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
this
|
|
139
|
-
this
|
|
140
|
-
this
|
|
141
|
-
this
|
|
142
|
-
this
|
|
143
|
-
this
|
|
138
|
+
this.#memory = data.memory;
|
|
139
|
+
this.#memoryOffset = data.memoryOffset;
|
|
140
|
+
this.#outerMemoryLength = data.outerMemoryLength;
|
|
141
|
+
this.#valueTypeModes = data.valueTypeModes || this.#valueTypeModes;
|
|
142
|
+
this.#valueTypes = data.valueTypes || this.#valueTypes;
|
|
143
|
+
this.#endianness = data.endianness || this.#endianness;
|
|
144
144
|
this.setAddress(data.address);
|
|
145
145
|
this.render();
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
private render(): void {
|
|
149
|
-
const {start, end} = this.getPageRangeForAddress(this
|
|
149
|
+
const {start, end} = this.getPageRangeForAddress(this.#address, this.#numBytesPerPage);
|
|
150
150
|
|
|
151
|
-
const navigatorAddressToShow =
|
|
152
|
-
|
|
151
|
+
const navigatorAddressToShow = this.#currentNavigatorMode === Mode.Submitted ? formatAddress(this.#address) :
|
|
152
|
+
this.#currentNavigatorAddressLine;
|
|
153
153
|
const navigatorAddressIsValid = this.isValidAddress(navigatorAddressToShow);
|
|
154
154
|
|
|
155
155
|
const invalidAddressMsg = i18nString(
|
|
156
156
|
UIStrings.addressHasToBeANumberBetweenSAnd,
|
|
157
|
-
{PH1: formatAddress(0), PH2: formatAddress(this
|
|
157
|
+
{PH1: formatAddress(0), PH2: formatAddress(this.#outerMemoryLength)});
|
|
158
158
|
|
|
159
159
|
const errorMsg = navigatorAddressIsValid ? undefined : invalidAddressMsg;
|
|
160
160
|
|
|
161
|
-
const canGoBackInHistory = this
|
|
162
|
-
const canGoForwardInHistory = this
|
|
161
|
+
const canGoBackInHistory = this.#history.canRollback();
|
|
162
|
+
const canGoForwardInHistory = this.#history.canRollover();
|
|
163
163
|
// Disabled until https://crbug.com/1079231 is fixed.
|
|
164
164
|
// clang-format off
|
|
165
165
|
render(html`
|
|
166
166
|
<div class="view">
|
|
167
167
|
<${LinearMemoryNavigator.litTagName}
|
|
168
|
-
.data=${{address: navigatorAddressToShow, valid: navigatorAddressIsValid, mode: this
|
|
168
|
+
.data=${{address: navigatorAddressToShow, valid: navigatorAddressIsValid, mode: this.#currentNavigatorMode, error: errorMsg, canGoBackInHistory, canGoForwardInHistory} as LinearMemoryNavigatorData}
|
|
169
169
|
@refreshrequested=${this.onRefreshRequest}
|
|
170
170
|
@addressinputchanged=${this.onAddressChange}
|
|
171
171
|
@pagenavigation=${this.navigatePage}
|
|
172
172
|
@historynavigation=${this.navigateHistory}></${LinearMemoryNavigator.litTagName}>
|
|
173
173
|
<${LinearMemoryViewer.litTagName}
|
|
174
|
-
.data=${{memory: this
|
|
174
|
+
.data=${{memory: this.#memory.slice(start - this.#memoryOffset, end - this.#memoryOffset), address: this.#address, memoryOffset: start, focus: this.#currentNavigatorMode === Mode.Submitted} as LinearMemoryViewerData}
|
|
175
175
|
@byteselected=${this.onByteSelected}
|
|
176
176
|
@resize=${this.resize}>
|
|
177
177
|
</${LinearMemoryViewer.litTagName}>
|
|
@@ -179,11 +179,11 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
179
179
|
<div class="value-interpreter">
|
|
180
180
|
<${LinearMemoryValueInterpreter.litTagName}
|
|
181
181
|
.data=${{
|
|
182
|
-
value: this
|
|
183
|
-
valueTypes: this
|
|
184
|
-
valueTypeModes: this
|
|
185
|
-
endianness: this
|
|
186
|
-
memoryLength: this
|
|
182
|
+
value: this.#memory.slice(this.#address - this.#memoryOffset, this.#address + VALUE_INTEPRETER_MAX_NUM_BYTES).buffer,
|
|
183
|
+
valueTypes: this.#valueTypes,
|
|
184
|
+
valueTypeModes: this.#valueTypeModes,
|
|
185
|
+
endianness: this.#endianness,
|
|
186
|
+
memoryLength: this.#outerMemoryLength } as LinearMemoryValueInterpreterData}
|
|
187
187
|
@valuetypetoggled=${this.onValueTypeToggled}
|
|
188
188
|
@valuetypemodechanged=${this.onValueTypeModeChanged}
|
|
189
189
|
@endiannesschanged=${this.onEndiannessChanged}
|
|
@@ -191,7 +191,7 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
191
191
|
>
|
|
192
192
|
</${LinearMemoryValueInterpreter.litTagName}/>
|
|
193
193
|
</div>
|
|
194
|
-
`, this
|
|
194
|
+
`, this.#shadow, {
|
|
195
195
|
host: this,
|
|
196
196
|
});
|
|
197
197
|
// clang-format on
|
|
@@ -200,53 +200,53 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
200
200
|
private onJumpToPointerAddress(e: JumpToPointerAddressEvent): void {
|
|
201
201
|
// Stop event from bubbling up, since no element further up needs the event.
|
|
202
202
|
e.stopPropagation();
|
|
203
|
-
this
|
|
204
|
-
const addressInRange = Math.max(0, Math.min(e.data, this
|
|
203
|
+
this.#currentNavigatorMode = Mode.Submitted;
|
|
204
|
+
const addressInRange = Math.max(0, Math.min(e.data, this.#outerMemoryLength - 1));
|
|
205
205
|
this.jumpToAddress(addressInRange);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
private onRefreshRequest(): void {
|
|
209
|
-
const {start, end} = this.getPageRangeForAddress(this
|
|
210
|
-
this.dispatchEvent(new MemoryRequestEvent(start, end, this
|
|
209
|
+
const {start, end} = this.getPageRangeForAddress(this.#address, this.#numBytesPerPage);
|
|
210
|
+
this.dispatchEvent(new MemoryRequestEvent(start, end, this.#address));
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
private onByteSelected(e: ByteSelectedEvent): void {
|
|
214
|
-
this
|
|
215
|
-
const addressInRange = Math.max(0, Math.min(e.data, this
|
|
214
|
+
this.#currentNavigatorMode = Mode.Submitted;
|
|
215
|
+
const addressInRange = Math.max(0, Math.min(e.data, this.#outerMemoryLength - 1));
|
|
216
216
|
this.jumpToAddress(addressInRange);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
private createSettings(): Settings {
|
|
220
|
-
return {valueTypes: this
|
|
220
|
+
return {valueTypes: this.#valueTypes, modes: this.#valueTypeModes, endianness: this.#endianness};
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
private onEndiannessChanged(e: EndiannessChangedEvent): void {
|
|
224
|
-
this
|
|
224
|
+
this.#endianness = e.data;
|
|
225
225
|
this.dispatchEvent(new SettingsChangedEvent(this.createSettings()));
|
|
226
226
|
this.render();
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
private isValidAddress(address: string): boolean {
|
|
230
230
|
const newAddress = parseAddress(address);
|
|
231
|
-
return newAddress !== undefined && newAddress >= 0 && newAddress < this
|
|
231
|
+
return newAddress !== undefined && newAddress >= 0 && newAddress < this.#outerMemoryLength;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
private onAddressChange(e: AddressInputChangedEvent): void {
|
|
235
235
|
const {address, mode} = e.data;
|
|
236
236
|
const isValid = this.isValidAddress(address);
|
|
237
237
|
const newAddress = parseAddress(address);
|
|
238
|
-
this
|
|
238
|
+
this.#currentNavigatorAddressLine = address;
|
|
239
239
|
|
|
240
240
|
if (newAddress !== undefined && isValid) {
|
|
241
|
-
this
|
|
241
|
+
this.#currentNavigatorMode = mode;
|
|
242
242
|
this.jumpToAddress(newAddress);
|
|
243
243
|
return;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
if (mode === Mode.Submitted && !isValid) {
|
|
247
|
-
this
|
|
247
|
+
this.#currentNavigatorMode = Mode.InvalidSubmit;
|
|
248
248
|
} else {
|
|
249
|
-
this
|
|
249
|
+
this.#currentNavigatorMode = Mode.Edit;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
this.render();
|
|
@@ -255,9 +255,9 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
255
255
|
private onValueTypeToggled(e: ValueTypeToggledEvent): void {
|
|
256
256
|
const {type, checked} = e.data;
|
|
257
257
|
if (checked) {
|
|
258
|
-
this
|
|
258
|
+
this.#valueTypes.add(type);
|
|
259
259
|
} else {
|
|
260
|
-
this
|
|
260
|
+
this.#valueTypes.delete(type);
|
|
261
261
|
}
|
|
262
262
|
this.dispatchEvent(new SettingsChangedEvent(this.createSettings()));
|
|
263
263
|
this.render();
|
|
@@ -266,24 +266,24 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
266
266
|
private onValueTypeModeChanged(e: ValueTypeModeChangedEvent): void {
|
|
267
267
|
e.stopImmediatePropagation();
|
|
268
268
|
const {type, mode} = e.data;
|
|
269
|
-
this
|
|
269
|
+
this.#valueTypeModes.set(type, mode);
|
|
270
270
|
this.dispatchEvent(new SettingsChangedEvent(this.createSettings()));
|
|
271
271
|
this.render();
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
private navigateHistory(e: HistoryNavigationEvent): boolean {
|
|
275
|
-
return e.data === Navigation.Forward ? this
|
|
275
|
+
return e.data === Navigation.Forward ? this.#history.rollover() : this.#history.rollback();
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
private navigatePage(e: PageNavigationEvent): void {
|
|
279
279
|
const newAddress =
|
|
280
|
-
e.data === Navigation.Forward ? this
|
|
281
|
-
const addressInRange = Math.max(0, Math.min(newAddress, this
|
|
280
|
+
e.data === Navigation.Forward ? this.#address + this.#numBytesPerPage : this.#address - this.#numBytesPerPage;
|
|
281
|
+
const addressInRange = Math.max(0, Math.min(newAddress, this.#outerMemoryLength - 1));
|
|
282
282
|
this.jumpToAddress(addressInRange);
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
private jumpToAddress(address: number): void {
|
|
286
|
-
if (address < 0 || address >= this
|
|
286
|
+
if (address < 0 || address >= this.#outerMemoryLength) {
|
|
287
287
|
console.warn(`Specified address is out of bounds: ${address}`);
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
@@ -294,19 +294,19 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
294
294
|
private getPageRangeForAddress(address: number, numBytesPerPage: number): {start: number, end: number} {
|
|
295
295
|
const pageNumber = Math.floor(address / numBytesPerPage);
|
|
296
296
|
const pageStartAddress = pageNumber * numBytesPerPage;
|
|
297
|
-
const pageEndAddress = Math.min(pageStartAddress + numBytesPerPage, this
|
|
297
|
+
const pageEndAddress = Math.min(pageStartAddress + numBytesPerPage, this.#outerMemoryLength);
|
|
298
298
|
return {start: pageStartAddress, end: pageEndAddress};
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
private resize(event: ResizeEvent): void {
|
|
302
|
-
this
|
|
302
|
+
this.#numBytesPerPage = event.data;
|
|
303
303
|
this.update();
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
private update(): void {
|
|
307
|
-
const {start, end} = this.getPageRangeForAddress(this
|
|
308
|
-
if (start < this
|
|
309
|
-
this.dispatchEvent(new MemoryRequestEvent(start, end, this
|
|
307
|
+
const {start, end} = this.getPageRangeForAddress(this.#address, this.#numBytesPerPage);
|
|
308
|
+
if (start < this.#memoryOffset || end > this.#memoryOffset + this.#memory.length) {
|
|
309
|
+
this.dispatchEvent(new MemoryRequestEvent(start, end, this.#address));
|
|
310
310
|
} else {
|
|
311
311
|
this.render();
|
|
312
312
|
}
|
|
@@ -314,13 +314,13 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
|
314
314
|
|
|
315
315
|
private setAddress(address: number): void {
|
|
316
316
|
// If we are already showing the address that is requested, no need to act upon it.
|
|
317
|
-
if (this
|
|
317
|
+
if (this.#address === address) {
|
|
318
318
|
return;
|
|
319
319
|
}
|
|
320
320
|
const historyEntry = new AddressHistoryEntry(address, () => this.jumpToAddress(address));
|
|
321
|
-
this
|
|
322
|
-
this
|
|
323
|
-
this.dispatchEvent(new AddressChangedEvent(this
|
|
321
|
+
this.#history.push(historyEntry);
|
|
322
|
+
this.#address = address;
|
|
323
|
+
this.dispatchEvent(new AddressChangedEvent(this.#address));
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
|