chrome-devtools-frontend 1.0.957495 → 1.0.957983

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 (50) hide show
  1. package/extension-api/ExtensionAPI.d.ts +7 -0
  2. package/front_end/Tests.js +14 -0
  3. package/front_end/core/common/Debouncer.ts +1 -1
  4. package/front_end/core/common/Settings.ts +33 -0
  5. package/front_end/core/host/InspectorFrontendHost.ts +7 -3
  6. package/front_end/core/host/InspectorFrontendHostAPI.ts +2 -0
  7. package/front_end/core/host/UserMetrics.ts +2 -2
  8. package/front_end/core/i18n/i18nImpl.ts +1 -1
  9. package/front_end/core/protocol_client/InspectorBackend.ts +3 -3
  10. package/front_end/core/sdk/Connections.ts +1 -1
  11. package/front_end/core/sdk/IsolateManager.ts +1 -1
  12. package/front_end/core/sdk/PageResourceLoader.ts +4 -2
  13. package/front_end/devtools_compatibility.js +9 -0
  14. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  15. package/front_end/models/extensions/ExtensionAPI.ts +33 -5
  16. package/front_end/models/extensions/ExtensionServer.ts +28 -0
  17. package/front_end/models/logs/LogManager.ts +1 -1
  18. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +1 -1
  19. package/front_end/models/workspace/UISourceCode.ts +1 -1
  20. package/front_end/panels/application/StorageView.ts +1 -1
  21. package/front_end/panels/console/ConsoleView.ts +1 -1
  22. package/front_end/panels/elements/ComputedStyleModel.ts +1 -1
  23. package/front_end/panels/elements/StylesSidebarPane.ts +2 -2
  24. package/front_end/panels/network/NetworkItemView.ts +1 -1
  25. package/front_end/panels/profiler/HeapTimelineOverview.ts +2 -2
  26. package/front_end/panels/profiler/LiveHeapProfileView.ts +1 -1
  27. package/front_end/panels/screencast/ScreencastView.ts +2 -2
  28. package/front_end/panels/settings/SettingsScreen.ts +1 -1
  29. package/front_end/panels/settings/settingsScreen.css +8 -3
  30. package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
  31. package/front_end/panels/sources/NavigatorView.ts +1 -1
  32. package/front_end/panels/sources/SourcesSearchScope.ts +1 -1
  33. package/front_end/panels/timeline/TimelineController.ts +2 -2
  34. package/front_end/panels/timeline/TimelineLoader.ts +3 -3
  35. package/front_end/panels/timeline/TimelinePanel.ts +1 -1
  36. package/front_end/panels/webauthn/WebauthnPane.ts +1 -1
  37. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  38. package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
  39. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +76 -12
  40. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  41. package/front_end/third_party/codemirror.next/package.json +13 -13
  42. package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +2 -2
  43. package/front_end/ui/components/text_editor/TextEditor.ts +1 -1
  44. package/front_end/ui/components/text_editor/cursor_tooltip.ts +1 -1
  45. package/front_end/ui/components/text_editor/javascript.ts +1 -1
  46. package/front_end/ui/legacy/SearchableView.ts +1 -1
  47. package/front_end/ui/legacy/SoftDropDown.ts +2 -2
  48. package/front_end/ui/legacy/TextPrompt.ts +2 -1
  49. package/front_end/ui/legacy/components/perf_ui/LiveHeapProfile.ts +1 -1
  50. package/package.json +1 -1
@@ -69,6 +69,13 @@ export namespace Chrome {
69
69
 
70
70
  create(title: string, iconPath: string, pagePath: string, callback?: (panel: ExtensionPanel) => unknown): void;
71
71
  openResource(url: string, lineNumber: number, columnNumber?: number, callback?: () => unknown): void;
72
+
73
+ /**
74
+ * Fired when the theme changes in DevTools.
75
+ *
76
+ * @param callback The handler callback to register and be invoked on theme changes.
77
+ */
78
+ setThemeChangeHandler(callback?: (themeName: string) => unknown): void;
72
79
  }
73
80
 
74
81
  export interface Request {
@@ -1572,6 +1572,20 @@
1572
1572
  `console.log(1) //# sourceMappingURL=chrome-extension://${extensionId}/source.map`, () => {});
1573
1573
  };
1574
1574
 
1575
+ TestSuite.prototype.testSourceMapsFromDevtools = function() {
1576
+ this.takeControl();
1577
+ const debuggerModel = self.SDK.targetManager.mainTarget().model(SDK.DebuggerModel);
1578
+ debuggerModel.sourceMapManager().addEventListener(
1579
+ SDK.SourceMapManager.Events.SourceMapWillAttach, this.releaseControl.bind(this));
1580
+
1581
+ this.evaluateInConsole_(
1582
+ 'console.log(1) //# sourceMappingURL=devtools://devtools/bundled/devtools_compatibility.js', () => {});
1583
+ };
1584
+
1585
+ TestSuite.prototype.testDoesNotCrashOnSourceMapsFromUnknownScheme = function() {
1586
+ this.evaluateInConsole_('console.log(1) //# sourceMappingURL=invalid-scheme://source.map', () => {});
1587
+ };
1588
+
1575
1589
  /**
1576
1590
  * Returns all loaded non anonymous uiSourceCodes.
1577
1591
  * @return {!Array.<!Workspace.UISourceCode>}
@@ -9,7 +9,7 @@ export const debounce = function(func: Function, delay: number): Function {
9
9
  let timer = 0;
10
10
  const debounced = (): void => {
11
11
  clearTimeout(timer);
12
- timer = setTimeout(() => func(), delay);
12
+ timer = window.setTimeout(() => func(), delay);
13
13
  };
14
14
  return debounced;
15
15
  };
@@ -197,6 +197,7 @@ export class Settings {
197
197
 
198
198
  export interface SettingsBackingStore {
199
199
  register(setting: string): void;
200
+ get(setting: string): Promise<string>;
200
201
  set(setting: string, value: string): void;
201
202
  remove(setting: string): void;
202
203
  clear(): void;
@@ -205,6 +206,7 @@ export interface SettingsBackingStore {
205
206
  export const NOOP_STORAGE: SettingsBackingStore = {
206
207
  register: () => {},
207
208
  set: () => {},
209
+ get: () => Promise.resolve(''),
208
210
  remove: () => {},
209
211
  clear: () => {},
210
212
  };
@@ -236,6 +238,17 @@ export class SettingsStorage {
236
238
  return this.object[name];
237
239
  }
238
240
 
241
+ async forceGet(originalName: string): Promise<string> {
242
+ const name = this.storagePrefix + originalName;
243
+ const value = await this.backingStore.get(name);
244
+ if (value && value !== this.object[name]) {
245
+ this.set(originalName, value);
246
+ } else if (!value) {
247
+ this.remove(originalName);
248
+ }
249
+ return value;
250
+ }
251
+
239
252
  remove(name: string): void {
240
253
  name = this.storagePrefix + name;
241
254
  delete this.object[name];
@@ -363,6 +376,26 @@ export class Setting<V> {
363
376
  return this.#value;
364
377
  }
365
378
 
379
+ async forceGet(): Promise<V> {
380
+ const name = this.name;
381
+ const oldValue = this.storage.get(name);
382
+ const value = await this.storage.forceGet(name);
383
+ this.#value = this.defaultValue;
384
+ if (value) {
385
+ try {
386
+ this.#value = this.#serializer.parse(value);
387
+ } catch (e) {
388
+ this.storage.remove(this.name);
389
+ }
390
+ }
391
+
392
+ if (oldValue !== value) {
393
+ this.eventSupport.dispatchEventToListeners(this.name, this.#value);
394
+ }
395
+
396
+ return this.#value;
397
+ }
398
+
366
399
  set(value: V): void {
367
400
  this.#hadUserAction = true;
368
401
  this.#value = value;
@@ -94,15 +94,15 @@ export class InspectorFrontendHostStub implements InspectorFrontendHostAPI {
94
94
  }
95
95
 
96
96
  setIsDocked(isDocked: boolean, callback: () => void): void {
97
- setTimeout(callback, 0);
97
+ window.setTimeout(callback, 0);
98
98
  }
99
99
 
100
100
  showSurvey(trigger: string, callback: (arg0: ShowSurveyResult) => void): void {
101
- setTimeout(() => callback({surveyShown: false}), 0);
101
+ window.setTimeout(() => callback({surveyShown: false}), 0);
102
102
  }
103
103
 
104
104
  canShowSurvey(trigger: string, callback: (arg0: CanShowSurveyResult) => void): void {
105
- setTimeout(() => callback({canShowSurvey: false}), 0);
105
+ window.setTimeout(() => callback({canShowSurvey: false}), 0);
106
106
  }
107
107
 
108
108
  /**
@@ -260,6 +260,10 @@ export class InspectorFrontendHostStub implements InspectorFrontendHostAPI {
260
260
  callback(prefs);
261
261
  }
262
262
 
263
+ getPreference(name: string, callback: (arg0: string) => void): void {
264
+ callback(window.localStorage[name]);
265
+ }
266
+
263
267
  setPreference(name: string, value: string): void {
264
268
  window.localStorage[name] = value;
265
269
  }
@@ -234,6 +234,8 @@ export interface InspectorFrontendHostAPI {
234
234
  [x: string]: string,
235
235
  }) => void): void;
236
236
 
237
+ getPreference(name: string, callback: (arg0: string) => void): void;
238
+
237
239
  setPreference(name: string, value: string): void;
238
240
 
239
241
  removePreference(name: string): void;
@@ -78,10 +78,10 @@ export class UserMetrics {
78
78
  }
79
79
 
80
80
  this.#firedLaunchHistogram = true;
81
- // Use rAF and setTimeout to ensure the marker is fired after layout and rendering.
81
+ // Use rAF and window.setTimeout to ensure the marker is fired after layout and rendering.
82
82
  // This will give the most accurate representation of the tool being ready for a user.
83
83
  requestAnimationFrame(() => {
84
- setTimeout(() => {
84
+ window.setTimeout(() => {
85
85
  // Mark the load time so that we can pinpoint it more easily in a trace.
86
86
  performance.mark(histogramName);
87
87
  // If the user has switched panel before we finished loading, ignore the histogram,
@@ -58,7 +58,7 @@ function getLocaleFetchUrl(locale: Intl.UnicodeBCP47LocaleIdentifier): string {
58
58
  export async function fetchAndRegisterLocaleData(locale: Intl.UnicodeBCP47LocaleIdentifier): Promise<void> {
59
59
  const localeDataTextPromise = fetch(getLocaleFetchUrl(locale)).then(result => result.json());
60
60
  const timeoutPromise =
61
- new Promise((resolve, reject) => setTimeout(() => reject(new Error('timed out fetching locale')), 5000));
61
+ new Promise((resolve, reject) => window.setTimeout(() => reject(new Error('timed out fetching locale')), 5000));
62
62
  const localeData = await Promise.race([timeoutPromise, localeDataTextPromise]);
63
63
  i18nInstance.registerLocaleData(locale, localeData);
64
64
  }
@@ -442,7 +442,7 @@ export class SessionRouter {
442
442
  }
443
443
 
444
444
  // Execute all promises.
445
- setTimeout(() => {
445
+ window.setTimeout(() => {
446
446
  if (!this.hasOutstandingNonLongPollingRequests()) {
447
447
  this.executeAfterPendingDispatches();
448
448
  } else {
@@ -467,7 +467,7 @@ export class SessionRouter {
467
467
  code: ConnectionClosedErrorCode,
468
468
  data: null,
469
469
  };
470
- setTimeout(() => callback(error, null), 0);
470
+ window.setTimeout(() => callback(error, null), 0);
471
471
  }
472
472
 
473
473
  static dispatchUnregisterSessionError({callback, method}: CallbackWithDebugInfo): void {
@@ -476,7 +476,7 @@ export class SessionRouter {
476
476
  code: ConnectionClosedErrorCode,
477
477
  data: null,
478
478
  };
479
- setTimeout(() => callback(error, null), 0);
479
+ window.setTimeout(() => callback(error, null), 0);
480
480
  }
481
481
  }
482
482
 
@@ -189,7 +189,7 @@ export class StubConnection implements ProtocolClient.InspectorBackend.Connectio
189
189
  }
190
190
 
191
191
  sendRawMessage(message: string): void {
192
- setTimeout(this.respondWithError.bind(this, message), 0);
192
+ window.setTimeout(this.respondWithError.bind(this, message), 0);
193
193
  }
194
194
 
195
195
  private respondWithError(message: string): void {
@@ -126,7 +126,7 @@ export class IsolateManager extends Common.ObjectWrapper.ObjectWrapper<EventType
126
126
  const pollId = this.#pollId;
127
127
  while (pollId === this.#pollId) {
128
128
  await Promise.all(Array.from(this.isolates(), isolate => isolate.update()));
129
- await new Promise(r => setTimeout(r, PollIntervalMs));
129
+ await new Promise(r => window.setTimeout(r, PollIntervalMs));
130
130
  }
131
131
  }
132
132
  }
@@ -163,7 +163,8 @@ export class PageResourceLoader extends Common.ObjectWrapper.ObjectWrapper<Event
163
163
 
164
164
  static async withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {
165
165
  const timeoutPromise = new Promise<T>(
166
- (_, reject) => setTimeout(reject, timeout, new Error(i18nString(UIStrings.loadCanceledDueToLoadTimeout))));
166
+ (_, reject) =>
167
+ window.setTimeout(reject, timeout, new Error(i18nString(UIStrings.loadCanceledDueToLoadTimeout))));
167
168
  return Promise.race([promise, timeoutPromise]);
168
169
  }
169
170
 
@@ -219,7 +220,8 @@ export class PageResourceLoader extends Common.ObjectWrapper.ObjectWrapper<Event
219
220
  return this.#loadOverride(url);
220
221
  }
221
222
  const parsedURL = new Common.ParsedURL.ParsedURL(url);
222
- const eligibleForLoadFromTarget = getLoadThroughTargetSetting().get() && parsedURL && parsedURL.isHttpOrHttps();
223
+ const eligibleForLoadFromTarget = getLoadThroughTargetSetting().get() && parsedURL && parsedURL.scheme !== 'file' &&
224
+ parsedURL.scheme !== 'data' && parsedURL.scheme !== 'devtools';
223
225
  Host.userMetrics.developerResourceScheme(this.getDeveloperResourceScheme(parsedURL));
224
226
  if (eligibleForLoadFromTarget) {
225
227
  try {
@@ -542,6 +542,15 @@
542
542
  DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback));
543
543
  }
544
544
 
545
+ /**
546
+ * @override
547
+ * @param {string} name
548
+ * @param {function(string)} callback
549
+ */
550
+ getPreference(name, callback) {
551
+ DevToolsAPI.sendMessageToEmbedder('getPreference', [name], /** @type {function(string)} */ (callback));
552
+ }
553
+
545
554
  /**
546
555
  * @override
547
556
  * @param {string} name
@@ -233,6 +233,11 @@ export class MainImpl {
233
233
  register: (name: string) =>
234
234
  Host.InspectorFrontendHost.InspectorFrontendHostInstance.registerPreference(name, {synced: false}),
235
235
  set: Host.InspectorFrontendHost.InspectorFrontendHostInstance.setPreference,
236
+ get: (name: string) => {
237
+ return new Promise(resolve => {
238
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.getPreference(name, resolve);
239
+ });
240
+ },
236
241
  remove: Host.InspectorFrontendHost.InspectorFrontendHostInstance.removePreference,
237
242
  clear: Host.InspectorFrontendHost.InspectorFrontendHostInstance.clearPreferences,
238
243
  };
@@ -571,7 +576,7 @@ export class MainImpl {
571
576
  UI.ARIAUtils.alertElementInstance();
572
577
 
573
578
  // Allow UI cycles to repaint prior to creating connection.
574
- setTimeout(this.#initializeTarget.bind(this), 0);
579
+ window.setTimeout(this.#initializeTarget.bind(this), 0);
575
580
  MainImpl.timeEnd('Main._showAppUI');
576
581
  }
577
582
 
@@ -587,7 +592,7 @@ export class MainImpl {
587
592
  // Used for browser tests.
588
593
  Host.InspectorFrontendHost.InspectorFrontendHostInstance.readyForTest();
589
594
  // Asynchronously run the extensions.
590
- setTimeout(this.#lateInitialization.bind(this), 100);
595
+ window.setTimeout(this.#lateInitialization.bind(this), 100);
591
596
  MainImpl.timeEnd('Main._initializeTarget');
592
597
  }
593
598
 
@@ -55,6 +55,7 @@ export namespace PrivateAPI {
55
55
  ResourceContentCommitted = 'resource-content-committed',
56
56
  ViewShown = 'view-shown-',
57
57
  ViewHidden = 'view-hidden,',
58
+ ThemeChange = 'host-theme-change',
58
59
  }
59
60
 
60
61
  export const enum Commands {
@@ -75,6 +76,7 @@ export namespace PrivateAPI {
75
76
  Reload = 'Reload',
76
77
  Subscribe = 'subscribe',
77
78
  SetOpenResourceHandler = 'setOpenResourceHandler',
79
+ SetThemeChangeHandler = 'setThemeChangeHandler',
78
80
  SetResourceContent = 'setResourceContent',
79
81
  SetSidebarContent = 'setSidebarContent',
80
82
  SetSidebarHeight = 'setSidebarHeight',
@@ -151,6 +153,7 @@ export namespace PrivateAPI {
151
153
  type SetSidebarPageRequest = {command: Commands.SetSidebarPage, id: string, page: string};
152
154
  type OpenResourceRequest = {command: Commands.OpenResource, url: string, lineNumber: number, columnNumber: number};
153
155
  type SetOpenResourceHandlerRequest = {command: Commands.SetOpenResourceHandler, handlerPresent: boolean};
156
+ type SetThemeChangeHandlerRequest = {command: Commands.SetThemeChangeHandler, handlerPresent: boolean};
154
157
  type ReloadRequest = {
155
158
  command: Commands.Reload,
156
159
  options: null|{
@@ -180,9 +183,10 @@ export namespace PrivateAPI {
180
183
  export type ServerRequests = RegisterLanguageExtensionPluginRequest|SubscribeRequest|UnsubscribeRequest|
181
184
  AddRequestHeadersRequest|ApplyStyleSheetRequest|CreatePanelRequest|ShowPanelRequest|CreateToolbarButtonRequest|
182
185
  UpdateButtonRequest|CompleteTraceSessionRequest|CreateSidebarPaneRequest|SetSidebarHeightRequest|
183
- SetSidebarContentRequest|SetSidebarPageRequest|OpenResourceRequest|SetOpenResourceHandlerRequest|ReloadRequest|
184
- EvaluateOnInspectedPageRequest|GetRequestContentRequest|GetResourceContentRequest|SetResourceContentRequest|
185
- AddTraceProviderRequest|ForwardKeyboardEventRequest|GetHARRequest|GetPageResourcesRequest;
186
+ SetSidebarContentRequest|SetSidebarPageRequest|OpenResourceRequest|SetOpenResourceHandlerRequest|
187
+ SetThemeChangeHandlerRequest|ReloadRequest|EvaluateOnInspectedPageRequest|GetRequestContentRequest|
188
+ GetResourceContentRequest|SetResourceContentRequest|AddTraceProviderRequest|ForwardKeyboardEventRequest|
189
+ GetHARRequest|GetPageResourcesRequest;
186
190
  export type ExtensionServerRequestMessage = PrivateAPI.ServerRequests&{requestId?: number};
187
191
 
188
192
  type AddRawModuleRequest = {
@@ -330,6 +334,7 @@ namespace APIImpl {
330
334
  applyStyleSheet(styleSheet: string): void;
331
335
  setOpenResourceHandler(callback?: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown):
332
336
  void;
337
+ setThemeChangeHandler(callback?: (themeName: string) => unknown): void;
333
338
  }
334
339
 
335
340
  export interface ExtensionView extends PublicAPI.Chrome.DevTools.ExtensionView {
@@ -539,7 +544,8 @@ self.injectedExtensionAPI = function(
539
544
  };
540
545
  }
541
546
 
542
- (Panels.prototype as Pick<APIImpl.Panels, 'create'|'setOpenResourceHandler'|'openResource'|'SearchAction'>) = {
547
+ (Panels.prototype as
548
+ Pick<APIImpl.Panels, 'create'|'setOpenResourceHandler'|'openResource'|'SearchAction'|'setThemeChangeHandler'>) = {
543
549
  create: function(
544
550
  title: string, icon: string, page: string,
545
551
  callback: (panel: PublicAPI.Chrome.DevTools.ExtensionPanel) => unknown): void {
@@ -577,6 +583,28 @@ self.injectedExtensionAPI = function(
577
583
  }
578
584
  },
579
585
 
586
+ setThemeChangeHandler: function(callback: (themeName: string) => unknown): void {
587
+ const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.ThemeChange);
588
+
589
+ function callbackWrapper(message: unknown): void {
590
+ const {themeName} = message as {themeName: string};
591
+ chrome.devtools.panels.themeName = themeName;
592
+ callback.call(null, themeName);
593
+ }
594
+
595
+ if (!callback) {
596
+ extensionServer.unregisterHandler(PrivateAPI.Events.ThemeChange);
597
+ } else {
598
+ extensionServer.registerHandler(PrivateAPI.Events.ThemeChange, callbackWrapper);
599
+ }
600
+
601
+ // Only send command if we either removed an existing handler or added handler and had none before.
602
+ if (hadHandler === !callback) {
603
+ extensionServer.sendRequest(
604
+ {command: PrivateAPI.Commands.SetThemeChangeHandler, 'handlerPresent': Boolean(callback)});
605
+ }
606
+ },
607
+
580
608
  openResource: function(
581
609
  url: string, lineNumber: number, columnNumber?: number, _callback?: (response: unknown) => unknown): void {
582
610
  const callbackArg = extractCallbackArgument(arguments);
@@ -1084,7 +1112,7 @@ self.injectedExtensionAPI = function(
1084
1112
  };
1085
1113
  keyboardEventRequestQueue.push(requestPayload);
1086
1114
  if (!forwardTimer) {
1087
- forwardTimer = setTimeout(forwardEventQueue, 0);
1115
+ forwardTimer = window.setTimeout(forwardEventQueue, 0);
1088
1116
  }
1089
1117
  }
1090
1118
 
@@ -89,6 +89,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
89
89
  private extensionsEnabled: boolean;
90
90
  private inspectedTabId?: string;
91
91
  private readonly extensionAPITestHook?: (server: unknown, api: unknown) => unknown;
92
+ private themeChangeHandlers: Map<string, MessagePort> = new Map();
92
93
 
93
94
  private constructor() {
94
95
  super();
@@ -124,6 +125,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
124
125
  this.registerHandler(PrivateAPI.Commands.GetResourceContent, this.onGetResourceContent.bind(this));
125
126
  this.registerHandler(PrivateAPI.Commands.Reload, this.onReload.bind(this));
126
127
  this.registerHandler(PrivateAPI.Commands.SetOpenResourceHandler, this.onSetOpenResourceHandler.bind(this));
128
+ this.registerHandler(PrivateAPI.Commands.SetThemeChangeHandler, this.onSetThemeChangeHandler.bind(this));
127
129
  this.registerHandler(PrivateAPI.Commands.SetResourceContent, this.onSetResourceContent.bind(this));
128
130
  this.registerHandler(PrivateAPI.Commands.SetSidebarHeight, this.onSetSidebarHeight.bind(this));
129
131
  this.registerHandler(PrivateAPI.Commands.SetSidebarContent, this.onSetSidebarContent.bind(this));
@@ -147,6 +149,13 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
147
149
  Host.InspectorFrontendHostAPI.Events.SetInspectedTabId, this.setInspectedTabId, this);
148
150
 
149
151
  this.initExtensions();
152
+
153
+ ThemeSupport.ThemeSupport.instance().addEventListener(ThemeSupport.ThemeChangeEvent.eventName, () => {
154
+ const themeName = ThemeSupport.ThemeSupport.instance().themeName();
155
+ for (const port of this.themeChangeHandlers.values()) {
156
+ port.postMessage({command: PrivateAPI.Events.ThemeChange, themeName});
157
+ }
158
+ });
150
159
  }
151
160
 
152
161
  static instance(opts: {
@@ -530,6 +539,25 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
530
539
  return undefined;
531
540
  }
532
541
 
542
+ private onSetThemeChangeHandler(message: PrivateAPI.ExtensionServerRequestMessage, port: MessagePort): Record
543
+ |undefined {
544
+ if (message.command !== PrivateAPI.Commands.SetThemeChangeHandler) {
545
+ return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.SetThemeChangeHandler}`);
546
+ }
547
+ const extensionOrigin = this.getExtensionOrigin(port);
548
+ const extension = this.registeredExtensions.get(extensionOrigin);
549
+ if (!extension) {
550
+ throw new Error('Received a message from an unregistered extension');
551
+ }
552
+
553
+ if (message.handlerPresent) {
554
+ this.themeChangeHandlers.set(extensionOrigin, port);
555
+ } else {
556
+ this.themeChangeHandlers.delete(extensionOrigin);
557
+ }
558
+ return undefined;
559
+ }
560
+
533
561
  private handleOpenURL(
534
562
  port: MessagePort, contentProvider: TextUtils.ContentProvider.ContentProvider, lineNumber: number): void {
535
563
  port.postMessage(
@@ -67,7 +67,7 @@ export class LogManager implements SDK.TargetManager.SDKModelObserver<SDK.LogMod
67
67
  if (SDK.TargetManager.TargetManager.instance().targetById(workerId)) {
68
68
  return;
69
69
  }
70
- setTimeout(() => {
70
+ window.setTimeout(() => {
71
71
  if (!SDK.TargetManager.TargetManager.instance().targetById(workerId)) {
72
72
  SDK.ConsoleModel.ConsoleModel.instance().addMessage(consoleMessage);
73
73
  }
@@ -331,7 +331,7 @@ export class FileSystem extends Workspace.Workspace.ProjectStore implements Work
331
331
  this.addFile(filePaths[i]);
332
332
  }
333
333
  if (to < filePaths.length) {
334
- setTimeout(reportFileChunk.bind(this, to), 100);
334
+ window.setTimeout(reportFileChunk.bind(this, to), 100);
335
335
  }
336
336
  }
337
337
  }
@@ -277,7 +277,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
277
277
  await Common.Revealer.reveal(this);
278
278
 
279
279
  // Make sure we are in the next frame before stopping the world with confirm
280
- await new Promise(resolve => setTimeout(resolve, 0));
280
+ await new Promise(resolve => window.setTimeout(resolve, 0));
281
281
 
282
282
  const shouldUpdate = window.confirm(i18nString(UIStrings.thisFileWasChangedExternally));
283
283
  if (shouldUpdate) {
@@ -381,7 +381,7 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
381
381
  this.clearButton.disabled = true;
382
382
  const label = this.clearButton.textContent;
383
383
  this.clearButton.textContent = i18nString(UIStrings.clearing);
384
- setTimeout(() => {
384
+ window.setTimeout(() => {
385
385
  this.clearButton.disabled = false;
386
386
  this.clearButton.textContent = label;
387
387
  this.clearButton.focus();
@@ -1390,7 +1390,7 @@ export class ConsoleView extends UI.Widget.VBox implements UI.SearchableView.Sea
1390
1390
 
1391
1391
  if (index === this.visibleViewMessages.length) {
1392
1392
  this.cleanupAfterSearch();
1393
- setTimeout(this.searchFinishedForTests.bind(this), 0);
1393
+ window.setTimeout(this.searchFinishedForTests.bind(this), 0);
1394
1394
  return;
1395
1395
  }
1396
1396
 
@@ -83,7 +83,7 @@ export class ComputedStyleModel extends Common.ObjectWrapper.ObjectWrapper<Event
83
83
  clearTimeout(this.frameResizedTimer);
84
84
  }
85
85
 
86
- this.frameResizedTimer = setTimeout(refreshContents.bind(this), 100);
86
+ this.frameResizedTimer = window.setTimeout(refreshContents.bind(this), 100);
87
87
  }
88
88
 
89
89
  private elementNode(): SDK.DOMModel.DOMNode|null {
@@ -590,7 +590,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
590
590
 
591
591
  async doUpdate(): Promise<void> {
592
592
  if (!this.initialUpdateCompleted) {
593
- setTimeout(() => {
593
+ window.setTimeout(() => {
594
594
  if (!this.initialUpdateCompleted) {
595
595
  // the spinner will get automatically removed when innerRebuildUpdate is called
596
596
  this.sectionsContainer.createChild('span', 'spinner');
@@ -1650,7 +1650,7 @@ export class StylePropertiesSection {
1650
1650
  if (this.hoverTimer) {
1651
1651
  clearTimeout(this.hoverTimer);
1652
1652
  }
1653
- this.hoverTimer = setTimeout(this.highlight.bind(this), 300);
1653
+ this.hoverTimer = window.setTimeout(this.highlight.bind(this), 300);
1654
1654
  }
1655
1655
 
1656
1656
  highlight(mode: string|undefined = 'all'): void {
@@ -275,7 +275,7 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
275
275
  if (!this.selectTab(tabId)) {
276
276
  // maybeAppendPayloadPanel might cause payload tab to appear asynchronously, so
277
277
  // it makes sense to retry on the next tick
278
- setTimeout(() => {
278
+ window.setTimeout(() => {
279
279
  if (!this.selectTab(tabId)) {
280
280
  this.selectTab('headers');
281
281
  }
@@ -196,7 +196,7 @@ export class HeapTimelineOverview extends Common.ObjectWrapper.eventMixin<EventT
196
196
 
197
197
  onWindowChanged(): void {
198
198
  if (!this.updateGridTimerId) {
199
- this.updateGridTimerId = setTimeout(this.updateGrid.bind(this), 10);
199
+ this.updateGridTimerId = window.setTimeout(this.updateGrid.bind(this), 10);
200
200
  }
201
201
  }
202
202
 
@@ -204,7 +204,7 @@ export class HeapTimelineOverview extends Common.ObjectWrapper.eventMixin<EventT
204
204
  if (this.updateTimerId) {
205
205
  return;
206
206
  }
207
- this.updateTimerId = setTimeout(this.update.bind(this), 10);
207
+ this.updateTimerId = window.setTimeout(this.update.bind(this), 10);
208
208
  }
209
209
 
210
210
  updateBoundaries(): void {
@@ -203,7 +203,7 @@ export class LiveHeapProfileView extends UI.Widget.VBox {
203
203
  return;
204
204
  }
205
205
  this.update(isolates, profiles);
206
- await new Promise(r => setTimeout(r, 3000));
206
+ await new Promise(r => window.setTimeout(r, 3000));
207
207
  } while (this.currentPollId === pollId);
208
208
  }
209
209
 
@@ -796,7 +796,7 @@ export class ProgressTracker {
796
796
  private onLoad(): void {
797
797
  this.requestIds = null;
798
798
  this.updateProgress(1); // Display 100% progress on load, hide it in 0.5s.
799
- setTimeout(() => {
799
+ window.setTimeout(() => {
800
800
  if (!this.navigationProgressVisible()) {
801
801
  this.displayProgress(0);
802
802
  }
@@ -831,7 +831,7 @@ export class ProgressTracker {
831
831
  return;
832
832
  }
833
833
  ++this.finishedRequests;
834
- setTimeout(() => {
834
+ window.setTimeout(() => {
835
835
  this.updateProgress(
836
836
  this.finishedRequests / this.startedRequests * 0.9); // Finished requests drive the progress up to 90%.
837
837
  }, 500); // Delay to give the new requests time to start. This makes the progress smoother.
@@ -392,7 +392,7 @@ export class ExperimentsSettingsTab extends SettingsTab {
392
392
  constructor() {
393
393
  super(i18nString(UIStrings.experiments), 'experiments-tab-content');
394
394
  const filterSection = this.appendSection();
395
- filterSection.style.paddingTop = '1px';
395
+ filterSection.classList.add('experiments-filter');
396
396
 
397
397
  const labelElement = filterSection.createChild('label');
398
398
  labelElement.textContent = i18nString(UIStrings.filterExperimentsLabel);
@@ -74,9 +74,14 @@ fieldset {
74
74
  border: none;
75
75
  }
76
76
 
77
- .settings-tab label {
78
- padding-right: 4px;
79
- display: inline-flex;
77
+ .experiments-filter {
78
+ padding-top: 1px;
79
+ display: flex;
80
+ align-items: center;
81
+ }
82
+
83
+ .experiments-filter label {
84
+ padding-right: 8px;
80
85
  flex-shrink: 0;
81
86
  }
82
87
 
@@ -603,7 +603,7 @@ export class DebuggerPlugin extends Plugin {
603
603
  } else if (/^text\/(javascript|typescript|jsx)/.test(this.uiSourceCode.mimeType())) {
604
604
  let node: CodeMirror.SyntaxNode|null = CodeMirror.syntaxTree(editor.state).resolveInner(textPosition, 1);
605
605
  // Only do something if the cursor is over a leaf node.
606
- if (node.firstChild) {
606
+ if (node?.firstChild) {
607
607
  return null;
608
608
  }
609
609
  while (
@@ -1137,7 +1137,7 @@ export class NavigatorSourceTreeElement extends UI.TreeOutline.TreeElement {
1137
1137
  super.selectOnMouseDown(event);
1138
1138
  return;
1139
1139
  }
1140
- setTimeout(rename.bind(this), 300);
1140
+ window.setTimeout(rename.bind(this), 300);
1141
1141
 
1142
1142
  function rename(this: NavigatorSourceTreeElement): void {
1143
1143
  if (this.shouldRenameOnMouseDown()) {
@@ -240,7 +240,7 @@ export class SourcesSearchScope implements Search.SearchConfig.SearchScope {
240
240
 
241
241
  ++callbacksLeft;
242
242
  const uiSourceCode = files[fileIndex++];
243
- setTimeout(searchInNextFile.bind(this, uiSourceCode), 0);
243
+ window.setTimeout(searchInNextFile.bind(this, uiSourceCode), 0);
244
244
  }
245
245
 
246
246
  function contentLoaded(
@@ -146,7 +146,7 @@ export class TimelineController implements SDK.TargetManager.SDKModelObserver<SD
146
146
  const extensionCompletionPromises = this.extensionSessions.map(session => session.stop());
147
147
  if (extensionCompletionPromises.length) {
148
148
  tracingStoppedPromises.push(
149
- Promise.race([Promise.all(extensionCompletionPromises), new Promise(r => setTimeout(r, 5000))]));
149
+ Promise.race([Promise.all(extensionCompletionPromises), new Promise(r => window.setTimeout(r, 5000))]));
150
150
  }
151
151
  await Promise.all(tracingStoppedPromises);
152
152
  }
@@ -222,7 +222,7 @@ export class TimelineController implements SDK.TargetManager.SDKModelObserver<SD
222
222
 
223
223
  private allSourcesFinished(): void {
224
224
  this.client.processingStarted();
225
- setTimeout(() => this.finalizeTrace(), 0);
225
+ window.setTimeout(() => this.finalizeTrace(), 0);
226
226
  }
227
227
 
228
228
  private async finalizeTrace(): Promise<void> {