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.
Files changed (43) hide show
  1. package/front_end/core/sdk/ScopeTreeCache.ts +4 -0
  2. package/front_end/entrypoint_template.html +5 -1
  3. package/front_end/generated/Deprecation.ts +21 -0
  4. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  5. package/front_end/generated/protocol.ts +2 -0
  6. package/front_end/models/ai_assistance/AiConversation.ts +5 -1
  7. package/front_end/models/ai_assistance/agents/AiAgent.ts +16 -4
  8. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +7 -1
  9. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +0 -2
  10. package/front_end/panels/ai_assistance/components/ChatInput.ts +36 -31
  11. package/front_end/panels/ai_assistance/components/chatInput.css +6 -9
  12. package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -6
  13. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +11 -3
  14. package/front_end/panels/common/DOMLinkifier.ts +6 -1
  15. package/front_end/panels/elements/ComputedStyleWidget.ts +25 -2
  16. package/front_end/panels/elements/ElementsPanel.ts +114 -15
  17. package/front_end/panels/elements/PropertiesWidget.ts +40 -2
  18. package/front_end/panels/elements/StylesSidebarPane.ts +26 -3
  19. package/front_end/panels/network/NetworkDataGridNode.ts +4 -0
  20. package/front_end/panels/network/NetworkItemView.ts +6 -44
  21. package/front_end/panels/network/RequestHeadersView.ts +499 -0
  22. package/front_end/panels/network/components/RequestHeaderSection.ts +3 -0
  23. package/front_end/panels/network/components/components.ts +0 -2
  24. package/front_end/panels/network/network.ts +3 -0
  25. package/front_end/third_party/chromium/README.chromium +1 -1
  26. package/front_end/third_party/puppeteer/README.chromium +2 -2
  27. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  28. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  29. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  30. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  31. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +3 -3
  32. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  33. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  34. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  35. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  36. package/front_end/third_party/puppeteer/package/package.json +1 -1
  37. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  38. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  39. package/front_end/ui/legacy/Toolbar.ts +37 -5
  40. package/front_end/ui/legacy/UIUtils.ts +35 -5
  41. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +113 -133
  42. package/package.json +1 -1
  43. package/front_end/panels/network/components/RequestHeadersView.ts +0 -569
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "puppeteer-core",
3
- "version": "24.37.4",
3
+ "version": "24.37.5",
4
4
  "description": "A high-level API to control headless Chrome over the DevTools Protocol",
5
5
  "keywords": [
6
6
  "puppeteer",
@@ -8,7 +8,7 @@
8
8
  * @internal
9
9
  */
10
10
  export const PUPPETEER_REVISIONS = Object.freeze({
11
- chrome: '145.0.7632.76',
12
- 'chrome-headless-shell': '145.0.7632.76',
11
+ chrome: '145.0.7632.77',
12
+ 'chrome-headless-shell': '145.0.7632.77',
13
13
  firefox: 'stable_147.0.4',
14
14
  });
@@ -6,5 +6,5 @@
6
6
 
7
7
  // If moved update release-please config
8
8
  // x-release-please-start-version
9
- export const packageVersion = '24.37.4';
9
+ export const packageVersion = '24.37.5';
10
10
  // x-release-please-end
@@ -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(_listener: Function): undefined {
2038
- return undefined;
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 wrapper = Lit.Directive.directive(InterceptBindingDirective);
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 (typeof value === 'function') {
2127
+ if (isCallable(value)) {
2109
2128
  try {
2110
- return wrapper(value);
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, createRef, ref} = Directives;
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: {table?: HTMLElement}, target: HTMLElement) => void;
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
- // TODO(crbug.com/483576322): Remove once fully migrated.
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)} ${ref(tableRef)}>
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
- const output: {table?: HTMLElement} = {};
268
- this.#view(
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
- if (this.#stackTrace && output.table) {
276
- renderStackTraceTable(output.table, this.element, this.#stackTrace, this.#options);
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
@@ -105,5 +105,5 @@
105
105
  "flat-cache": "6.1.12"
106
106
  }
107
107
  },
108
- "version": "1.0.1586699"
108
+ "version": "1.0.1587905"
109
109
  }