豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 5391300

Browse files
szuendDevtools-frontend LUCI CQ
authored andcommitted
[ui] Migrate fragment rendering of StackTracePreviewContent to lit
This CL finishes the Lit migration of StackTracePreviewwContent. R=pfaffe@chromium.org Fixed: 483576322 Change-Id: I1640340383c61916e0255e3a078cc0adf121804a Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7595295 Commit-Queue: Simon Zünd <szuend@chromium.org> Reviewed-by: Philip Pfaffe <pfaffe@chromium.org>
1 parent 2fac722 commit 5391300

File tree

1 file changed

+55
-86
lines changed

1 file changed

+55
-86
lines changed

front_end/ui/legacy/components/utils/JSPresentationUtils.ts

Lines changed: 55 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import * as i18n from '../../../../core/i18n/i18n.js';
3737
import * as SDK from '../../../../core/sdk/sdk.js';
3838
import * as StackTrace from '../../../../models/stack_trace/stack_trace.js';
3939
import * as Workspace from '../../../../models/workspace/workspace.js';
40-
import {Directives, html, nothing, render} from '../../../lit/lit.js';
40+
import {Directives, html, nothing, render, type TemplateResult} from '../../../lit/lit.js';
4141
import * as VisualLogging from '../../../visual_logging/visual_logging.js';
4242
import * as UI from '../../legacy.js';
4343

@@ -107,19 +107,71 @@ export interface ViewInput {
107107
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
108108

109109
export const DEFAULT_VIEW: View = (input, output, target) => {
110+
let renderExpandButton = Boolean(input.expandable);
111+
const maybeRenderExpandButton = (): TemplateResult => {
112+
// clang-format off
113+
const result = html`
114+
${renderExpandButton ? html`
115+
<button class="arrow-icon-button" jslog=${VisualLogging.expand().track({click: true})} @click=${input.onExpand}>
116+
<span class="arrow-icon"></span>
117+
</button>
118+
` : '\n'}`;
119+
// clang-format on
120+
renderExpandButton = false;
121+
return result;
122+
};
123+
110124
const classes = {
111125
'stack-preview-container': true,
112126
'width-constrained': Boolean(input.widthConstrained),
113127
expandable: Boolean(input.expandable),
114128
expanded: Boolean(input.expanded),
115129
'show-hidden-rows': Boolean(input.showIgnoreListed),
116130
};
131+
const {stackTrace} = input;
117132
// clang-format off
118133
render(html`
119134
<style>${jsUtilsStyles}</style>
120135
<table class=${classMap(classes)}>
121-
${renderStackTraceTable(input)}
122-
${input.stackTrace ? html`
136+
${stackTrace ? html`
137+
${[stackTrace.syncFragment, ...stackTrace.asyncFragments].map(fragment => html`
138+
<tbody>
139+
${'description' in fragment ? html`
140+
<tr class="stack-preview-async-row">
141+
<td>${maybeRenderExpandButton()}</td>
142+
<td class="stack-preview-async-description">
143+
${UI.UIUtils.asyncFragmentLabel(stackTrace, fragment as StackTrace.StackTrace.AsyncFragment)}
144+
</td>
145+
<td></td>
146+
<td></td>
147+
</tr>
148+
` : nothing}
149+
${fragment.frames.map((frame, i) => {
150+
const previousStackFrameWasBreakpointCondition = i > 0 && [
151+
SDK.DebuggerModel.COND_BREAKPOINT_SOURCE_URL,
152+
SDK.DebuggerModel.LOGPOINT_SOURCE_URL,
153+
].includes(fragment.frames[i - 1].url ?? '');
154+
const link = Linkifier.linkifyStackTraceFrame(frame, {
155+
showColumnNumber: Boolean(input.showColumnNumber),
156+
tabStop: Boolean(input.tabStops),
157+
inlineFrameIndex: 0,
158+
revealBreakpoint: previousStackFrameWasBreakpointCondition,
159+
maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
160+
});
161+
link.setAttribute('jslog', `${VisualLogging.link('stack-trace').track({click: true})}`);
162+
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
163+
return html`
164+
<tr>
165+
<td>${maybeRenderExpandButton()}</td>
166+
<td class="function-name">
167+
${UI.UIUtils.beautifyFunctionName(frame.name ?? '')}
168+
</td>
169+
<td> @ </td>
170+
<td class="link">${link}</td>
171+
</tr>
172+
`;})}
173+
</tbody>
174+
`)}
123175
<tfoot>
124176
<tr class="show-all-link">
125177
<td></td>
@@ -144,80 +196,6 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
144196
// clang-format on
145197
};
146198

147-
function renderStackTraceTable(options: ViewInput): DocumentFragment {
148-
const container = document.createDocumentFragment();
149-
150-
if (!options.stackTrace) {
151-
return container;
152-
}
153-
const {stackTrace} = options;
154-
155-
function buildStackTraceRowsHelper(fragment: StackTrace.StackTrace.Fragment|StackTrace.StackTrace.AsyncFragment):
156-
Array<StackTraceRegularRow|StackTraceAsyncRow> {
157-
const stackTraceRows: Array<StackTraceRegularRow|StackTraceAsyncRow> = [];
158-
if ('description' in fragment) {
159-
stackTraceRows.push({asyncDescription: UI.UIUtils.asyncFragmentLabel(stackTrace, fragment)});
160-
}
161-
let previousStackFrameWasBreakpointCondition = false;
162-
for (const frame of fragment.frames) {
163-
const functionName = UI.UIUtils.beautifyFunctionName(frame.name ?? '');
164-
const link = Linkifier.linkifyStackTraceFrame(frame, {
165-
showColumnNumber: Boolean(options.showColumnNumber),
166-
tabStop: Boolean(options.tabStops),
167-
inlineFrameIndex: 0,
168-
revealBreakpoint: previousStackFrameWasBreakpointCondition,
169-
maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
170-
});
171-
link.setAttribute('jslog', `${VisualLogging.link('stack-trace').track({click: true})}`);
172-
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
173-
174-
stackTraceRows.push({functionName, link});
175-
previousStackFrameWasBreakpointCondition = [
176-
SDK.DebuggerModel.COND_BREAKPOINT_SOURCE_URL,
177-
SDK.DebuggerModel.LOGPOINT_SOURCE_URL,
178-
].includes(frame.url ?? '');
179-
}
180-
181-
return stackTraceRows;
182-
}
183-
184-
// The tableSection groups one or more synchronous call frames together.
185-
// Wherever there is an asynchronous call, a new section is created.
186-
let firstRow = true;
187-
for (const fragment of [stackTrace.syncFragment, ...stackTrace.asyncFragments]) {
188-
if (fragment.frames.length === 0) {
189-
continue;
190-
}
191-
192-
const stackTraceRows = buildStackTraceRowsHelper(fragment);
193-
const tableSection = container.createChild('tbody');
194-
for (const item of stackTraceRows) {
195-
const row = tableSection.createChild('tr');
196-
if (firstRow && options.expandable) {
197-
const button = row.createChild('td').createChild('button', 'arrow-icon-button');
198-
button.createChild('span', 'arrow-icon');
199-
button.setAttribute('jslog', `${VisualLogging.expand().track({click: true})}`);
200-
button.addEventListener('click', options.onExpand);
201-
firstRow = false;
202-
} else {
203-
row.createChild('td').textContent = '\n';
204-
}
205-
if ('asyncDescription' in item) {
206-
row.createChild('td', 'stack-preview-async-description').textContent = item.asyncDescription;
207-
row.createChild('td');
208-
row.createChild('td');
209-
row.classList.add('stack-preview-async-row');
210-
} else {
211-
row.createChild('td', 'function-name').textContent = item.functionName;
212-
row.createChild('td').textContent = ' @ ';
213-
row.createChild('td', 'link').appendChild(item.link);
214-
}
215-
}
216-
}
217-
218-
return container;
219-
}
220-
221199
export interface Options {
222200
tabStops?: boolean;
223201
// Whether the width of stack trace preview
@@ -228,15 +206,6 @@ export interface Options {
228206
expandable?: boolean;
229207
}
230208

231-
interface StackTraceRegularRow {
232-
functionName: string;
233-
link: HTMLElement;
234-
}
235-
236-
interface StackTraceAsyncRow {
237-
asyncDescription: string;
238-
}
239-
240209
export class StackTracePreviewContent extends UI.Widget.Widget {
241210
readonly #view: View;
242211

0 commit comments

Comments
 (0)