chrome-devtools-frontend 1.0.1586699 → 1.0.1587905
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/front_end/core/sdk/ScopeTreeCache.ts +4 -0
- package/front_end/entrypoint_template.html +5 -1
- package/front_end/generated/Deprecation.ts +21 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +2 -0
- package/front_end/models/ai_assistance/AiConversation.ts +5 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +16 -4
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +7 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +0 -2
- package/front_end/panels/ai_assistance/components/ChatInput.ts +36 -31
- package/front_end/panels/ai_assistance/components/chatInput.css +6 -9
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -6
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +11 -3
- package/front_end/panels/common/DOMLinkifier.ts +6 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +25 -2
- package/front_end/panels/elements/ElementsPanel.ts +114 -15
- package/front_end/panels/elements/PropertiesWidget.ts +40 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +26 -3
- package/front_end/panels/network/NetworkDataGridNode.ts +4 -0
- package/front_end/panels/network/NetworkItemView.ts +6 -44
- package/front_end/panels/network/RequestHeadersView.ts +499 -0
- package/front_end/panels/network/components/RequestHeaderSection.ts +3 -0
- package/front_end/panels/network/components/components.ts +0 -2
- package/front_end/panels/network/network.ts +3 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +37 -5
- package/front_end/ui/legacy/UIUtils.ts +35 -5
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +113 -133
- package/package.json +1 -1
- package/front_end/panels/network/components/RequestHeadersView.ts +0 -569
|
@@ -40,6 +40,10 @@ const UIStrings = {
|
|
|
40
40
|
* @description Placeholder for filter bars that shows before the user types in a filter keyword.
|
|
41
41
|
*/
|
|
42
42
|
filter: 'Filter',
|
|
43
|
+
/**
|
|
44
|
+
* @description Tooltip shown when the user hovers over the regex icon to toggle regular-expression filtering.
|
|
45
|
+
*/
|
|
46
|
+
useRegularExpression: 'Use regular expression',
|
|
43
47
|
} as const;
|
|
44
48
|
const str_ = i18n.i18n.registerUIStrings('ui/legacy/Toolbar.ts', UIStrings);
|
|
45
49
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -693,7 +697,6 @@ export namespace ToolbarButton {
|
|
|
693
697
|
export class ToolbarInput extends ToolbarItem<ToolbarInput.EventTypes> {
|
|
694
698
|
private prompt: TextPrompt;
|
|
695
699
|
private readonly proxyElement: Element;
|
|
696
|
-
|
|
697
700
|
constructor(
|
|
698
701
|
placeholder: string, accessiblePlaceholder?: string, growFactor?: number, shrinkFactor?: number, tooltip?: string,
|
|
699
702
|
completions?: ((arg0: string, arg1: string, arg2?: boolean|undefined) => Promise<Suggestion[]>),
|
|
@@ -759,6 +762,10 @@ export class ToolbarInput extends ToolbarItem<ToolbarInput.EventTypes> {
|
|
|
759
762
|
this.updateEmptyStyles();
|
|
760
763
|
}
|
|
761
764
|
|
|
765
|
+
protected insertTrailingElement(element: Element): void {
|
|
766
|
+
this.element.appendChild(element);
|
|
767
|
+
}
|
|
768
|
+
|
|
762
769
|
override applyEnabledState(enabled: boolean): void {
|
|
763
770
|
if (enabled) {
|
|
764
771
|
this.element.classList.remove('disabled');
|
|
@@ -818,7 +825,8 @@ export class ToolbarFilter extends ToolbarInput {
|
|
|
818
825
|
constructor(
|
|
819
826
|
filterBy?: Common.UIString.LocalizedString, growFactor?: number, shrinkFactor?: number, tooltip?: string,
|
|
820
827
|
completions?: ((arg0: string, arg1: string, arg2?: boolean|undefined) => Promise<Suggestion[]>),
|
|
821
|
-
dynamicCompletions?: boolean, jslogContext?: string, element?: HTMLElement
|
|
828
|
+
dynamicCompletions?: boolean, jslogContext?: string, element?: HTMLElement, showRegexToggle?: boolean,
|
|
829
|
+
onRegexToggle?: () => void) {
|
|
822
830
|
const filterPlaceholder = filterBy ? filterBy : i18nString(UIStrings.filter);
|
|
823
831
|
super(
|
|
824
832
|
filterPlaceholder, filterPlaceholder, growFactor, shrinkFactor, tooltip, completions, dynamicCompletions,
|
|
@@ -827,17 +835,36 @@ export class ToolbarFilter extends ToolbarInput {
|
|
|
827
835
|
const filterIcon = createIcon('filter');
|
|
828
836
|
this.element.prepend(filterIcon);
|
|
829
837
|
this.element.classList.add('toolbar-filter');
|
|
838
|
+
|
|
839
|
+
if (showRegexToggle) {
|
|
840
|
+
const regexIconName = 'regular-expression';
|
|
841
|
+
const regexButton = new Buttons.Button.Button();
|
|
842
|
+
regexButton.data = {
|
|
843
|
+
variant: Buttons.Button.Variant.ICON_TOGGLE,
|
|
844
|
+
size: Buttons.Button.Size.SMALL,
|
|
845
|
+
iconName: regexIconName,
|
|
846
|
+
toggledIconName: regexIconName,
|
|
847
|
+
toggleType: Buttons.Button.ToggleType.PRIMARY,
|
|
848
|
+
toggled: false,
|
|
849
|
+
title: i18nString(UIStrings.useRegularExpression),
|
|
850
|
+
jslogContext: regexIconName,
|
|
851
|
+
};
|
|
852
|
+
ARIAUtils.setLabel(regexButton, i18nString(UIStrings.useRegularExpression));
|
|
853
|
+
regexButton.addEventListener('click', () => {
|
|
854
|
+
onRegexToggle?.();
|
|
855
|
+
});
|
|
856
|
+
this.insertTrailingElement(regexButton);
|
|
857
|
+
}
|
|
830
858
|
}
|
|
831
859
|
}
|
|
832
860
|
|
|
833
861
|
export class ToolbarInputElement extends HTMLElement {
|
|
834
|
-
static observedAttributes = ['value', 'disabled'];
|
|
862
|
+
static observedAttributes = ['value', 'disabled', 'regex'];
|
|
835
863
|
|
|
836
864
|
item?: ToolbarInput;
|
|
837
865
|
datalist: HTMLDataListElement|null = null;
|
|
838
866
|
#value: string|undefined = undefined;
|
|
839
867
|
#disabled = false;
|
|
840
|
-
|
|
841
868
|
connectedCallback(): void {
|
|
842
869
|
if (this.item) {
|
|
843
870
|
return;
|
|
@@ -855,7 +882,8 @@ export class ToolbarInputElement extends HTMLElement {
|
|
|
855
882
|
this.item = new ToolbarFilter(
|
|
856
883
|
placeholder as Platform.UIString.LocalizedString, /* growFactor=*/ undefined,
|
|
857
884
|
/* shrinkFactor=*/ undefined, tooltip, this.datalist ? this.#onAutocomplete.bind(this) : undefined,
|
|
858
|
-
/* dynamicCompletions=*/ undefined, jslogContext || 'filter', this)
|
|
885
|
+
/* dynamicCompletions=*/ undefined, jslogContext || 'filter', this, this.hasAttribute('regex'),
|
|
886
|
+
this.#onRegexToggle.bind(this));
|
|
859
887
|
} else {
|
|
860
888
|
this.item = new ToolbarInput(
|
|
861
889
|
placeholder, accessiblePlaceholder, /* growFactor=*/ undefined,
|
|
@@ -880,6 +908,10 @@ export class ToolbarInputElement extends HTMLElement {
|
|
|
880
908
|
this.item?.focus();
|
|
881
909
|
}
|
|
882
910
|
|
|
911
|
+
#onRegexToggle(): void {
|
|
912
|
+
this.dispatchEvent(new CustomEvent('regextoggle'));
|
|
913
|
+
}
|
|
914
|
+
|
|
883
915
|
async #onAutocomplete(expression: string, prefix: string, force?: boolean): Promise<Suggestion[]> {
|
|
884
916
|
if (!prefix && !force && expression || !this.datalist) {
|
|
885
917
|
return [];
|
|
@@ -2034,8 +2034,8 @@ export class InterceptBindingDirective extends Lit.Directive.Directive {
|
|
|
2034
2034
|
}
|
|
2035
2035
|
|
|
2036
2036
|
/* eslint-disable-next-line @typescript-eslint/no-unsafe-function-type */
|
|
2037
|
-
render(
|
|
2038
|
-
return
|
|
2037
|
+
render(listener: Function): Function {
|
|
2038
|
+
return listener;
|
|
2039
2039
|
}
|
|
2040
2040
|
|
|
2041
2041
|
static setEventListeners(templateElement: Element, renderedElement: Element): void {
|
|
@@ -2092,7 +2092,17 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2092
2092
|
}
|
|
2093
2093
|
|
|
2094
2094
|
private static patchLitTemplate(template: Lit.LitTemplate): void {
|
|
2095
|
-
const
|
|
2095
|
+
const interceptingWrapper = Lit.Directive.directive(InterceptBindingDirective);
|
|
2096
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2097
|
+
const patchingWrapper = <Args extends any[], R>(fn: (...args: Args) => R): ((...args: Args) => R) => {
|
|
2098
|
+
return function(this: unknown, ...args: Args): R {
|
|
2099
|
+
const result = fn.apply(this, args);
|
|
2100
|
+
if (isLitTemplate(result)) {
|
|
2101
|
+
HTMLElementWithLightDOMTemplate.patchLitTemplate(result);
|
|
2102
|
+
}
|
|
2103
|
+
return result;
|
|
2104
|
+
};
|
|
2105
|
+
};
|
|
2096
2106
|
if (template === Lit.nothing) {
|
|
2097
2107
|
return;
|
|
2098
2108
|
}
|
|
@@ -2104,10 +2114,19 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2104
2114
|
value['_$litType$'] === 1);
|
|
2105
2115
|
}
|
|
2106
2116
|
|
|
2117
|
+
function isLitDirective(value: unknown): value is {values: unknown[]} {
|
|
2118
|
+
return Boolean(typeof value === 'object' && value && '_$litDirective$' in value && 'values' in value);
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2122
|
+
function isCallable(value: unknown): value is(...args: any[]) => any {
|
|
2123
|
+
return typeof value === 'function';
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2107
2126
|
function patchValue(value: unknown): unknown {
|
|
2108
|
-
if (
|
|
2127
|
+
if (isCallable(value)) {
|
|
2109
2128
|
try {
|
|
2110
|
-
return
|
|
2129
|
+
return interceptingWrapper(value);
|
|
2111
2130
|
} catch {
|
|
2112
2131
|
return value;
|
|
2113
2132
|
}
|
|
@@ -2116,6 +2135,17 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2116
2135
|
HTMLElementWithLightDOMTemplate.patchLitTemplate(value);
|
|
2117
2136
|
return value;
|
|
2118
2137
|
}
|
|
2138
|
+
if (isLitDirective(value)) {
|
|
2139
|
+
for (let i = 0; i < value.values.length; i++) {
|
|
2140
|
+
const subvalue = value.values[i];
|
|
2141
|
+
if (isCallable(subvalue)) {
|
|
2142
|
+
value.values[i] = patchingWrapper(subvalue);
|
|
2143
|
+
} else {
|
|
2144
|
+
value.values[i] = patchValue(subvalue);
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
return value;
|
|
2148
|
+
}
|
|
2119
2149
|
if (Array.isArray(value) || value instanceof Iterator) {
|
|
2120
2150
|
return value.map(patchValue);
|
|
2121
2151
|
}
|
|
@@ -37,14 +37,14 @@ import * as i18n from '../../../../core/i18n/i18n.js';
|
|
|
37
37
|
import * as SDK from '../../../../core/sdk/sdk.js';
|
|
38
38
|
import * as StackTrace from '../../../../models/stack_trace/stack_trace.js';
|
|
39
39
|
import * as Workspace from '../../../../models/workspace/workspace.js';
|
|
40
|
-
import {Directives, html, render} from '../../../lit/lit.js';
|
|
40
|
+
import {Directives, html, nothing, render, type TemplateResult} from '../../../lit/lit.js';
|
|
41
41
|
import * as VisualLogging from '../../../visual_logging/visual_logging.js';
|
|
42
42
|
import * as UI from '../../legacy.js';
|
|
43
43
|
|
|
44
44
|
import jsUtilsStyles from './jsUtils.css.js';
|
|
45
45
|
import {Linkifier} from './Linkifier.js';
|
|
46
46
|
|
|
47
|
-
const {classMap
|
|
47
|
+
const {classMap} = Directives;
|
|
48
48
|
|
|
49
49
|
const UIStrings = {
|
|
50
50
|
/**
|
|
@@ -97,134 +97,105 @@ export interface ViewInput {
|
|
|
97
97
|
widthConstrained?: boolean;
|
|
98
98
|
showColumnNumber?: boolean;
|
|
99
99
|
expandable?: boolean;
|
|
100
|
+
expanded?: boolean;
|
|
101
|
+
showIgnoreListed?: boolean;
|
|
102
|
+
onExpand: () => void;
|
|
103
|
+
onShowMore: () => void;
|
|
104
|
+
onShowLess: () => void;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
export type View = (input: ViewInput, output:
|
|
107
|
+
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
103
108
|
|
|
104
109
|
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
|
+
|
|
105
124
|
const classes = {
|
|
106
125
|
'stack-preview-container': true,
|
|
107
126
|
'width-constrained': Boolean(input.widthConstrained),
|
|
127
|
+
expandable: Boolean(input.expandable),
|
|
128
|
+
expanded: Boolean(input.expanded),
|
|
129
|
+
'show-hidden-rows': Boolean(input.showIgnoreListed),
|
|
108
130
|
};
|
|
109
|
-
|
|
110
|
-
const tableRef = createRef<HTMLElement>();
|
|
131
|
+
const {stackTrace} = input;
|
|
111
132
|
// clang-format off
|
|
112
133
|
render(html`
|
|
113
134
|
<style>${jsUtilsStyles}</style>
|
|
114
|
-
<table class=${classMap(classes)}
|
|
135
|
+
<table class=${classMap(classes)}>
|
|
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
|
+
`)}
|
|
175
|
+
<tfoot>
|
|
176
|
+
<tr class="show-all-link">
|
|
177
|
+
<td></td>
|
|
178
|
+
<td colspan="3">
|
|
179
|
+
<span class="link" @click=${input.onShowMore}>
|
|
180
|
+
<span class="css-inserted-text" data-inserted-text=${i18nString(UIStrings.showMoreFrames)}></span>
|
|
181
|
+
</span>
|
|
182
|
+
</td>
|
|
183
|
+
</tr>
|
|
184
|
+
<tr class="show-less-link">
|
|
185
|
+
<td></td>
|
|
186
|
+
<td colspan="3">
|
|
187
|
+
<span class="link" @click=${input.onShowLess}>
|
|
188
|
+
<span class="css-inserted-text" data-inserted-text=${i18nString(UIStrings.showLess)}></span>
|
|
189
|
+
</span>
|
|
190
|
+
</td>
|
|
191
|
+
</tr>
|
|
192
|
+
</tfoot>
|
|
193
|
+
` : nothing}
|
|
115
194
|
</table>
|
|
116
195
|
`, target);
|
|
117
196
|
// clang-format on
|
|
118
|
-
output.table = tableRef.value;
|
|
119
197
|
};
|
|
120
198
|
|
|
121
|
-
function renderStackTraceTable(
|
|
122
|
-
container: Element,
|
|
123
|
-
parent: Element,
|
|
124
|
-
stackTrace: StackTrace.StackTrace.StackTrace,
|
|
125
|
-
options: Options,
|
|
126
|
-
): void {
|
|
127
|
-
container.removeChildren();
|
|
128
|
-
|
|
129
|
-
function buildStackTraceRowsHelper(fragment: StackTrace.StackTrace.Fragment|StackTrace.StackTrace.AsyncFragment):
|
|
130
|
-
Array<StackTraceRegularRow|StackTraceAsyncRow> {
|
|
131
|
-
const stackTraceRows: Array<StackTraceRegularRow|StackTraceAsyncRow> = [];
|
|
132
|
-
if ('description' in fragment) {
|
|
133
|
-
stackTraceRows.push({asyncDescription: UI.UIUtils.asyncFragmentLabel(stackTrace, fragment)});
|
|
134
|
-
}
|
|
135
|
-
let previousStackFrameWasBreakpointCondition = false;
|
|
136
|
-
for (const frame of fragment.frames) {
|
|
137
|
-
const functionName = UI.UIUtils.beautifyFunctionName(frame.name ?? '');
|
|
138
|
-
const link = Linkifier.linkifyStackTraceFrame(frame, {
|
|
139
|
-
showColumnNumber: Boolean(options.showColumnNumber),
|
|
140
|
-
tabStop: Boolean(options.tabStops),
|
|
141
|
-
inlineFrameIndex: 0,
|
|
142
|
-
revealBreakpoint: previousStackFrameWasBreakpointCondition,
|
|
143
|
-
maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
|
|
144
|
-
});
|
|
145
|
-
link.setAttribute('jslog', `${VisualLogging.link('stack-trace').track({click: true})}`);
|
|
146
|
-
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
|
|
147
|
-
|
|
148
|
-
stackTraceRows.push({functionName, link});
|
|
149
|
-
previousStackFrameWasBreakpointCondition = [
|
|
150
|
-
SDK.DebuggerModel.COND_BREAKPOINT_SOURCE_URL,
|
|
151
|
-
SDK.DebuggerModel.LOGPOINT_SOURCE_URL,
|
|
152
|
-
].includes(frame.url ?? '');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return stackTraceRows;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// The tableSection groups one or more synchronous call frames together.
|
|
159
|
-
// Wherever there is an asynchronous call, a new section is created.
|
|
160
|
-
let firstRow = true;
|
|
161
|
-
for (const fragment of [stackTrace.syncFragment, ...stackTrace.asyncFragments]) {
|
|
162
|
-
if (fragment.frames.length === 0) {
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const stackTraceRows = buildStackTraceRowsHelper(fragment);
|
|
167
|
-
const tableSection = container.createChild('tbody');
|
|
168
|
-
for (const item of stackTraceRows) {
|
|
169
|
-
const row = tableSection.createChild('tr');
|
|
170
|
-
if (firstRow && options.expandable) {
|
|
171
|
-
const button = row.createChild('td').createChild('button', 'arrow-icon-button');
|
|
172
|
-
button.createChild('span', 'arrow-icon');
|
|
173
|
-
parent.classList.add('expandable');
|
|
174
|
-
container.classList.add('expandable');
|
|
175
|
-
button.addEventListener('click', () => {
|
|
176
|
-
button.setAttribute('jslog', `${VisualLogging.expand().track({click: true})}`);
|
|
177
|
-
parent.classList.toggle('expanded');
|
|
178
|
-
container.classList.toggle('expanded');
|
|
179
|
-
});
|
|
180
|
-
firstRow = false;
|
|
181
|
-
} else {
|
|
182
|
-
row.createChild('td').textContent = '\n';
|
|
183
|
-
}
|
|
184
|
-
if ('asyncDescription' in item) {
|
|
185
|
-
row.createChild('td', 'stack-preview-async-description').textContent = item.asyncDescription;
|
|
186
|
-
row.createChild('td');
|
|
187
|
-
row.createChild('td');
|
|
188
|
-
row.classList.add('stack-preview-async-row');
|
|
189
|
-
} else {
|
|
190
|
-
row.createChild('td', 'function-name').textContent = item.functionName;
|
|
191
|
-
row.createChild('td').textContent = ' @ ';
|
|
192
|
-
row.createChild('td', 'link').appendChild(item.link);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const tableSection = container.createChild('tfoot');
|
|
198
|
-
const showAllRow = tableSection.createChild('tr', 'show-all-link');
|
|
199
|
-
showAllRow.createChild('td');
|
|
200
|
-
const cell = showAllRow.createChild('td');
|
|
201
|
-
cell.colSpan = 4;
|
|
202
|
-
const showAllLink = cell.createChild('span', 'link');
|
|
203
|
-
// Don't directly put the text of the link in the DOM, as it will likely be
|
|
204
|
-
// invisible and it may be confusing if it is copied to the clipboard.
|
|
205
|
-
showAllLink.createChild('span', 'css-inserted-text')
|
|
206
|
-
.setAttribute('data-inserted-text', i18nString(UIStrings.showMoreFrames));
|
|
207
|
-
showAllLink.addEventListener('click', () => {
|
|
208
|
-
container.classList.add('show-hidden-rows');
|
|
209
|
-
parent.classList.add('show-hidden-rows');
|
|
210
|
-
// If we are in a popup, this will trigger a re-layout
|
|
211
|
-
UI.GlassPane.GlassPane.containerMoved(container);
|
|
212
|
-
}, false);
|
|
213
|
-
const showLessRow = tableSection.createChild('tr', 'show-less-link');
|
|
214
|
-
showLessRow.createChild('td');
|
|
215
|
-
const showLesscell = showLessRow.createChild('td');
|
|
216
|
-
showLesscell.colSpan = 4;
|
|
217
|
-
const showLessLink = showLesscell.createChild('span', 'link');
|
|
218
|
-
showLessLink.createChild('span', 'css-inserted-text')
|
|
219
|
-
.setAttribute('data-inserted-text', i18nString(UIStrings.showLess));
|
|
220
|
-
showLessLink.addEventListener('click', () => {
|
|
221
|
-
container.classList.remove('show-hidden-rows');
|
|
222
|
-
parent.classList.remove('show-hidden-rows');
|
|
223
|
-
// If we are in a popup, this will trigger a re-layout
|
|
224
|
-
UI.GlassPane.GlassPane.containerMoved(container);
|
|
225
|
-
}, false);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
199
|
export interface Options {
|
|
229
200
|
tabStops?: boolean;
|
|
230
201
|
// Whether the width of stack trace preview
|
|
@@ -235,20 +206,13 @@ export interface Options {
|
|
|
235
206
|
expandable?: boolean;
|
|
236
207
|
}
|
|
237
208
|
|
|
238
|
-
interface StackTraceRegularRow {
|
|
239
|
-
functionName: string;
|
|
240
|
-
link: HTMLElement;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
interface StackTraceAsyncRow {
|
|
244
|
-
asyncDescription: string;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
209
|
export class StackTracePreviewContent extends UI.Widget.Widget {
|
|
248
210
|
readonly #view: View;
|
|
249
211
|
|
|
250
212
|
#stackTrace?: StackTrace.StackTrace.StackTrace;
|
|
251
213
|
#options: Options = {};
|
|
214
|
+
#expanded = false;
|
|
215
|
+
#showIgnoreListed = false;
|
|
252
216
|
|
|
253
217
|
constructor(element?: HTMLElement, view = DEFAULT_VIEW) {
|
|
254
218
|
super(element, {useShadowDom: true, classes: ['monospace', 'stack-preview-container']});
|
|
@@ -264,17 +228,20 @@ export class StackTracePreviewContent extends UI.Widget.Widget {
|
|
|
264
228
|
}
|
|
265
229
|
|
|
266
230
|
override performUpdate(): void {
|
|
267
|
-
|
|
268
|
-
this.#
|
|
269
|
-
|
|
270
|
-
stackTrace: this.#stackTrace,
|
|
271
|
-
...this.#options,
|
|
272
|
-
},
|
|
273
|
-
output, this.contentElement);
|
|
231
|
+
this.element.classList.toggle('expandable', this.#options.expandable);
|
|
232
|
+
this.element.classList.toggle('expanded', this.#expanded);
|
|
233
|
+
this.element.classList.toggle('show-hidden-rows', this.#showIgnoreListed);
|
|
274
234
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
235
|
+
const input: ViewInput = {
|
|
236
|
+
stackTrace: this.#stackTrace,
|
|
237
|
+
...this.#options,
|
|
238
|
+
expanded: this.#expanded,
|
|
239
|
+
showIgnoreListed: this.#showIgnoreListed,
|
|
240
|
+
onExpand: this.#onExpand.bind(this),
|
|
241
|
+
onShowMore: this.#onShowMoreLess.bind(this, true),
|
|
242
|
+
onShowLess: this.#onShowMoreLess.bind(this, false),
|
|
243
|
+
};
|
|
244
|
+
this.#view(input, {}, this.contentElement);
|
|
278
245
|
}
|
|
279
246
|
|
|
280
247
|
get linkElements(): readonly HTMLElement[] {
|
|
@@ -294,4 +261,17 @@ export class StackTracePreviewContent extends UI.Widget.Widget {
|
|
|
294
261
|
this.#stackTrace.addEventListener(StackTrace.StackTrace.Events.UPDATED, this.requestUpdate, this);
|
|
295
262
|
this.requestUpdate();
|
|
296
263
|
}
|
|
264
|
+
|
|
265
|
+
#onShowMoreLess(more: boolean): void {
|
|
266
|
+
this.#showIgnoreListed = more;
|
|
267
|
+
this.requestUpdate();
|
|
268
|
+
|
|
269
|
+
// If we are in a popup, this will trigger a re-layout
|
|
270
|
+
void this.updateComplete.then(() => UI.GlassPane.GlassPane.containerMoved(this.contentElement));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
#onExpand(): void {
|
|
274
|
+
this.#expanded = !this.#expanded;
|
|
275
|
+
this.requestUpdate();
|
|
276
|
+
}
|
|
297
277
|
}
|
package/package.json
CHANGED