blob: 1824bf8b20b89a9352402ff00dd765c629df5e4d [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4/* eslint-disable indent */
5(function(window) {
6
Nikolay Vitkov42be2662023-01-12 15:32:357// DevToolsAPI ----------------------------------------------------------------
Blink Reformat4c46d092018-04-07 15:32:378
Nikolay Vitkov42be2662023-01-12 15:32:359const DevToolsAPIImpl = class {
10 constructor() {
Blink Reformat4c46d092018-04-07 15:32:3711 /**
Nikolay Vitkov42be2662023-01-12 15:32:3512 * @type {number}
Blink Reformat4c46d092018-04-07 15:32:3713 */
Nikolay Vitkov42be2662023-01-12 15:32:3514 this._lastCallId = 0;
Blink Reformat4c46d092018-04-07 15:32:3715
16 /**
Nikolay Vitkov42be2662023-01-12 15:32:3517 * @type {!Object.<number, function(?Object)>}
Blink Reformat4c46d092018-04-07 15:32:3718 */
Nikolay Vitkov42be2662023-01-12 15:32:3519 this._callbacks = {};
Blink Reformat4c46d092018-04-07 15:32:3720
21 /**
Nikolay Vitkov42be2662023-01-12 15:32:3522 * @type {!Array.<!ExtensionDescriptor>}
Blink Reformat4c46d092018-04-07 15:32:3723 */
Nikolay Vitkov42be2662023-01-12 15:32:3524 this._pendingExtensionDescriptors = [];
Blink Reformat4c46d092018-04-07 15:32:3725
26 /**
Nikolay Vitkov42be2662023-01-12 15:32:3527 * @type {?function(!ExtensionDescriptor)}
Blink Reformat4c46d092018-04-07 15:32:3728 */
Nikolay Vitkov42be2662023-01-12 15:32:3529 this._addExtensionCallback = null;
Blink Reformat4c46d092018-04-07 15:32:3730
31 /**
Nikolay Vitkov42be2662023-01-12 15:32:3532 * @type {!Array<string>}
Danil Somsikov1f747672022-02-02 10:44:4433 */
Nikolay Vitkov42be2662023-01-12 15:32:3534 this._originsForbiddenForExtensions = [];
Danil Somsikov1f747672022-02-02 10:44:4435
36 /**
Nikolay Vitkov42be2662023-01-12 15:32:3537 * @type {!Promise<string>}
Danil Somsikov1f747672022-02-02 10:44:4438 */
Nikolay Vitkov42be2662023-01-12 15:32:3539 this._initialTargetIdPromise = new Promise(resolve => {
40 this._setInitialTargetId = resolve;
41 });
Blink Reformat4c46d092018-04-07 15:32:3742 }
43
Nikolay Vitkov42be2662023-01-12 15:32:3544 /**
45 * @param {number} id
46 * @param {?Object} arg
47 */
48 embedderMessageAck(id, arg) {
49 const callback = this._callbacks[id];
50 delete this._callbacks[id];
51 if (callback) {
52 callback(arg);
53 }
54 }
Blink Reformat4c46d092018-04-07 15:32:3755
56 /**
Nikolay Vitkov42be2662023-01-12 15:32:3557 * @param {string} method
58 * @param {!Array.<*>} args
59 * @param {?function(?Object)} callback
60 */
61 sendMessageToEmbedder(method, args, callback) {
62 const callId = ++this._lastCallId;
63 if (callback) {
64 this._callbacks[callId] = callback;
65 }
66 const message = {'id': callId, 'method': method};
67 if (args.length) {
68 message.params = args;
69 }
70 DevToolsHost.sendMessageToEmbedder(JSON.stringify(message));
71 }
72
73 /**
74 * @param {string} method
75 * @param {!Array<*>} args
76 */
77 _dispatchOnInspectorFrontendAPI(method, args) {
78 const inspectorFrontendAPI = /** @type {!Object<string, function()>} */ (window['InspectorFrontendAPI']);
79 inspectorFrontendAPI[method].apply(inspectorFrontendAPI, args);
80 }
81
82 // API methods below this line --------------------------------------------
83
84 /**
85 * @param {!Array.<!ExtensionDescriptor>} extensions
86 */
87 addExtensions(extensions) {
88 // Support for legacy front-ends (<M41).
89 if (window['WebInspector'] && window['WebInspector']['addExtensions']) {
90 window['WebInspector']['addExtensions'](extensions);
91 } else {
92 // The addExtensions command is sent as the onload event happens for
93 // DevTools front-end. We should buffer this command until the frontend
94 // is ready for it.
95 if (this._addExtensionCallback) {
96 extensions.forEach(this._addExtensionCallback);
97 } else {
98 this._pendingExtensionDescriptors.push(...extensions);
99 }
100 }
101 }
102
103 /**
104 * @param {!Array<string>} forbiddenOrigins
105 */
106 setOriginsForbiddenForExtensions(forbiddenOrigins) {
107 this._originsForbiddenForExtensions = forbiddenOrigins;
108 }
109
110 /**
111 * @return {!Array<string>}
112 */
113 getOriginsForbiddenForExtensions() {
114 return this._originsForbiddenForExtensions;
115 }
116
117 /**
118 * @param {string} url
119 */
120 appendedToURL(url) {
121 this._dispatchOnInspectorFrontendAPI('appendedToURL', [url]);
122 }
123
124 /**
125 * @param {string} url
126 */
127 canceledSaveURL(url) {
128 this._dispatchOnInspectorFrontendAPI('canceledSaveURL', [url]);
129 }
130
131 contextMenuCleared() {
132 this._dispatchOnInspectorFrontendAPI('contextMenuCleared', []);
133 }
134
135 /**
136 * @param {string} id
137 */
138 contextMenuItemSelected(id) {
139 this._dispatchOnInspectorFrontendAPI('contextMenuItemSelected', [id]);
140 }
141
142 /**
143 * @param {number} count
144 */
145 deviceCountUpdated(count) {
146 this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
147 }
148
149 /**
150 * @param {!Adb.Config} config
151 */
152 devicesDiscoveryConfigChanged(config) {
153 this._dispatchOnInspectorFrontendAPI('devicesDiscoveryConfigChanged', [config]);
154 }
155
156 /**
157 * @param {!Adb.PortForwardingStatus} status
158 */
159 devicesPortForwardingStatusChanged(status) {
160 this._dispatchOnInspectorFrontendAPI('devicesPortForwardingStatusChanged', [status]);
161 }
162
163 /**
164 * @param {!Array.<!Adb.Device>} devices
165 */
166 devicesUpdated(devices) {
167 this._dispatchOnInspectorFrontendAPI('devicesUpdated', [devices]);
168 }
169
170 /**
171 * @param {string} message
172 */
173 dispatchMessage(message) {
174 this._dispatchOnInspectorFrontendAPI('dispatchMessage', [message]);
175 }
176
177 /**
178 * @param {string} messageChunk
179 * @param {number} messageSize
180 */
181 dispatchMessageChunk(messageChunk, messageSize) {
182 this._dispatchOnInspectorFrontendAPI('dispatchMessageChunk', [messageChunk, messageSize]);
183 }
184
185 enterInspectElementMode() {
186 this._dispatchOnInspectorFrontendAPI('enterInspectElementMode', []);
187 }
188
189 /**
190 * @param {!{r: number, g: number, b: number, a: number}} color
191 */
192 eyeDropperPickedColor(color) {
193 this._dispatchOnInspectorFrontendAPI('eyeDropperPickedColor', [color]);
194 }
195
196 /**
197 * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems
198 */
199 fileSystemsLoaded(fileSystems) {
200 this._dispatchOnInspectorFrontendAPI('fileSystemsLoaded', [fileSystems]);
201 }
202
203 /**
204 * @param {string} fileSystemPath
205 */
206 fileSystemRemoved(fileSystemPath) {
207 this._dispatchOnInspectorFrontendAPI('fileSystemRemoved', [fileSystemPath]);
208 }
209
210 /**
211 * @param {?string} error
212 * @param {?{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem
213 */
214 fileSystemAdded(error, fileSystem) {
215 this._dispatchOnInspectorFrontendAPI('fileSystemAdded', [error, fileSystem]);
216 }
217
218 /**
219 * @param {!Array<string>} changedPaths
220 * @param {!Array<string>} addedPaths
221 * @param {!Array<string>} removedPaths
222 */
223 fileSystemFilesChangedAddedRemoved(changedPaths, addedPaths, removedPaths) {
224 // Support for legacy front-ends (<M58)
225 if (window['InspectorFrontendAPI'] && window['InspectorFrontendAPI']['fileSystemFilesChanged']) {
226 this._dispatchOnInspectorFrontendAPI(
227 'fileSystemFilesChanged', [changedPaths.concat(addedPaths).concat(removedPaths)]);
228 } else {
229 this._dispatchOnInspectorFrontendAPI(
230 'fileSystemFilesChangedAddedRemoved', [changedPaths, addedPaths, removedPaths]);
231 }
232 }
233
234 /**
235 * @param {number} requestId
236 * @param {string} fileSystemPath
237 * @param {number} totalWork
238 */
239 indexingTotalWorkCalculated(requestId, fileSystemPath, totalWork) {
240 this._dispatchOnInspectorFrontendAPI('indexingTotalWorkCalculated', [requestId, fileSystemPath, totalWork]);
241 }
242
243 /**
244 * @param {number} requestId
245 * @param {string} fileSystemPath
246 * @param {number} worked
247 */
248 indexingWorked(requestId, fileSystemPath, worked) {
249 this._dispatchOnInspectorFrontendAPI('indexingWorked', [requestId, fileSystemPath, worked]);
250 }
251
252 /**
253 * @param {number} requestId
254 * @param {string} fileSystemPath
255 */
256 indexingDone(requestId, fileSystemPath) {
257 this._dispatchOnInspectorFrontendAPI('indexingDone', [requestId, fileSystemPath]);
258 }
259
260 /**
261 * @param {{type: string, key: string, code: string, keyCode: number, modifiers: number}} event
262 */
263 keyEventUnhandled(event) {
264 event.keyIdentifier = keyCodeToKeyIdentifier(event.keyCode);
265 this._dispatchOnInspectorFrontendAPI('keyEventUnhandled', [event]);
266 }
267
268 /**
269 * @param {function(!ExtensionDescriptor)} callback
270 */
271 setAddExtensionCallback(callback) {
272 this._addExtensionCallback = callback;
273 if (this._pendingExtensionDescriptors.length) {
274 this._pendingExtensionDescriptors.forEach(this._addExtensionCallback);
275 this._pendingExtensionDescriptors = [];
276 }
277 }
278
279 reattachMainTarget() {
280 this._dispatchOnInspectorFrontendAPI('reattachMainTarget', []);
281 }
282
283 /**
284 * @param {boolean} hard
285 */
286 reloadInspectedPage(hard) {
287 this._dispatchOnInspectorFrontendAPI('reloadInspectedPage', [hard]);
288 }
289
290 /**
291 * @param {string} url
292 * @param {number} lineNumber
293 * @param {number} columnNumber
294 */
295 revealSourceLine(url, lineNumber, columnNumber) {
296 this._dispatchOnInspectorFrontendAPI('revealSourceLine', [url, lineNumber, columnNumber]);
297 }
298
299 /**
300 * @param {string} url
301 * @param {string=} fileSystemPath
302 */
303 savedURL(url, fileSystemPath) {
304 this._dispatchOnInspectorFrontendAPI('savedURL', [url, fileSystemPath]);
305 }
306
307 /**
308 * @param {number} requestId
309 * @param {string} fileSystemPath
310 * @param {!Array.<string>} files
311 */
312 searchCompleted(requestId, fileSystemPath, files) {
313 this._dispatchOnInspectorFrontendAPI('searchCompleted', [requestId, fileSystemPath, files]);
314 }
315
316 /**
317 * @param {string} tabId
318 */
319 setInspectedTabId(tabId) {
320 this._inspectedTabIdValue = tabId;
321
322 // Support for legacy front-ends (<M41).
323 if (window['WebInspector'] && window['WebInspector']['setInspectedTabId']) {
324 window['WebInspector']['setInspectedTabId'](tabId);
325 } else {
326 this._dispatchOnInspectorFrontendAPI('setInspectedTabId', [tabId]);
327 }
328 }
329
330 /**
331 * @param {string} targetId
332 */
333 setInitialTargetId(targetId) {
334 this._setInitialTargetId(targetId);
335 }
336
337 /**
338 * @return {string|undefined}
339 */
340 getInspectedTabId() {
341 return this._inspectedTabIdValue;
342 }
343
344 /**
345 * @param {boolean} useSoftMenu
346 */
347 setUseSoftMenu(useSoftMenu) {
348 this._dispatchOnInspectorFrontendAPI('setUseSoftMenu', [useSoftMenu]);
349 }
350
351 /**
352 * @param {string} panelName
353 */
354 showPanel(panelName) {
355 this._dispatchOnInspectorFrontendAPI('showPanel', [panelName]);
356 }
357
358 /**
359 * @param {number} id
360 * @param {string} chunk
361 * @param {boolean} encoded
362 */
363 streamWrite(id, chunk, encoded) {
364 this._dispatchOnInspectorFrontendAPI('streamWrite', [id, encoded ? this._decodeBase64(chunk) : chunk]);
365 }
366
367 /**
368 * @param {string} chunk
Blink Reformat4c46d092018-04-07 15:32:37369 * @return {string}
370 */
Nikolay Vitkov42be2662023-01-12 15:32:35371 _decodeBase64(chunk) {
372 const request = new XMLHttpRequest();
373 request.open('GET', 'data:text/plain;base64,' + chunk, false);
374 request.send(null);
375 if (request.status === 200) {
376 return request.responseText;
Tim van der Lippe1d6e57a2019-09-30 11:55:34377 }
Nikolay Vitkov42be2662023-01-12 15:32:35378 console.error('Error while decoding chunk in streamWrite');
379 return '';
380 }
381};
382
383const DevToolsAPI = new DevToolsAPIImpl();
384window.DevToolsAPI = DevToolsAPI;
385
386// InspectorFrontendHostImpl --------------------------------------------------
387
388/**
389 * Enum for recordPerformanceHistogram
390 * Warning: There is another definition of this enum in the DevTools code
391 * base, keep them in sync:
392 * front_end/core/host/InspectorFrontendHostAPI.ts
393 * @readonly
394 * @enum {string}
395 */
396const EnumeratedHistogram = {
397 ActionTaken: 'DevTools.ActionTaken',
398 BreakpointWithConditionAdded: 'DevTools.BreakpointWithConditionAdded',
399 BreakpointEditDialogRevealedFrom: 'DevTools.BreakpointEditDialogRevealedFrom',
400 CSSHintShown: 'DevTools.CSSHintShown',
401 DeveloperResourceLoaded: 'DevTools.DeveloperResourceLoaded',
402 DeveloperResourceScheme: 'DevTools.DeveloperResourceScheme',
Ergun Erdogmus6f52cb72023-06-01 11:51:51403 ElementsSidebarTabShown: 'DevTools.Elements.SidebarTabShown',
Nikolay Vitkov42be2662023-01-12 15:32:35404 ExperimentDisabled: 'DevTools.ExperimentDisabled',
405 ExperimentEnabled: 'DevTools.ExperimentEnabled',
406 ExperimentEnabledAtLaunch: 'DevTools.ExperimentEnabledAtLaunch',
407 IssueCreated: 'DevTools.IssueCreated',
408 IssuesPanelIssueExpanded: 'DevTools.IssuesPanelIssueExpanded',
409 IssuesPanelOpenedFrom: 'DevTools.IssuesPanelOpenedFrom',
410 IssuesPanelResourceOpened: 'DevTools.IssuesPanelResourceOpened',
411 KeybindSetSettingChanged: 'DevTools.KeybindSetSettingChanged',
412 KeyboardShortcutFired: 'DevTools.KeyboardShortcutFired',
413 Language: 'DevTools.Language',
414 LighthouseModeRun: 'DevTools.LighthouseModeRun',
415 LinearMemoryInspectorRevealedFrom: 'DevTools.LinearMemoryInspector.RevealedFrom',
416 LinearMemoryInspectorTarget: 'DevTools.LinearMemoryInspector.Target',
417 ManifestSectionSelected: 'DevTools.ManifestSectionSelected',
418 PanelClosed: 'DevTools.PanelClosed',
419 PanelShown: 'DevTools.PanelShown',
Randolf Jungd3ea3e62023-04-11 09:10:09420 RecordingAssertion: 'DevTools.RecordingAssertion',
Nikolay Vitkov42be2662023-01-12 15:32:35421 RecordingCodeToggled: 'DevTools.RecordingCodeToggled',
422 RecordingCopiedToClipboard: 'DevTools.RecordingCopiedToClipboard',
423 RecordingEdited: 'DevTools.RecordingEdited',
424 RecordingExported: 'DevTools.RecordingExported',
425 RecordingReplayFinished: 'DevTools.RecordingReplayFinished',
426 RecordingReplaySpeed: 'DevTools.RecordingReplaySpeed',
427 RecordingReplayStarted: 'DevTools.RecordingReplayStarted',
428 RecordingToggled: 'DevTools.RecordingToggled',
429 SidebarPaneShown: 'DevTools.SidebarPaneShown',
Ergun Erdogmus6f52cb72023-06-01 11:51:51430 SourcesSidebarTabShown: 'DevTools.Sources.SidebarTabShown',
Simon Zünddc8c1452023-05-16 09:53:50431 SourcesPanelFileDebugged: 'DevTools.SourcesPanelFileDebugged',
Nikolay Vitkov42be2662023-01-12 15:32:35432 SourcesPanelFileOpened: 'DevTools.SourcesPanelFileOpened',
433 NetworkPanelResponsePreviewOpened: 'DevTools.NetworkPanelResponsePreviewOpened',
434 StyleTextCopied: 'DevTools.StyleTextCopied',
435 SyncSetting: 'DevTools.SyncSetting',
Changhao Hana49f2452023-03-16 10:12:10436 ColorConvertedFrom: 'DevTools.ColorConvertedFrom',
437 ColorPickerOpenedFrom: 'DevTools.ColorPickerOpenedFrom',
438 CSSPropertyDocumentation: 'DevTools.CSSPropertyDocumentation',
Changhao Han2df6fc22023-05-22 09:36:32439 InlineScriptParsed: 'DevTools.InlineScriptParsed',
440 VMInlineScriptTypeShown: 'DevTools.VMInlineScriptShown',
441 BreakpointsRestoredFromStorageCount: 'DevTools.BreakpointsRestoredFromStorageCount',
442 SwatchActivated: 'DevTools.SwatchActivated',
Nikolay Vitkov42be2662023-01-12 15:32:35443};
444
445/**
446 * @implements {InspectorFrontendHostAPI}
447 */
448const InspectorFrontendHostImpl = class {
449 /**
450 * @return {string}
451 */
452 getSelectionBackgroundColor() {
453 return '#6e86ff';
Blink Reformat4c46d092018-04-07 15:32:37454 }
455
Nikolay Vitkov42be2662023-01-12 15:32:35456 /**
457 * @return {string}
458 */
459 getSelectionForegroundColor() {
460 return '#ffffff';
461 }
Blink Reformat4c46d092018-04-07 15:32:37462
Nikolay Vitkov42be2662023-01-12 15:32:35463 /**
464 * @return {string}
465 */
466 getInactiveSelectionBackgroundColor() {
467 return '#c9c8c8';
468 }
Joel Einbinder82b1d8e2018-12-08 01:01:37469
Nikolay Vitkov42be2662023-01-12 15:32:35470 /**
471 * @return {string}
472 */
473 getInactiveSelectionForegroundColor() {
474 return '#323232';
475 }
Joel Einbinder82b1d8e2018-12-08 01:01:37476
Nikolay Vitkov42be2662023-01-12 15:32:35477 /**
478 * @override
479 * @return {string}
480 */
481 platform() {
482 return DevToolsHost.platform();
483 }
Joel Einbinder82b1d8e2018-12-08 01:01:37484
Nikolay Vitkov42be2662023-01-12 15:32:35485 /**
486 * @override
487 */
488 loadCompleted() {
489 DevToolsAPI.sendMessageToEmbedder('loadCompleted', [], null);
490 // Support for legacy (<57) frontends.
491 if (window.Runtime && window.Runtime.queryParam) {
492 const panelToOpen = window.Runtime.queryParam('panel');
493 if (panelToOpen) {
494 window.DevToolsAPI.showPanel(panelToOpen);
Joel Einbinderf55cc942018-10-30 01:59:53495 }
Blink Reformat4c46d092018-04-07 15:32:37496 }
Nikolay Vitkov42be2662023-01-12 15:32:35497 }
Blink Reformat4c46d092018-04-07 15:32:37498
Nikolay Vitkov42be2662023-01-12 15:32:35499 /**
500 * @override
501 */
502 bringToFront() {
503 DevToolsAPI.sendMessageToEmbedder('bringToFront', [], null);
504 }
505
506 /**
507 * @override
508 */
509 closeWindow() {
510 DevToolsAPI.sendMessageToEmbedder('closeWindow', [], null);
511 }
512
513 /**
514 * @override
515 * @param {boolean} isDocked
516 * @param {function()} callback
517 */
518 setIsDocked(isDocked, callback) {
519 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [isDocked], callback);
520 }
521
522 /**
523 * @override
524 * @param {string} trigger
525 * @param {function(!InspectorFrontendHostAPI.ShowSurveyResult): void} callback
526 */
527 showSurvey(trigger, callback) {
528 DevToolsAPI.sendMessageToEmbedder('showSurvey', [trigger], /** @type {function(?Object)} */ (callback));
529 }
530
531 /**
532 * @override
533 * @param {string} trigger
534 * @param {function(!InspectorFrontendHostAPI.CanShowSurveyResult): void} callback
535 */
536 canShowSurvey(trigger, callback) {
537 DevToolsAPI.sendMessageToEmbedder('canShowSurvey', [trigger], /** @type {function(?Object)} */ (callback));
538 }
539
540 /**
541 * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
542 * @override
543 * @param {{x: number, y: number, width: number, height: number}} bounds
544 */
545 setInspectedPageBounds(bounds) {
546 DevToolsAPI.sendMessageToEmbedder('setInspectedPageBounds', [bounds], null);
547 }
548
549 /**
550 * @override
551 */
552 inspectElementCompleted() {
553 DevToolsAPI.sendMessageToEmbedder('inspectElementCompleted', [], null);
554 }
555
556 /**
557 * @override
558 * @param {string} url
559 * @param {string} headers
560 * @param {number} streamId
561 * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult): void} callback
562 */
563 loadNetworkResource(url, headers, streamId, callback) {
564 DevToolsAPI.sendMessageToEmbedder(
565 'loadNetworkResource', [url, headers, streamId], /** @type {function(?Object)} */ (callback));
566 }
567
568 /**
569 * @override
570 * @param {string} name
571 * @param {!{synced: (boolean|undefined)}} options
572 */
573 registerPreference(name, options) {
574 DevToolsAPI.sendMessageToEmbedder('registerPreference', [name, options], null);
575 }
576
577 /**
578 * @override
579 * @param {function(!Object<string, string>)} callback
580 */
581 getPreferences(callback) {
582 DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback));
583 }
584
585 /**
586 * @override
587 * @param {string} name
588 * @param {function(string)} callback
589 */
590 getPreference(name, callback) {
591 DevToolsAPI.sendMessageToEmbedder('getPreference', [name], /** @type {function(string)} */ (callback));
592 }
593
594 /**
595 * @override
596 * @param {string} name
597 * @param {string} value
598 */
599 setPreference(name, value) {
600 DevToolsAPI.sendMessageToEmbedder('setPreference', [name, value], null);
601 }
602
603 /**
604 * @override
605 * @param {string} name
606 */
607 removePreference(name) {
608 DevToolsAPI.sendMessageToEmbedder('removePreference', [name], null);
609 }
610
611 /**
612 * @override
613 */
614 clearPreferences() {
615 DevToolsAPI.sendMessageToEmbedder('clearPreferences', [], null);
616 }
617
618 /**
619 * @override
620 * @param {!function(!InspectorFrontendHostAPI.SyncInformation):void} callback
621 */
622 getSyncInformation(callback) {
623 DevToolsAPI.sendMessageToEmbedder('getSyncInformation', [], callback);
624 }
625
626 /**
627 * @override
628 * @param {string} origin
629 * @param {string} script
630 */
631 setInjectedScriptForOrigin(origin, script) {
632 DevToolsAPI.sendMessageToEmbedder('registerExtensionsAPI', [origin, script], null);
633 }
634
635 /**
636 * @override
637 * @param {string} url
638 */
639 inspectedURLChanged(url) {
640 DevToolsAPI.sendMessageToEmbedder('inspectedURLChanged', [url], null);
641 }
642
643 /**
644 * @override
645 * @param {string} text
646 */
647 copyText(text) {
648 DevToolsHost.copyText(text);
649 }
650
651 /**
652 * @override
653 * @param {string} url
654 */
655 openInNewTab(url) {
656 DevToolsAPI.sendMessageToEmbedder('openInNewTab', [url], null);
657 }
658
659 /**
660 * @override
661 * @param {string} fileSystemPath
662 */
663 showItemInFolder(fileSystemPath) {
664 DevToolsAPI.sendMessageToEmbedder('showItemInFolder', [fileSystemPath], null);
665 }
666
667 /**
668 * @override
669 * @param {string} url
670 * @param {string} content
671 * @param {boolean} forceSaveAs
672 */
673 save(url, content, forceSaveAs) {
674 DevToolsAPI.sendMessageToEmbedder('save', [url, content, forceSaveAs], null);
675 }
676
677 /**
678 * @override
679 * @param {string} url
680 * @param {string} content
681 */
682 append(url, content) {
683 DevToolsAPI.sendMessageToEmbedder('append', [url, content], null);
684 }
685
686 /**
687 * @override
688 * @param {string} url
689 */
690 close(url) {
691 }
692
693 /**
694 * @override
695 * @param {string} message
696 */
697 sendMessageToBackend(message) {
698 DevToolsAPI.sendMessageToEmbedder('dispatchProtocolMessage', [message], null);
699 }
700
701 /**
702 * @override
703 * @param {!InspectorFrontendHostAPI.EnumeratedHistogram} actionName
704 * @param {number} actionCode
705 * @param {number} bucketSize
706 */
707 recordEnumeratedHistogram(actionName, actionCode, bucketSize) {
708 if (!Object.values(EnumeratedHistogram).includes(actionName)) {
709 return;
710 }
711 DevToolsAPI.sendMessageToEmbedder('recordEnumeratedHistogram', [actionName, actionCode, bucketSize], null);
712 }
713
714 /**
715 * @override
716 * @param {string} histogramName
717 * @param {number} duration
718 */
719 recordPerformanceHistogram(histogramName, duration) {
720 DevToolsAPI.sendMessageToEmbedder('recordPerformanceHistogram', [histogramName, duration], null);
721 }
722
723 /**
724 * @override
725 * @param {string} umaName
726 */
727 recordUserMetricsAction(umaName) {
728 DevToolsAPI.sendMessageToEmbedder('recordUserMetricsAction', [umaName], null);
729 }
730
731 /**
732 * @override
733 */
734 requestFileSystems() {
735 DevToolsAPI.sendMessageToEmbedder('requestFileSystems', [], null);
736 }
737
738 /**
739 * @override
740 * @param {string=} type
741 */
742 addFileSystem(type) {
743 DevToolsAPI.sendMessageToEmbedder('addFileSystem', [type || ''], null);
744 }
745
746 /**
747 * @override
748 * @param {string} fileSystemPath
749 */
750 removeFileSystem(fileSystemPath) {
751 DevToolsAPI.sendMessageToEmbedder('removeFileSystem', [fileSystemPath], null);
752 }
753
754 /**
755 * @override
756 * @param {string} fileSystemId
757 * @param {string} registeredName
758 * @return {?FileSystem}
759 */
760 isolatedFileSystem(fileSystemId, registeredName) {
761 return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName);
762 }
763
764 /**
765 * @override
766 * @param {!FileSystem} fileSystem
767 */
768 upgradeDraggedFileSystemPermissions(fileSystem) {
769 DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem);
770 }
771
772 /**
773 * @override
774 * @param {number} requestId
775 * @param {string} fileSystemPath
776 * @param {string} excludedFolders
777 */
778 indexPath(requestId, fileSystemPath, excludedFolders) {
779 // |excludedFolders| added in M67. For backward compatibility,
780 // pass empty array.
781 excludedFolders = excludedFolders || '[]';
782 DevToolsAPI.sendMessageToEmbedder('indexPath', [requestId, fileSystemPath, excludedFolders], null);
783 }
784
785 /**
786 * @override
787 * @param {number} requestId
788 */
789 stopIndexing(requestId) {
790 DevToolsAPI.sendMessageToEmbedder('stopIndexing', [requestId], null);
791 }
792
793 /**
794 * @override
795 * @param {number} requestId
796 * @param {string} fileSystemPath
797 * @param {string} query
798 */
799 searchInPath(requestId, fileSystemPath, query) {
800 DevToolsAPI.sendMessageToEmbedder('searchInPath', [requestId, fileSystemPath, query], null);
801 }
802
803 /**
804 * @override
805 * @return {number}
806 */
807 zoomFactor() {
808 return DevToolsHost.zoomFactor();
809 }
810
811 /**
812 * @override
813 */
814 zoomIn() {
815 DevToolsAPI.sendMessageToEmbedder('zoomIn', [], null);
816 }
817
818 /**
819 * @override
820 */
821 zoomOut() {
822 DevToolsAPI.sendMessageToEmbedder('zoomOut', [], null);
823 }
824
825 /**
826 * @override
827 */
828 resetZoom() {
829 DevToolsAPI.sendMessageToEmbedder('resetZoom', [], null);
830 }
831
832 /**
833 * @override
834 * @param {string} shortcuts
835 */
836 setWhitelistedShortcuts(shortcuts) {
837 DevToolsAPI.sendMessageToEmbedder('setWhitelistedShortcuts', [shortcuts], null);
838 }
839
840 /**
841 * @override
842 * @param {boolean} active
843 */
844 setEyeDropperActive(active) {
845 DevToolsAPI.sendMessageToEmbedder('setEyeDropperActive', [active], null);
846 }
847
848 /**
849 * @override
850 * @param {!Array<string>} certChain
851 */
852 showCertificateViewer(certChain) {
853 DevToolsAPI.sendMessageToEmbedder('showCertificateViewer', [JSON.stringify(certChain)], null);
854 }
855
856 /**
857 * Only needed to run Lighthouse on old devtools.
858 * @override
859 * @param {function()} callback
860 */
861 reattach(callback) {
862 DevToolsAPI.sendMessageToEmbedder('reattach', [], callback);
863 }
864
865 /**
866 * @override
867 */
868 readyForTest() {
869 DevToolsAPI.sendMessageToEmbedder('readyForTest', [], null);
870 }
871
872 /**
873 * @override
874 */
875 connectionReady() {
876 DevToolsAPI.sendMessageToEmbedder('connectionReady', [], null);
877 }
878
879 /**
880 * @override
881 * @param {boolean} value
882 */
883 setOpenNewWindowForPopups(value) {
884 DevToolsAPI.sendMessageToEmbedder('setOpenNewWindowForPopups', [value], null);
885 }
886
887 /**
888 * @override
889 * @param {!Adb.Config} config
890 */
891 setDevicesDiscoveryConfig(config) {
892 DevToolsAPI.sendMessageToEmbedder(
893 'setDevicesDiscoveryConfig',
894 [
895 config.discoverUsbDevices, config.portForwardingEnabled, JSON.stringify(config.portForwardingConfig),
896 config.networkDiscoveryEnabled, JSON.stringify(config.networkDiscoveryConfig)
897 ],
898 null);
899 }
900
901 /**
902 * @override
903 * @param {boolean} enabled
904 */
905 setDevicesUpdatesEnabled(enabled) {
906 DevToolsAPI.sendMessageToEmbedder('setDevicesUpdatesEnabled', [enabled], null);
907 }
908
909 /**
910 * @override
911 * @param {string} pageId
912 * @param {string} action
913 */
914 performActionOnRemotePage(pageId, action) {
915 DevToolsAPI.sendMessageToEmbedder('performActionOnRemotePage', [pageId, action], null);
916 }
917
918 /**
919 * @override
920 * @param {string} browserId
921 * @param {string} url
922 */
923 openRemotePage(browserId, url) {
924 DevToolsAPI.sendMessageToEmbedder('openRemotePage', [browserId, url], null);
925 }
926
927 /**
928 * @override
929 */
930 openNodeFrontend() {
931 DevToolsAPI.sendMessageToEmbedder('openNodeFrontend', [], null);
932 }
933
934 /**
935 * @override
936 * @param {number} x
937 * @param {number} y
938 * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
939 * @param {!Document} document
940 */
941 showContextMenuAtPoint(x, y, items, document) {
942 DevToolsHost.showContextMenuAtPoint(x, y, items, document);
943 }
944
945 /**
946 * @override
947 * @return {boolean}
948 */
949 isHostedMode() {
950 return DevToolsHost.isHostedMode();
951 }
952
953 /**
954 * @override
955 * @param {function(!ExtensionDescriptor)} callback
956 */
957 setAddExtensionCallback(callback) {
958 DevToolsAPI.setAddExtensionCallback(callback);
959 }
960
961 // Backward-compatible methods below this line --------------------------------------------
962
963 /**
964 * Support for legacy front-ends (<M65).
965 * @return {boolean}
966 */
967 isUnderTest() {
968 return false;
969 }
970
971 /**
972 * Support for legacy front-ends (<M50).
973 * @param {string} message
974 */
975 sendFrontendAPINotification(message) {
976 }
977
978 /**
979 * Support for legacy front-ends (<M41).
980 * @return {string}
981 */
982 port() {
983 return 'unknown';
984 }
985
986 /**
987 * Support for legacy front-ends (<M38).
988 * @param {number} zoomFactor
989 */
990 setZoomFactor(zoomFactor) {
991 }
992
993 /**
994 * Support for legacy front-ends (<M34).
995 */
996 sendMessageToEmbedder() {
997 }
998
999 /**
1000 * Support for legacy front-ends (<M34).
1001 * @param {string} dockSide
1002 */
1003 requestSetDockSide(dockSide) {
1004 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [dockSide !== 'undocked'], null);
1005 }
1006
1007 /**
1008 * Support for legacy front-ends (<M34).
1009 * @return {boolean}
1010 */
1011 supportsFileSystems() {
1012 return true;
1013 }
1014
1015 /**
1016 * Support for legacy front-ends (<M44).
1017 * @param {number} actionCode
1018 */
1019 recordActionTaken(actionCode) {
1020 // Do not record actions, as that may crash the DevTools renderer.
1021 }
1022
1023 /**
1024 * Support for legacy front-ends (<M44).
1025 * @param {number} panelCode
1026 */
1027 recordPanelShown(panelCode) {
1028 // Do not record actions, as that may crash the DevTools renderer.
1029 }
1030
1031 /**
1032 * @return {!Promise<string>}
1033 */
1034 initialTargetId() {
1035 return DevToolsAPI._initialTargetIdPromise;
1036 }
1037};
1038
1039window.InspectorFrontendHost = new InspectorFrontendHostImpl();
1040
1041// DevToolsApp ---------------------------------------------------------------
1042
1043function installObjectObserve() {
1044 /** @type {!Array<string>} */
1045 const properties = [
1046 'advancedSearchConfig',
1047 'auditsPanelSplitViewState',
1048 'auditsSidebarWidth',
1049 'blockedURLs',
1050 'breakpoints',
1051 'cacheDisabled',
1052 'colorFormat',
1053 'consoleHistory',
1054 'consoleTimestampsEnabled',
1055 'cpuProfilerView',
1056 'cssSourceMapsEnabled',
1057 'currentDockState',
1058 'customColorPalette',
1059 'customDevicePresets',
1060 'customEmulatedDeviceList',
1061 'customFormatters',
1062 'customUserAgent',
1063 'databaseTableViewVisibleColumns',
1064 'dataGrid-cookiesTable',
1065 'dataGrid-DOMStorageItemsView',
1066 'debuggerSidebarHidden',
1067 'disablePausedStateOverlay',
1068 'domBreakpoints',
1069 'domWordWrap',
1070 'elementsPanelSplitViewState',
1071 'elementsSidebarWidth',
1072 'emulation.deviceHeight',
1073 'emulation.deviceModeValue',
1074 'emulation.deviceOrientationOverride',
1075 'emulation.deviceScale',
1076 'emulation.deviceScaleFactor',
1077 'emulation.deviceUA',
1078 'emulation.deviceWidth',
1079 'emulation.locationOverride',
1080 'emulation.showDeviceMode',
1081 'emulation.showRulers',
1082 'enableAsyncStackTraces',
1083 'enableIgnoreListing',
1084 'eventListenerBreakpoints',
1085 'fileMappingEntries',
1086 'fileSystemMapping',
1087 'FileSystemViewSidebarWidth',
1088 'fileSystemViewSplitViewState',
1089 'filterBar-consoleView',
1090 'filterBar-networkPanel',
1091 'filterBar-promisePane',
1092 'filterBar-timelinePanel',
1093 'frameViewerHideChromeWindow',
1094 'heapSnapshotRetainersViewSize',
1095 'heapSnapshotSplitViewState',
1096 'hideCollectedPromises',
1097 'hideNetworkMessages',
1098 'highlightNodeOnHoverInOverlay',
1099 'inlineVariableValues',
1100 'Inspector.drawerSplitView',
1101 'Inspector.drawerSplitViewState',
1102 'InspectorView.panelOrder',
1103 'InspectorView.screencastSplitView',
1104 'InspectorView.screencastSplitViewState',
1105 'InspectorView.splitView',
1106 'InspectorView.splitViewState',
1107 'javaScriptDisabled',
1108 'jsSourceMapsEnabled',
1109 'lastActivePanel',
1110 'lastDockState',
1111 'lastSelectedSourcesSidebarPaneTab',
1112 'lastSnippetEvaluationIndex',
1113 'layerDetailsSplitView',
1114 'layerDetailsSplitViewState',
1115 'layersPanelSplitViewState',
1116 'layersShowInternalLayers',
1117 'layersSidebarWidth',
1118 'messageLevelFilters',
1119 'messageURLFilters',
1120 'monitoringXHREnabled',
1121 'navigatorGroupByAuthored',
1122 'navigatorGroupByFolder',
1123 'navigatorHidden',
1124 'networkColorCodeResourceTypes',
1125 'networkConditions',
1126 'networkConditionsCustomProfiles',
1127 'networkHideDataURL',
1128 'networkLogColumnsVisibility',
1129 'networkLogLargeRows',
1130 'networkLogShowOverview',
1131 'networkPanelSplitViewState',
1132 'networkRecordFilmStripSetting',
1133 'networkResourceTypeFilters',
1134 'networkShowPrimaryLoadWaterfall',
1135 'networkSidebarWidth',
1136 'openLinkHandler',
1137 'pauseOnUncaughtException',
1138 'pauseOnCaughtException',
1139 'pauseOnExceptionEnabled',
1140 'preserveConsoleLog',
1141 'prettyPrintInfobarDisabled',
1142 'previouslyViewedFiles',
1143 'profilesPanelSplitViewState',
1144 'profilesSidebarWidth',
1145 'promiseStatusFilters',
1146 'recordAllocationStacks',
1147 'requestHeaderFilterSetting',
1148 'request-info-formData-category-expanded',
1149 'request-info-general-category-expanded',
1150 'request-info-queryString-category-expanded',
1151 'request-info-requestHeaders-category-expanded',
1152 'request-info-requestPayload-category-expanded',
1153 'request-info-responseHeaders-category-expanded',
1154 'resources',
1155 'resourcesLastSelectedItem',
1156 'resourcesPanelSplitViewState',
1157 'resourcesSidebarWidth',
1158 'resourceViewTab',
1159 'savedURLs',
1160 'screencastEnabled',
1161 'scriptsPanelNavigatorSidebarWidth',
1162 'searchInContentScripts',
1163 'selectedAuditCategories',
1164 'selectedColorPalette',
1165 'selectedProfileType',
1166 'shortcutPanelSwitch',
1167 'showAdvancedHeapSnapshotProperties',
1168 'showEventListenersForAncestors',
1169 'showFrameowkrListeners',
1170 'showHeaSnapshotObjectsHiddenProperties',
1171 'showInheritedComputedStyleProperties',
1172 'showMediaQueryInspector',
1173 'showNativeFunctionsInJSProfile',
1174 'showUAShadowDOM',
1175 'showWhitespacesInEditor',
1176 'sidebarPosition',
1177 'skipContentScripts',
1178 'automaticallyIgnoreListKnownThirdPartyScripts',
1179 'skipStackFramesPattern',
1180 'sourceMapInfobarDisabled',
1181 'sourcesPanelDebuggerSidebarSplitViewState',
1182 'sourcesPanelNavigatorSplitViewState',
1183 'sourcesPanelSplitSidebarRatio',
1184 'sourcesPanelSplitViewState',
1185 'sourcesSidebarWidth',
1186 'standardEmulatedDeviceList',
1187 'StylesPaneSplitRatio',
1188 'stylesPaneSplitViewState',
1189 'textEditorAutocompletion',
1190 'textEditorAutoDetectIndent',
1191 'textEditorBracketMatching',
1192 'textEditorIndent',
1193 'textEditorTabMovesFocus',
1194 'timelineCaptureFilmStrip',
1195 'timelineCaptureLayersAndPictures',
1196 'timelineCaptureMemory',
1197 'timelineCaptureNetwork',
1198 'timeline-details',
1199 'timelineEnableJSSampling',
1200 'timelineOverviewMode',
1201 'timelinePanelDetailsSplitViewState',
1202 'timelinePanelRecorsSplitViewState',
1203 'timelinePanelTimelineStackSplitViewState',
1204 'timelinePerspective',
1205 'timeline-split',
1206 'timelineTreeGroupBy',
1207 'timeline-view',
1208 'timelineViewMode',
1209 'uiTheme',
1210 'watchExpressions',
1211 'WebInspector.Drawer.lastSelectedView',
1212 'WebInspector.Drawer.showOnLoad',
1213 'workspaceExcludedFolders',
1214 'workspaceFolderExcludePattern',
1215 'workspaceInfobarDisabled',
1216 'workspaceMappingInfobarDisabled',
1217 'xhrBreakpoints'
1218 ];
1219
1220 /**
1221 * @this {!{_storage: Object, _name: string}}
1222 */
1223 function settingRemove() {
1224 this._storage[this._name] = undefined;
1225 }
1226
1227 /**
1228 * @param {!Object} object
1229 * @param {function(!Array<!{name: string}>)} observer
1230 */
1231 function objectObserve(object, observer) {
1232 if (window['WebInspector']) {
1233 const settingPrototype = /** @type {!Object} */ (window['WebInspector']['Setting']['prototype']);
1234 if (typeof settingPrototype['remove'] === 'function') {
1235 settingPrototype['remove'] = settingRemove;
1236 }
1237 }
1238 /** @type {!Set<string>} */
1239 const changedProperties = new Set();
1240 let scheduled = false;
1241
1242 function scheduleObserver() {
1243 if (scheduled) {
1244 return;
1245 }
1246 scheduled = true;
1247 queueMicrotask(callObserver);
1248 }
1249
1250 function callObserver() {
1251 scheduled = false;
1252 const changes = /** @type {!Array<!{name: string}>} */ ([]);
1253 changedProperties.forEach(function(name) {
1254 changes.push({name: name});
1255 });
1256 changedProperties.clear();
1257 observer.call(null, changes);
1258 }
1259
1260 /** @type {!Map<string, *>} */
1261 const storage = new Map();
1262
1263 /**
1264 * @param {string} property
1265 */
1266 function defineProperty(property) {
1267 if (property in object) {
1268 storage.set(property, object[property]);
1269 delete object[property];
1270 }
1271
1272 Object.defineProperty(object, property, {
Blink Reformat4c46d092018-04-07 15:32:371273 /**
Nikolay Vitkov42be2662023-01-12 15:32:351274 * @return {*}
Blink Reformat4c46d092018-04-07 15:32:371275 */
1276 get: function() {
Nikolay Vitkov42be2662023-01-12 15:32:351277 return storage.get(property);
1278 },
1279
1280 /**
1281 * @param {*} value
1282 */
1283 set: function(value) {
1284 storage.set(property, value);
1285 changedProperties.add(property);
1286 scheduleObserver();
Blink Reformat4c46d092018-04-07 15:32:371287 }
1288 });
1289 }
1290
Nikolay Vitkov42be2662023-01-12 15:32:351291 for (let i = 0; i < properties.length; ++i) {
1292 defineProperty(properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341293 }
Joel Einbinderf55cc942018-10-30 01:59:531294 }
Blink Reformat4c46d092018-04-07 15:32:371295
Nikolay Vitkov42be2662023-01-12 15:32:351296 window.Object.observe = objectObserve;
1297}
1298
1299/** @type {!Map<number, string>} */
1300const staticKeyIdentifiers = new Map([
1301 [0x12, 'Alt'],
1302 [0x11, 'Control'],
1303 [0x10, 'Shift'],
1304 [0x14, 'CapsLock'],
1305 [0x5b, 'Win'],
1306 [0x5c, 'Win'],
1307 [0x0c, 'Clear'],
1308 [0x28, 'Down'],
1309 [0x23, 'End'],
1310 [0x0a, 'Enter'],
1311 [0x0d, 'Enter'],
1312 [0x2b, 'Execute'],
1313 [0x70, 'F1'],
1314 [0x71, 'F2'],
1315 [0x72, 'F3'],
1316 [0x73, 'F4'],
1317 [0x74, 'F5'],
1318 [0x75, 'F6'],
1319 [0x76, 'F7'],
1320 [0x77, 'F8'],
1321 [0x78, 'F9'],
1322 [0x79, 'F10'],
1323 [0x7a, 'F11'],
1324 [0x7b, 'F12'],
1325 [0x7c, 'F13'],
1326 [0x7d, 'F14'],
1327 [0x7e, 'F15'],
1328 [0x7f, 'F16'],
1329 [0x80, 'F17'],
1330 [0x81, 'F18'],
1331 [0x82, 'F19'],
1332 [0x83, 'F20'],
1333 [0x84, 'F21'],
1334 [0x85, 'F22'],
1335 [0x86, 'F23'],
1336 [0x87, 'F24'],
1337 [0x2f, 'Help'],
1338 [0x24, 'Home'],
1339 [0x2d, 'Insert'],
1340 [0x25, 'Left'],
1341 [0x22, 'PageDown'],
1342 [0x21, 'PageUp'],
1343 [0x13, 'Pause'],
1344 [0x2c, 'PrintScreen'],
1345 [0x27, 'Right'],
1346 [0x91, 'Scroll'],
1347 [0x29, 'Select'],
1348 [0x26, 'Up'],
1349 [0x2e, 'U+007F'], // Standard says that DEL becomes U+007F.
1350 [0xb0, 'MediaNextTrack'],
1351 [0xb1, 'MediaPreviousTrack'],
1352 [0xb2, 'MediaStop'],
1353 [0xb3, 'MediaPlayPause'],
1354 [0xad, 'VolumeMute'],
1355 [0xae, 'VolumeDown'],
1356 [0xaf, 'VolumeUp'],
1357]);
1358
1359/**
1360 * @param {number} keyCode
1361 * @return {string}
1362 */
1363function keyCodeToKeyIdentifier(keyCode) {
1364 let result = staticKeyIdentifiers.get(keyCode);
1365 if (result !== undefined) {
1366 return result;
1367 }
1368 result = 'U+';
1369 const hexString = keyCode.toString(16).toUpperCase();
1370 for (let i = hexString.length; i < 4; ++i) {
1371 result += '0';
1372 }
1373 result += hexString;
1374 return result;
1375}
1376
1377function installBackwardsCompatibility() {
1378 const majorVersion = getRemoteMajorVersion();
1379 if (!majorVersion) {
1380 return;
1381 }
1382
1383 /** @type {!Array<string>} */
1384 const styleRules = [];
1385 // Shadow DOM V0 polyfill
1386 if (majorVersion <= 73 && !Element.prototype.createShadowRoot) {
1387 Element.prototype.createShadowRoot = function() {
1388 try {
1389 return this.attachShadow({mode: 'open'});
1390 } catch (e) {
1391 // some elements we use to add shadow roots can no
1392 // longer have shadow roots.
1393 const fakeShadowHost = document.createElement('span');
1394 this.appendChild(fakeShadowHost);
1395 fakeShadowHost.className = 'fake-shadow-host';
1396 return fakeShadowHost.createShadowRoot();
Tim van der Lippe1d6e57a2019-09-30 11:55:341397 }
Nikolay Vitkov42be2662023-01-12 15:32:351398 };
1399
1400 const origAdd = DOMTokenList.prototype.add;
1401 DOMTokenList.prototype.add = function(...tokens) {
1402 if (tokens[0].startsWith('insertion-point') || tokens[0].startsWith('tabbed-pane-header')) {
1403 this._myElement.slot = '.' + tokens[0];
1404 }
1405 return origAdd.apply(this, tokens);
1406 };
1407
1408 const origCreateElement = Document.prototype.createElement;
1409 Document.prototype.createElement = function(tagName, ...rest) {
1410 if (tagName === 'content') {
1411 tagName = 'slot';
1412 }
1413 const element = origCreateElement.call(this, tagName, ...rest);
1414 element.classList._myElement = element;
1415 return element;
1416 };
1417
1418 Object.defineProperty(HTMLSlotElement.prototype, 'select', {
1419 set(selector) {
1420 this.name = selector;
1421 }
1422 });
Joel Einbinderf55cc942018-10-30 01:59:531423 }
1424
Nikolay Vitkov42be2662023-01-12 15:32:351425 // Custom Elements V0 polyfill
1426 if (majorVersion <= 73 && !Document.prototype.hasOwnProperty('registerElement')) {
1427 const fakeRegistry = new Map();
1428 Document.prototype.registerElement = function(typeExtension, options) {
1429 const {prototype, extends: localName} = options;
1430 const document = this;
1431 const callback = function() {
1432 const element = document.createElement(localName || typeExtension);
1433 const skip = new Set(['constructor', '__proto__']);
1434 for (const key of Object.keys(Object.getOwnPropertyDescriptors(prototype.__proto__ || {}))) {
1435 if (skip.has(key)) {
1436 continue;
1437 }
1438 element[key] = prototype[key];
1439 }
1440 element.setAttribute('is', typeExtension);
1441 if (element['createdCallback']) {
1442 element['createdCallback']();
1443 }
1444 return element;
1445 };
1446 fakeRegistry.set(typeExtension, callback);
1447 return callback;
1448 };
Joel Einbinderf55cc942018-10-30 01:59:531449
Nikolay Vitkov42be2662023-01-12 15:32:351450 const origCreateElement = Document.prototype.createElement;
1451 Document.prototype.createElement = function(tagName, fakeCustomElementType) {
1452 const fakeConstructor = fakeRegistry.get(fakeCustomElementType);
1453 if (fakeConstructor) {
1454 return fakeConstructor();
1455 }
1456 return origCreateElement.call(this, tagName, fakeCustomElementType);
1457 };
1458
1459 // DevTools front-ends mistakenly assume that
1460 // classList.toggle('a', undefined) works as
1461 // classList.toggle('a', false) rather than as
1462 // classList.toggle('a');
1463 const originalDOMTokenListToggle = DOMTokenList.prototype.toggle;
1464 DOMTokenList.prototype.toggle = function(token, force) {
1465 if (arguments.length === 1) {
1466 force = !this.contains(token);
1467 }
1468 return originalDOMTokenListToggle.call(this, token, Boolean(force));
Joel Einbinderf55cc942018-10-30 01:59:531469 };
1470 }
1471
Nikolay Vitkov42be2662023-01-12 15:32:351472 if (majorVersion <= 66) {
1473 /** @type {(!function(number, number):Element|undefined)} */
1474 ShadowRoot.prototype.__originalShadowRootElementFromPoint;
1475
1476 if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) {
1477 ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint;
1478 /**
1479 * @param {number} x
1480 * @param {number} y
1481 * @return {Element}
1482 */
1483 ShadowRoot.prototype.elementFromPoint = function(x, y) {
1484 const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments);
1485 if (this.host && originalResult === this.host) {
1486 return null;
1487 }
1488 return originalResult;
1489 };
1490 }
Blink Reformat4c46d092018-04-07 15:32:371491 }
1492
Nikolay Vitkov42be2662023-01-12 15:32:351493 if (majorVersion <= 53) {
1494 Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', {
1495 /**
1496 * @return {string}
1497 * @this {KeyboardEvent}
1498 */
1499 get: function() {
1500 return keyCodeToKeyIdentifier(this.keyCode);
1501 }
1502 });
1503 }
Blink Reformat4c46d092018-04-07 15:32:371504
Nikolay Vitkov42be2662023-01-12 15:32:351505 if (majorVersion <= 50) {
1506 installObjectObserve();
1507 }
1508
1509 if (majorVersion <= 71) {
1510 styleRules.push(
1511 '.coverage-toolbar-container, .animation-timeline-toolbar-container, .computed-properties { flex-basis: auto; }');
1512 }
1513
1514 if (majorVersion <= 50) {
1515 Event.prototype.deepPath = undefined;
1516 }
1517
1518 if (majorVersion <= 54) {
1519 window.FileError = /** @type {!function (new: FileError) : ?} */ ({
1520 NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR,
1521 ABORT_ERR: DOMException.ABORT_ERR,
1522 INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR,
1523 NOT_READABLE_ERR: 0 // No matching DOMException, so code will be 0.
1524 });
1525 }
1526
1527 installExtraStyleRules(styleRules);
1528}
1529
1530/**
1531 * @return {?number}
1532 */
1533function getRemoteMajorVersion() {
1534 try {
1535 const remoteVersion = new URLSearchParams(window.location.search).get('remoteVersion');
1536 if (!remoteVersion) {
1537 return null;
1538 }
1539 const majorVersion = parseInt(remoteVersion.split('.')[0], 10);
1540 return majorVersion;
1541 } catch (e) {
1542 return null;
1543 }
1544}
1545
1546/**
1547 * @param {!Array<string>} styleRules
1548 */
1549function installExtraStyleRules(styleRules) {
1550 if (!styleRules.length) {
1551 return;
1552 }
1553 const styleText = styleRules.join('\n');
1554 document.head.appendChild(createStyleElement(styleText));
1555
1556 const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
1557 HTMLElement.prototype.createShadowRoot = function(...args) {
1558 const shadowRoot = origCreateShadowRoot.call(this, ...args);
1559 shadowRoot.appendChild(createStyleElement(styleText));
1560 return shadowRoot;
1561 };
1562}
1563
1564/**
1565 * @param {string} styleText
1566 * @return {!Element}
1567 */
1568function createStyleElement(styleText) {
1569 const style = document.createElement('style');
1570 style.textContent = styleText;
1571 return style;
1572}
1573
1574installBackwardsCompatibility();
Blink Reformat4c46d092018-04-07 15:32:371575})(window);