blob: 2e99d57cda846ac2a6f9e8a029d685a7fde0258d [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
7 // DevToolsAPI ----------------------------------------------------------------
8
Blink Reformat4c46d092018-04-07 15:32:379 const DevToolsAPIImpl = class {
10 constructor() {
11 /**
12 * @type {number}
13 */
14 this._lastCallId = 0;
15
16 /**
17 * @type {!Object.<number, function(?Object)>}
18 */
19 this._callbacks = {};
Jeff Fisherac799a52019-06-25 21:47:0620
21 /**
22 * @type {!Array.<!ExtensionDescriptor>}
23 */
24 this._pendingExtensionDescriptors = [];
25
26 /**
27 * @type {?function(!ExtensionDescriptor)}
28 */
29 this._addExtensionCallback = null;
Blink Reformat4c46d092018-04-07 15:32:3730 }
31
32 /**
33 * @param {number} id
34 * @param {?Object} arg
35 */
36 embedderMessageAck(id, arg) {
37 const callback = this._callbacks[id];
38 delete this._callbacks[id];
Tim van der Lippe1d6e57a2019-09-30 11:55:3439 if (callback) {
Blink Reformat4c46d092018-04-07 15:32:3740 callback(arg);
Tim van der Lippe1d6e57a2019-09-30 11:55:3441 }
Blink Reformat4c46d092018-04-07 15:32:3742 }
43
44 /**
45 * @param {string} method
46 * @param {!Array.<*>} args
47 * @param {?function(?Object)} callback
48 */
49 sendMessageToEmbedder(method, args, callback) {
50 const callId = ++this._lastCallId;
Tim van der Lippe1d6e57a2019-09-30 11:55:3451 if (callback) {
Blink Reformat4c46d092018-04-07 15:32:3752 this._callbacks[callId] = callback;
Tim van der Lippe1d6e57a2019-09-30 11:55:3453 }
Blink Reformat4c46d092018-04-07 15:32:3754 const message = {'id': callId, 'method': method};
Tim van der Lippe1d6e57a2019-09-30 11:55:3455 if (args.length) {
Blink Reformat4c46d092018-04-07 15:32:3756 message.params = args;
Tim van der Lippe1d6e57a2019-09-30 11:55:3457 }
Blink Reformat4c46d092018-04-07 15:32:3758 DevToolsHost.sendMessageToEmbedder(JSON.stringify(message));
59 }
60
61 /**
62 * @param {string} method
63 * @param {!Array<*>} args
64 */
65 _dispatchOnInspectorFrontendAPI(method, args) {
66 const inspectorFrontendAPI = /** @type {!Object<string, function()>} */ (window['InspectorFrontendAPI']);
67 inspectorFrontendAPI[method].apply(inspectorFrontendAPI, args);
68 }
69
70 // API methods below this line --------------------------------------------
71
72 /**
73 * @param {!Array.<!ExtensionDescriptor>} extensions
74 */
75 addExtensions(extensions) {
76 // Support for legacy front-ends (<M41).
77 if (window['WebInspector'] && window['WebInspector']['addExtensions']) {
78 window['WebInspector']['addExtensions'](extensions);
Jeff Fisherac799a52019-06-25 21:47:0679 } else {
Blink Reformat4c46d092018-04-07 15:32:3780 // The addExtensions command is sent as the onload event happens for
Jeff Fisherac799a52019-06-25 21:47:0681 // DevTools front-end. We should buffer this command until the frontend
82 // is ready for it.
Tim van der Lippe1d6e57a2019-09-30 11:55:3483 if (this._addExtensionCallback) {
Jeff Fisherac799a52019-06-25 21:47:0684 extensions.forEach(this._addExtensionCallback);
Tim van der Lippe1d6e57a2019-09-30 11:55:3485 } else {
Simon Zünd1facecf2020-01-16 08:08:3586 this._pendingExtensionDescriptors.push(...extensions);
Tim van der Lippe1d6e57a2019-09-30 11:55:3487 }
Blink Reformat4c46d092018-04-07 15:32:3788 }
89 }
90
91 /**
92 * @param {string} url
93 */
94 appendedToURL(url) {
95 this._dispatchOnInspectorFrontendAPI('appendedToURL', [url]);
96 }
97
98 /**
99 * @param {string} url
100 */
101 canceledSaveURL(url) {
102 this._dispatchOnInspectorFrontendAPI('canceledSaveURL', [url]);
103 }
104
105 contextMenuCleared() {
106 this._dispatchOnInspectorFrontendAPI('contextMenuCleared', []);
107 }
108
109 /**
110 * @param {string} id
111 */
112 contextMenuItemSelected(id) {
113 this._dispatchOnInspectorFrontendAPI('contextMenuItemSelected', [id]);
114 }
115
116 /**
117 * @param {number} count
118 */
119 deviceCountUpdated(count) {
120 this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
121 }
122
123 /**
124 * @param {!Adb.Config} config
125 */
126 devicesDiscoveryConfigChanged(config) {
127 this._dispatchOnInspectorFrontendAPI('devicesDiscoveryConfigChanged', [config]);
128 }
129
130 /**
131 * @param {!Adb.PortForwardingStatus} status
132 */
133 devicesPortForwardingStatusChanged(status) {
134 this._dispatchOnInspectorFrontendAPI('devicesPortForwardingStatusChanged', [status]);
135 }
136
137 /**
138 * @param {!Array.<!Adb.Device>} devices
139 */
140 devicesUpdated(devices) {
141 this._dispatchOnInspectorFrontendAPI('devicesUpdated', [devices]);
142 }
143
144 /**
145 * @param {string} message
146 */
147 dispatchMessage(message) {
148 this._dispatchOnInspectorFrontendAPI('dispatchMessage', [message]);
149 }
150
151 /**
152 * @param {string} messageChunk
153 * @param {number} messageSize
154 */
155 dispatchMessageChunk(messageChunk, messageSize) {
156 this._dispatchOnInspectorFrontendAPI('dispatchMessageChunk', [messageChunk, messageSize]);
157 }
158
159 enterInspectElementMode() {
160 this._dispatchOnInspectorFrontendAPI('enterInspectElementMode', []);
161 }
162
163 /**
164 * @param {!{r: number, g: number, b: number, a: number}} color
165 */
166 eyeDropperPickedColor(color) {
167 this._dispatchOnInspectorFrontendAPI('eyeDropperPickedColor', [color]);
168 }
169
170 /**
171 * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems
172 */
173 fileSystemsLoaded(fileSystems) {
174 this._dispatchOnInspectorFrontendAPI('fileSystemsLoaded', [fileSystems]);
175 }
176
177 /**
178 * @param {string} fileSystemPath
179 */
180 fileSystemRemoved(fileSystemPath) {
181 this._dispatchOnInspectorFrontendAPI('fileSystemRemoved', [fileSystemPath]);
182 }
183
184 /**
185 * @param {?string} error
186 * @param {?{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem
187 */
188 fileSystemAdded(error, fileSystem) {
189 this._dispatchOnInspectorFrontendAPI('fileSystemAdded', [error, fileSystem]);
190 }
191
192 /**
193 * @param {!Array<string>} changedPaths
194 * @param {!Array<string>} addedPaths
195 * @param {!Array<string>} removedPaths
196 */
197 fileSystemFilesChangedAddedRemoved(changedPaths, addedPaths, removedPaths) {
198 // Support for legacy front-ends (<M58)
199 if (window['InspectorFrontendAPI'] && window['InspectorFrontendAPI']['fileSystemFilesChanged']) {
200 this._dispatchOnInspectorFrontendAPI(
201 'fileSystemFilesChanged', [changedPaths.concat(addedPaths).concat(removedPaths)]);
202 } else {
203 this._dispatchOnInspectorFrontendAPI(
204 'fileSystemFilesChangedAddedRemoved', [changedPaths, addedPaths, removedPaths]);
205 }
206 }
207
208 /**
209 * @param {number} requestId
210 * @param {string} fileSystemPath
211 * @param {number} totalWork
212 */
213 indexingTotalWorkCalculated(requestId, fileSystemPath, totalWork) {
214 this._dispatchOnInspectorFrontendAPI('indexingTotalWorkCalculated', [requestId, fileSystemPath, totalWork]);
215 }
216
217 /**
218 * @param {number} requestId
219 * @param {string} fileSystemPath
220 * @param {number} worked
221 */
222 indexingWorked(requestId, fileSystemPath, worked) {
223 this._dispatchOnInspectorFrontendAPI('indexingWorked', [requestId, fileSystemPath, worked]);
224 }
225
226 /**
227 * @param {number} requestId
228 * @param {string} fileSystemPath
229 */
230 indexingDone(requestId, fileSystemPath) {
231 this._dispatchOnInspectorFrontendAPI('indexingDone', [requestId, fileSystemPath]);
232 }
233
234 /**
235 * @param {{type: string, key: string, code: string, keyCode: number, modifiers: number}} event
236 */
237 keyEventUnhandled(event) {
238 event.keyIdentifier = keyCodeToKeyIdentifier(event.keyCode);
239 this._dispatchOnInspectorFrontendAPI('keyEventUnhandled', [event]);
240 }
241
242 /**
Jeff Fisherac799a52019-06-25 21:47:06243 * @param {function(!ExtensionDescriptor)} callback
244 */
245 setAddExtensionCallback(callback) {
246 this._addExtensionCallback = callback;
247 if (this._pendingExtensionDescriptors.length) {
248 this._pendingExtensionDescriptors.forEach(this._addExtensionCallback);
249 this._pendingExtensionDescriptors = [];
250 }
251 }
252
Adithya Srinivasan7a133d22019-10-09 00:27:48253 reattachMainTarget() {
254 this._dispatchOnInspectorFrontendAPI('reattachMainTarget', []);
255 }
256
Jeff Fisherac799a52019-06-25 21:47:06257 /**
Blink Reformat4c46d092018-04-07 15:32:37258 * @param {boolean} hard
259 */
260 reloadInspectedPage(hard) {
261 this._dispatchOnInspectorFrontendAPI('reloadInspectedPage', [hard]);
262 }
263
264 /**
265 * @param {string} url
266 * @param {number} lineNumber
267 * @param {number} columnNumber
268 */
269 revealSourceLine(url, lineNumber, columnNumber) {
270 this._dispatchOnInspectorFrontendAPI('revealSourceLine', [url, lineNumber, columnNumber]);
271 }
272
273 /**
274 * @param {string} url
275 * @param {string=} fileSystemPath
276 */
277 savedURL(url, fileSystemPath) {
278 this._dispatchOnInspectorFrontendAPI('savedURL', [url, fileSystemPath]);
279 }
280
281 /**
282 * @param {number} requestId
283 * @param {string} fileSystemPath
284 * @param {!Array.<string>} files
285 */
286 searchCompleted(requestId, fileSystemPath, files) {
287 this._dispatchOnInspectorFrontendAPI('searchCompleted', [requestId, fileSystemPath, files]);
288 }
289
290 /**
291 * @param {string} tabId
292 */
293 setInspectedTabId(tabId) {
Tim van der Lippe647e33b2019-11-04 19:02:31294 this._inspectedTabIdValue = tabId;
295
Blink Reformat4c46d092018-04-07 15:32:37296 // Support for legacy front-ends (<M41).
Tim van der Lippe1d6e57a2019-09-30 11:55:34297 if (window['WebInspector'] && window['WebInspector']['setInspectedTabId']) {
Blink Reformat4c46d092018-04-07 15:32:37298 window['WebInspector']['setInspectedTabId'](tabId);
Tim van der Lippe1d6e57a2019-09-30 11:55:34299 } else {
Blink Reformat4c46d092018-04-07 15:32:37300 this._dispatchOnInspectorFrontendAPI('setInspectedTabId', [tabId]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34301 }
Blink Reformat4c46d092018-04-07 15:32:37302 }
303
304 /**
Tim van der Lippe647e33b2019-11-04 19:02:31305 * @return {string|undefined}
306 */
307 getInspectedTabId() {
308 return this._inspectedTabIdValue;
309 }
310
311 /**
Blink Reformat4c46d092018-04-07 15:32:37312 * @param {boolean} useSoftMenu
313 */
314 setUseSoftMenu(useSoftMenu) {
315 this._dispatchOnInspectorFrontendAPI('setUseSoftMenu', [useSoftMenu]);
316 }
317
318 /**
319 * @param {string} panelName
320 */
321 showPanel(panelName) {
322 this._dispatchOnInspectorFrontendAPI('showPanel', [panelName]);
323 }
324
325 /**
326 * @param {number} id
327 * @param {string} chunk
328 * @param {boolean} encoded
329 */
330 streamWrite(id, chunk, encoded) {
331 this._dispatchOnInspectorFrontendAPI('streamWrite', [id, encoded ? this._decodeBase64(chunk) : chunk]);
332 }
333
334 /**
335 * @param {string} chunk
336 * @return {string}
337 */
338 _decodeBase64(chunk) {
339 const request = new XMLHttpRequest();
340 request.open('GET', 'data:text/plain;base64,' + chunk, false);
341 request.send(null);
342 if (request.status === 200) {
343 return request.responseText;
Blink Reformat4c46d092018-04-07 15:32:37344 }
Mathias Bynensf06e8c02020-02-28 13:58:28345 console.error('Error while decoding chunk in streamWrite');
346 return '';
Blink Reformat4c46d092018-04-07 15:32:37347 }
348 };
349
350 const DevToolsAPI = new DevToolsAPIImpl();
351 window.DevToolsAPI = DevToolsAPI;
352
353 // InspectorFrontendHostImpl --------------------------------------------------
354
355 /**
Sigurd Schneiderf8d81c42020-07-02 07:32:58356 * Enum for recordPerformanceHistogram
Changhao Han45d84732020-11-27 11:04:08357 * Warning: There is another definition of this enum in the DevTools code
Changhao Han03c48382020-09-14 21:17:50358 * base, keep them in sync:
Changhao Han03c48382020-09-14 21:17:50359 * front_end/host/InspectorFrontendHostAPI.js
Sigurd Schneiderf8d81c42020-07-02 07:32:58360 * @readonly
361 * @enum {string}
362 */
363 const EnumeratedHistogram = {
364 ActionTaken: 'DevTools.ActionTaken',
Alex Rudenko3de657a2020-08-20 07:52:19365 ColorPickerFixedColor: 'DevTools.ColorPicker.FixedColor',
Jose Leal Chapa1e1d9582020-07-30 18:39:25366 PanelClosed: 'DevTools.PanelClosed',
Sigurd Schneiderf8d81c42020-07-02 07:32:58367 PanelShown: 'DevTools.PanelShown',
Changhao Hanf51d0792020-08-26 11:30:15368 SidebarPaneShown: 'DevTools.SidebarPaneShown',
Sigurd Schneiderf8d81c42020-07-02 07:32:58369 KeyboardShortcutFired: 'DevTools.KeyboardShortcutFired',
Wolfgang Beyera175e1f2020-12-14 09:41:54370 IssueCreated: 'DevTools.IssueCreated',
Jesus David Garcia Gomez0c37bf02020-09-10 16:10:19371 IssuesPanelIssueExpanded: 'DevTools.IssuesPanelIssueExpanded',
Sigurd Schneiderf8d81c42020-07-02 07:32:58372 IssuesPanelOpenedFrom: 'DevTools.IssuesPanelOpenedFrom',
Jesus David Garcia Gomez0c37bf02020-09-10 16:10:19373 IssuesPanelResourceOpened: 'DevTools.IssuesPanelResourceOpened',
Sigurd Schneiderf8d81c42020-07-02 07:32:58374 KeybindSetSettingChanged: 'DevTools.KeybindSetSettingChanged',
375 DualScreenDeviceEmulated: 'DevTools.DualScreenDeviceEmulated',
Brandon Goddard413d1722020-08-10 17:51:26376 ExperimentEnabledAtLaunch: 'DevTools.ExperimentEnabledAtLaunch',
377 ExperimentEnabled: 'DevTools.ExperimentEnabled',
378 ExperimentDisabled: 'DevTools.ExperimentDisabled',
Michael Liao07a11ed2020-12-07 23:52:37379 CssEditorOpened: 'DevTools.CssEditorOpened',
Sigurd Schneider8d627692021-01-12 12:25:31380 DeveloperResourceLoaded: 'DevTools.DeveloperResourceLoaded',
Sigurd Schneidera7099742021-01-20 08:22:36381 DeveloperResourceScheme: 'DevTools.DeveloperResourceScheme',
Benedikt Meurer55398c02021-03-02 08:15:15382 LinearMemoryInspectorRevealedFrom: 'DevTools.LinearMemoryInspector.RevealedFrom',
383 LinearMemoryInspectorTarget: 'DevTools.LinearMemoryInspector.Target',
Sigurd Schneiderf8d81c42020-07-02 07:32:58384 };
385
386 /**
Blink Reformat4c46d092018-04-07 15:32:37387 * @implements {InspectorFrontendHostAPI}
Blink Reformat4c46d092018-04-07 15:32:37388 */
389 const InspectorFrontendHostImpl = class {
390 /**
Blink Reformat4c46d092018-04-07 15:32:37391 * @return {string}
392 */
393 getSelectionBackgroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02394 return '#6e86ff';
Blink Reformat4c46d092018-04-07 15:32:37395 }
396
397 /**
Blink Reformat4c46d092018-04-07 15:32:37398 * @return {string}
399 */
400 getSelectionForegroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02401 return '#ffffff';
Blink Reformat4c46d092018-04-07 15:32:37402 }
403
404 /**
Blink Reformat4c46d092018-04-07 15:32:37405 * @return {string}
406 */
407 getInactiveSelectionBackgroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02408 return '#c9c8c8';
Blink Reformat4c46d092018-04-07 15:32:37409 }
410
411 /**
Blink Reformat4c46d092018-04-07 15:32:37412 * @return {string}
413 */
414 getInactiveSelectionForegroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02415 return '#323232';
Blink Reformat4c46d092018-04-07 15:32:37416 }
417
418 /**
419 * @override
420 * @return {string}
421 */
422 platform() {
423 return DevToolsHost.platform();
424 }
425
426 /**
427 * @override
428 */
429 loadCompleted() {
430 DevToolsAPI.sendMessageToEmbedder('loadCompleted', [], null);
431 // Support for legacy (<57) frontends.
432 if (window.Runtime && window.Runtime.queryParam) {
433 const panelToOpen = window.Runtime.queryParam('panel');
Tim van der Lippe1d6e57a2019-09-30 11:55:34434 if (panelToOpen) {
Blink Reformat4c46d092018-04-07 15:32:37435 window.DevToolsAPI.showPanel(panelToOpen);
Tim van der Lippe1d6e57a2019-09-30 11:55:34436 }
Blink Reformat4c46d092018-04-07 15:32:37437 }
438 }
439
440 /**
441 * @override
442 */
443 bringToFront() {
444 DevToolsAPI.sendMessageToEmbedder('bringToFront', [], null);
445 }
446
447 /**
448 * @override
449 */
450 closeWindow() {
451 DevToolsAPI.sendMessageToEmbedder('closeWindow', [], null);
452 }
453
454 /**
455 * @override
456 * @param {boolean} isDocked
457 * @param {function()} callback
458 */
459 setIsDocked(isDocked, callback) {
460 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [isDocked], callback);
461 }
462
463 /**
Peter Marshall355af6a2020-10-30 14:00:40464 * @override
465 * @param {string} trigger
466 * @param {function(!InspectorFrontendHostAPI.ShowSurveyResult): void} callback
467 */
468 showSurvey(trigger, callback) {
469 DevToolsAPI.sendMessageToEmbedder('showSurvey', [trigger], /** @type {function(?Object)} */ (callback));
470 }
471
472 /**
473 * @override
474 * @param {string} trigger
475 * @param {function(!InspectorFrontendHostAPI.CanShowSurveyResult): void} callback
476 */
477 canShowSurvey(trigger, callback) {
478 DevToolsAPI.sendMessageToEmbedder('canShowSurvey', [trigger], /** @type {function(?Object)} */ (callback));
479 }
480
481 /**
Blink Reformat4c46d092018-04-07 15:32:37482 * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
483 * @override
484 * @param {{x: number, y: number, width: number, height: number}} bounds
485 */
486 setInspectedPageBounds(bounds) {
487 DevToolsAPI.sendMessageToEmbedder('setInspectedPageBounds', [bounds], null);
488 }
489
490 /**
491 * @override
492 */
493 inspectElementCompleted() {
494 DevToolsAPI.sendMessageToEmbedder('inspectElementCompleted', [], null);
495 }
496
497 /**
498 * @override
499 * @param {string} url
500 * @param {string} headers
501 * @param {number} streamId
Peter Marshall355af6a2020-10-30 14:00:40502 * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult): void} callback
Blink Reformat4c46d092018-04-07 15:32:37503 */
504 loadNetworkResource(url, headers, streamId, callback) {
505 DevToolsAPI.sendMessageToEmbedder(
506 'loadNetworkResource', [url, headers, streamId], /** @type {function(?Object)} */ (callback));
507 }
508
509 /**
510 * @override
511 * @param {function(!Object<string, string>)} callback
512 */
513 getPreferences(callback) {
514 DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback));
515 }
516
517 /**
518 * @override
519 * @param {string} name
520 * @param {string} value
521 */
522 setPreference(name, value) {
523 DevToolsAPI.sendMessageToEmbedder('setPreference', [name, value], null);
524 }
525
526 /**
527 * @override
528 * @param {string} name
529 */
530 removePreference(name) {
531 DevToolsAPI.sendMessageToEmbedder('removePreference', [name], null);
532 }
533
534 /**
535 * @override
536 */
537 clearPreferences() {
538 DevToolsAPI.sendMessageToEmbedder('clearPreferences', [], null);
539 }
540
541 /**
542 * @override
543 * @param {string} origin
544 * @param {string} script
545 */
546 setInjectedScriptForOrigin(origin, script) {
547 DevToolsAPI.sendMessageToEmbedder('registerExtensionsAPI', [origin, script], null);
548 }
549
550 /**
551 * @override
552 * @param {string} url
553 */
554 inspectedURLChanged(url) {
555 DevToolsAPI.sendMessageToEmbedder('inspectedURLChanged', [url], null);
556 }
557
558 /**
559 * @override
560 * @param {string} text
561 */
562 copyText(text) {
563 DevToolsHost.copyText(text);
564 }
565
566 /**
567 * @override
568 * @param {string} url
569 */
570 openInNewTab(url) {
571 DevToolsAPI.sendMessageToEmbedder('openInNewTab', [url], null);
572 }
573
574 /**
575 * @override
576 * @param {string} fileSystemPath
577 */
578 showItemInFolder(fileSystemPath) {
579 DevToolsAPI.sendMessageToEmbedder('showItemInFolder', [fileSystemPath], null);
580 }
581
582 /**
583 * @override
584 * @param {string} url
585 * @param {string} content
586 * @param {boolean} forceSaveAs
587 */
588 save(url, content, forceSaveAs) {
589 DevToolsAPI.sendMessageToEmbedder('save', [url, content, forceSaveAs], null);
590 }
591
592 /**
593 * @override
594 * @param {string} url
595 * @param {string} content
596 */
597 append(url, content) {
598 DevToolsAPI.sendMessageToEmbedder('append', [url, content], null);
599 }
600
601 /**
602 * @override
Pavel Feldmanf1a36ee2018-07-28 16:10:25603 * @param {string} url
604 */
605 close(url) {
606 }
607
608 /**
609 * @override
Blink Reformat4c46d092018-04-07 15:32:37610 * @param {string} message
611 */
612 sendMessageToBackend(message) {
613 DevToolsAPI.sendMessageToEmbedder('dispatchProtocolMessage', [message], null);
614 }
615
616 /**
617 * @override
Sigurd Schneiderf8d81c42020-07-02 07:32:58618 * @param {!InspectorFrontendHostAPI.EnumeratedHistogram} actionName
Blink Reformat4c46d092018-04-07 15:32:37619 * @param {number} actionCode
620 * @param {number} bucketSize
621 */
622 recordEnumeratedHistogram(actionName, actionCode, bucketSize) {
Sigurd Schneiderf8d81c42020-07-02 07:32:58623 if (!Object.values(EnumeratedHistogram).includes(actionName)) {
Blink Reformat4c46d092018-04-07 15:32:37624 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34625 }
Blink Reformat4c46d092018-04-07 15:32:37626 DevToolsAPI.sendMessageToEmbedder('recordEnumeratedHistogram', [actionName, actionCode, bucketSize], null);
627 }
628
629 /**
630 * @override
James Lissiakd2f1a2f2019-03-26 17:36:51631 * @param {string} histogramName
632 * @param {number} duration
633 */
634 recordPerformanceHistogram(histogramName, duration) {
635 DevToolsAPI.sendMessageToEmbedder('recordPerformanceHistogram', [histogramName, duration], null);
636 }
637
638 /**
639 * @override
James Lissiake21c97b2019-04-29 17:36:43640 * @param {string} umaName
641 */
642 recordUserMetricsAction(umaName) {
643 DevToolsAPI.sendMessageToEmbedder('recordUserMetricsAction', [umaName], null);
644 }
645
646 /**
647 * @override
Blink Reformat4c46d092018-04-07 15:32:37648 */
649 requestFileSystems() {
650 DevToolsAPI.sendMessageToEmbedder('requestFileSystems', [], null);
651 }
652
653 /**
654 * @override
655 * @param {string=} type
656 */
657 addFileSystem(type) {
658 DevToolsAPI.sendMessageToEmbedder('addFileSystem', [type || ''], null);
659 }
660
661 /**
662 * @override
663 * @param {string} fileSystemPath
664 */
665 removeFileSystem(fileSystemPath) {
666 DevToolsAPI.sendMessageToEmbedder('removeFileSystem', [fileSystemPath], null);
667 }
668
669 /**
670 * @override
671 * @param {string} fileSystemId
672 * @param {string} registeredName
Tim van der Lipped71c22d2020-03-19 12:29:19673 * @return {?FileSystem}
Blink Reformat4c46d092018-04-07 15:32:37674 */
675 isolatedFileSystem(fileSystemId, registeredName) {
676 return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName);
677 }
678
679 /**
680 * @override
681 * @param {!FileSystem} fileSystem
682 */
683 upgradeDraggedFileSystemPermissions(fileSystem) {
684 DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem);
685 }
686
687 /**
688 * @override
689 * @param {number} requestId
690 * @param {string} fileSystemPath
691 * @param {string} excludedFolders
692 */
693 indexPath(requestId, fileSystemPath, excludedFolders) {
694 // |excludedFolders| added in M67. For backward compatibility,
695 // pass empty array.
696 excludedFolders = excludedFolders || '[]';
697 DevToolsAPI.sendMessageToEmbedder('indexPath', [requestId, fileSystemPath, excludedFolders], null);
698 }
699
700 /**
701 * @override
702 * @param {number} requestId
703 */
704 stopIndexing(requestId) {
705 DevToolsAPI.sendMessageToEmbedder('stopIndexing', [requestId], null);
706 }
707
708 /**
709 * @override
710 * @param {number} requestId
711 * @param {string} fileSystemPath
712 * @param {string} query
713 */
714 searchInPath(requestId, fileSystemPath, query) {
715 DevToolsAPI.sendMessageToEmbedder('searchInPath', [requestId, fileSystemPath, query], null);
716 }
717
718 /**
719 * @override
720 * @return {number}
721 */
722 zoomFactor() {
723 return DevToolsHost.zoomFactor();
724 }
725
726 /**
727 * @override
728 */
729 zoomIn() {
730 DevToolsAPI.sendMessageToEmbedder('zoomIn', [], null);
731 }
732
733 /**
734 * @override
735 */
736 zoomOut() {
737 DevToolsAPI.sendMessageToEmbedder('zoomOut', [], null);
738 }
739
740 /**
741 * @override
742 */
743 resetZoom() {
744 DevToolsAPI.sendMessageToEmbedder('resetZoom', [], null);
745 }
746
747 /**
748 * @override
749 * @param {string} shortcuts
750 */
751 setWhitelistedShortcuts(shortcuts) {
752 DevToolsAPI.sendMessageToEmbedder('setWhitelistedShortcuts', [shortcuts], null);
753 }
754
755 /**
756 * @override
757 * @param {boolean} active
758 */
759 setEyeDropperActive(active) {
760 DevToolsAPI.sendMessageToEmbedder('setEyeDropperActive', [active], null);
761 }
762
763 /**
764 * @override
765 * @param {!Array<string>} certChain
766 */
767 showCertificateViewer(certChain) {
768 DevToolsAPI.sendMessageToEmbedder('showCertificateViewer', [JSON.stringify(certChain)], null);
769 }
770
771 /**
Connor Clarkca8905e2019-08-23 18:35:10772 * Only needed to run Lighthouse on old devtools.
Blink Reformat4c46d092018-04-07 15:32:37773 * @override
774 * @param {function()} callback
775 */
776 reattach(callback) {
777 DevToolsAPI.sendMessageToEmbedder('reattach', [], callback);
778 }
779
780 /**
781 * @override
782 */
783 readyForTest() {
784 DevToolsAPI.sendMessageToEmbedder('readyForTest', [], null);
785 }
786
787 /**
788 * @override
789 */
790 connectionReady() {
791 DevToolsAPI.sendMessageToEmbedder('connectionReady', [], null);
792 }
793
794 /**
795 * @override
796 * @param {boolean} value
797 */
798 setOpenNewWindowForPopups(value) {
799 DevToolsAPI.sendMessageToEmbedder('setOpenNewWindowForPopups', [value], null);
800 }
801
802 /**
803 * @override
804 * @param {!Adb.Config} config
805 */
806 setDevicesDiscoveryConfig(config) {
807 DevToolsAPI.sendMessageToEmbedder(
808 'setDevicesDiscoveryConfig',
809 [
810 config.discoverUsbDevices, config.portForwardingEnabled, JSON.stringify(config.portForwardingConfig),
811 config.networkDiscoveryEnabled, JSON.stringify(config.networkDiscoveryConfig)
812 ],
813 null);
814 }
815
816 /**
817 * @override
818 * @param {boolean} enabled
819 */
820 setDevicesUpdatesEnabled(enabled) {
821 DevToolsAPI.sendMessageToEmbedder('setDevicesUpdatesEnabled', [enabled], null);
822 }
823
824 /**
825 * @override
826 * @param {string} pageId
827 * @param {string} action
828 */
829 performActionOnRemotePage(pageId, action) {
830 DevToolsAPI.sendMessageToEmbedder('performActionOnRemotePage', [pageId, action], null);
831 }
832
833 /**
834 * @override
835 * @param {string} browserId
836 * @param {string} url
837 */
838 openRemotePage(browserId, url) {
839 DevToolsAPI.sendMessageToEmbedder('openRemotePage', [browserId, url], null);
840 }
841
842 /**
843 * @override
844 */
845 openNodeFrontend() {
846 DevToolsAPI.sendMessageToEmbedder('openNodeFrontend', [], null);
847 }
848
849 /**
850 * @override
851 * @param {number} x
852 * @param {number} y
853 * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
854 * @param {!Document} document
855 */
856 showContextMenuAtPoint(x, y, items, document) {
857 DevToolsHost.showContextMenuAtPoint(x, y, items, document);
858 }
859
860 /**
861 * @override
862 * @return {boolean}
863 */
864 isHostedMode() {
865 return DevToolsHost.isHostedMode();
866 }
867
Jeff Fisherac799a52019-06-25 21:47:06868 /**
869 * @override
870 * @param {function(!ExtensionDescriptor)} callback
871 */
872 setAddExtensionCallback(callback) {
873 DevToolsAPI.setAddExtensionCallback(callback);
874 }
875
Blink Reformat4c46d092018-04-07 15:32:37876 // Backward-compatible methods below this line --------------------------------------------
877
878 /**
879 * Support for legacy front-ends (<M65).
880 * @return {boolean}
881 */
882 isUnderTest() {
883 return false;
884 }
885
886 /**
887 * Support for legacy front-ends (<M50).
888 * @param {string} message
889 */
890 sendFrontendAPINotification(message) {
891 }
892
893 /**
894 * Support for legacy front-ends (<M41).
895 * @return {string}
896 */
897 port() {
898 return 'unknown';
899 }
900
901 /**
902 * Support for legacy front-ends (<M38).
903 * @param {number} zoomFactor
904 */
905 setZoomFactor(zoomFactor) {
906 }
907
908 /**
909 * Support for legacy front-ends (<M34).
910 */
911 sendMessageToEmbedder() {
912 }
913
914 /**
915 * Support for legacy front-ends (<M34).
916 * @param {string} dockSide
917 */
918 requestSetDockSide(dockSide) {
919 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [dockSide !== 'undocked'], null);
920 }
921
922 /**
923 * Support for legacy front-ends (<M34).
924 * @return {boolean}
925 */
926 supportsFileSystems() {
927 return true;
928 }
929
930 /**
Blink Reformat4c46d092018-04-07 15:32:37931 * Support for legacy front-ends (<M44).
932 * @param {number} actionCode
933 */
934 recordActionTaken(actionCode) {
Sigurd Schneider7c3f3a62020-06-30 13:17:44935 // Do not record actions, as that may crash the DevTools renderer.
Blink Reformat4c46d092018-04-07 15:32:37936 }
937
938 /**
939 * Support for legacy front-ends (<M44).
940 * @param {number} panelCode
941 */
942 recordPanelShown(panelCode) {
Sigurd Schneider7c3f3a62020-06-30 13:17:44943 // Do not record actions, as that may crash the DevTools renderer.
Blink Reformat4c46d092018-04-07 15:32:37944 }
945 };
946
947 window.InspectorFrontendHost = new InspectorFrontendHostImpl();
948
949 // DevToolsApp ---------------------------------------------------------------
950
951 function installObjectObserve() {
952 /** @type {!Array<string>} */
953 const properties = [
954 'advancedSearchConfig',
955 'auditsPanelSplitViewState',
956 'auditsSidebarWidth',
957 'blockedURLs',
958 'breakpoints',
959 'cacheDisabled',
960 'colorFormat',
961 'consoleHistory',
962 'consoleTimestampsEnabled',
963 'cpuProfilerView',
964 'cssSourceMapsEnabled',
965 'currentDockState',
966 'customColorPalette',
967 'customDevicePresets',
968 'customEmulatedDeviceList',
969 'customFormatters',
970 'customUserAgent',
971 'databaseTableViewVisibleColumns',
972 'dataGrid-cookiesTable',
973 'dataGrid-DOMStorageItemsView',
974 'debuggerSidebarHidden',
Blink Reformat4c46d092018-04-07 15:32:37975 'disablePausedStateOverlay',
976 'domBreakpoints',
977 'domWordWrap',
978 'elementsPanelSplitViewState',
979 'elementsSidebarWidth',
980 'emulation.deviceHeight',
981 'emulation.deviceModeValue',
982 'emulation.deviceOrientationOverride',
983 'emulation.deviceScale',
984 'emulation.deviceScaleFactor',
985 'emulation.deviceUA',
986 'emulation.deviceWidth',
Mathias Bynens4e1cc672020-03-25 06:53:18987 'emulation.locationOverride',
Blink Reformat4c46d092018-04-07 15:32:37988 'emulation.showDeviceMode',
989 'emulation.showRulers',
990 'enableAsyncStackTraces',
991 'eventListenerBreakpoints',
992 'fileMappingEntries',
993 'fileSystemMapping',
994 'FileSystemViewSidebarWidth',
995 'fileSystemViewSplitViewState',
996 'filterBar-consoleView',
997 'filterBar-networkPanel',
998 'filterBar-promisePane',
999 'filterBar-timelinePanel',
1000 'frameViewerHideChromeWindow',
1001 'heapSnapshotRetainersViewSize',
1002 'heapSnapshotSplitViewState',
1003 'hideCollectedPromises',
1004 'hideNetworkMessages',
1005 'highlightNodeOnHoverInOverlay',
Blink Reformat4c46d092018-04-07 15:32:371006 'inlineVariableValues',
1007 'Inspector.drawerSplitView',
1008 'Inspector.drawerSplitViewState',
1009 'InspectorView.panelOrder',
1010 'InspectorView.screencastSplitView',
1011 'InspectorView.screencastSplitViewState',
1012 'InspectorView.splitView',
1013 'InspectorView.splitViewState',
1014 'javaScriptDisabled',
1015 'jsSourceMapsEnabled',
1016 'lastActivePanel',
1017 'lastDockState',
1018 'lastSelectedSourcesSidebarPaneTab',
1019 'lastSnippetEvaluationIndex',
1020 'layerDetailsSplitView',
1021 'layerDetailsSplitViewState',
1022 'layersPanelSplitViewState',
1023 'layersShowInternalLayers',
1024 'layersSidebarWidth',
1025 'messageLevelFilters',
1026 'messageURLFilters',
1027 'monitoringXHREnabled',
1028 'navigatorGroupByFolder',
1029 'navigatorHidden',
1030 'networkColorCodeResourceTypes',
1031 'networkConditions',
1032 'networkConditionsCustomProfiles',
1033 'networkHideDataURL',
1034 'networkLogColumnsVisibility',
1035 'networkLogLargeRows',
1036 'networkLogShowOverview',
1037 'networkPanelSplitViewState',
1038 'networkRecordFilmStripSetting',
1039 'networkResourceTypeFilters',
1040 'networkShowPrimaryLoadWaterfall',
1041 'networkSidebarWidth',
1042 'openLinkHandler',
1043 'pauseOnCaughtException',
1044 'pauseOnExceptionEnabled',
1045 'preserveConsoleLog',
1046 'prettyPrintInfobarDisabled',
1047 'previouslyViewedFiles',
1048 'profilesPanelSplitViewState',
1049 'profilesSidebarWidth',
1050 'promiseStatusFilters',
1051 'recordAllocationStacks',
1052 'requestHeaderFilterSetting',
1053 'request-info-formData-category-expanded',
1054 'request-info-general-category-expanded',
1055 'request-info-queryString-category-expanded',
1056 'request-info-requestHeaders-category-expanded',
1057 'request-info-requestPayload-category-expanded',
1058 'request-info-responseHeaders-category-expanded',
1059 'resources',
1060 'resourcesLastSelectedItem',
1061 'resourcesPanelSplitViewState',
1062 'resourcesSidebarWidth',
1063 'resourceViewTab',
1064 'savedURLs',
1065 'screencastEnabled',
1066 'scriptsPanelNavigatorSidebarWidth',
1067 'searchInContentScripts',
1068 'selectedAuditCategories',
1069 'selectedColorPalette',
1070 'selectedProfileType',
1071 'shortcutPanelSwitch',
1072 'showAdvancedHeapSnapshotProperties',
1073 'showEventListenersForAncestors',
1074 'showFrameowkrListeners',
1075 'showHeaSnapshotObjectsHiddenProperties',
1076 'showInheritedComputedStyleProperties',
1077 'showMediaQueryInspector',
1078 'showNativeFunctionsInJSProfile',
1079 'showUAShadowDOM',
1080 'showWhitespacesInEditor',
1081 'sidebarPosition',
1082 'skipContentScripts',
1083 'skipStackFramesPattern',
1084 'sourceMapInfobarDisabled',
1085 'sourcesPanelDebuggerSidebarSplitViewState',
1086 'sourcesPanelNavigatorSplitViewState',
1087 'sourcesPanelSplitSidebarRatio',
1088 'sourcesPanelSplitViewState',
1089 'sourcesSidebarWidth',
1090 'standardEmulatedDeviceList',
1091 'StylesPaneSplitRatio',
1092 'stylesPaneSplitViewState',
1093 'textEditorAutocompletion',
1094 'textEditorAutoDetectIndent',
1095 'textEditorBracketMatching',
1096 'textEditorIndent',
Junyi Xiao89142cf2019-04-11 16:01:381097 'textEditorTabMovesFocus',
Blink Reformat4c46d092018-04-07 15:32:371098 'timelineCaptureFilmStrip',
1099 'timelineCaptureLayersAndPictures',
1100 'timelineCaptureMemory',
1101 'timelineCaptureNetwork',
1102 'timeline-details',
1103 'timelineEnableJSSampling',
1104 'timelineOverviewMode',
1105 'timelinePanelDetailsSplitViewState',
1106 'timelinePanelRecorsSplitViewState',
1107 'timelinePanelTimelineStackSplitViewState',
1108 'timelinePerspective',
1109 'timeline-split',
1110 'timelineTreeGroupBy',
1111 'timeline-view',
1112 'timelineViewMode',
1113 'uiTheme',
1114 'watchExpressions',
1115 'WebInspector.Drawer.lastSelectedView',
1116 'WebInspector.Drawer.showOnLoad',
1117 'workspaceExcludedFolders',
1118 'workspaceFolderExcludePattern',
1119 'workspaceInfobarDisabled',
1120 'workspaceMappingInfobarDisabled',
1121 'xhrBreakpoints'
1122 ];
1123
1124 /**
1125 * @this {!{_storage: Object, _name: string}}
1126 */
1127 function settingRemove() {
1128 this._storage[this._name] = undefined;
1129 }
1130
1131 /**
1132 * @param {!Object} object
1133 * @param {function(!Array<!{name: string}>)} observer
1134 */
1135 function objectObserve(object, observer) {
1136 if (window['WebInspector']) {
1137 const settingPrototype = /** @type {!Object} */ (window['WebInspector']['Setting']['prototype']);
Tim van der Lippe1d6e57a2019-09-30 11:55:341138 if (typeof settingPrototype['remove'] === 'function') {
Blink Reformat4c46d092018-04-07 15:32:371139 settingPrototype['remove'] = settingRemove;
Tim van der Lippe1d6e57a2019-09-30 11:55:341140 }
Blink Reformat4c46d092018-04-07 15:32:371141 }
1142 /** @type {!Set<string>} */
1143 const changedProperties = new Set();
1144 let scheduled = false;
1145
1146 function scheduleObserver() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341147 if (scheduled) {
Blink Reformat4c46d092018-04-07 15:32:371148 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341149 }
Blink Reformat4c46d092018-04-07 15:32:371150 scheduled = true;
Mathias Bynensa0d60452020-11-30 11:45:331151 queueMicrotask(callObserver);
Blink Reformat4c46d092018-04-07 15:32:371152 }
1153
1154 function callObserver() {
1155 scheduled = false;
1156 const changes = /** @type {!Array<!{name: string}>} */ ([]);
1157 changedProperties.forEach(function(name) {
1158 changes.push({name: name});
1159 });
1160 changedProperties.clear();
1161 observer.call(null, changes);
1162 }
1163
1164 /** @type {!Map<string, *>} */
1165 const storage = new Map();
1166
1167 /**
1168 * @param {string} property
1169 */
1170 function defineProperty(property) {
1171 if (property in object) {
1172 storage.set(property, object[property]);
1173 delete object[property];
1174 }
1175
1176 Object.defineProperty(object, property, {
1177 /**
1178 * @return {*}
1179 */
1180 get: function() {
1181 return storage.get(property);
1182 },
1183
1184 /**
1185 * @param {*} value
1186 */
1187 set: function(value) {
1188 storage.set(property, value);
1189 changedProperties.add(property);
1190 scheduleObserver();
1191 }
1192 });
1193 }
1194
Tim van der Lippe1d6e57a2019-09-30 11:55:341195 for (let i = 0; i < properties.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371196 defineProperty(properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341197 }
Blink Reformat4c46d092018-04-07 15:32:371198 }
1199
1200 window.Object.observe = objectObserve;
1201 }
1202
1203 /** @type {!Map<number, string>} */
1204 const staticKeyIdentifiers = new Map([
1205 [0x12, 'Alt'],
1206 [0x11, 'Control'],
1207 [0x10, 'Shift'],
1208 [0x14, 'CapsLock'],
1209 [0x5b, 'Win'],
1210 [0x5c, 'Win'],
1211 [0x0c, 'Clear'],
1212 [0x28, 'Down'],
1213 [0x23, 'End'],
1214 [0x0a, 'Enter'],
1215 [0x0d, 'Enter'],
1216 [0x2b, 'Execute'],
1217 [0x70, 'F1'],
1218 [0x71, 'F2'],
1219 [0x72, 'F3'],
1220 [0x73, 'F4'],
1221 [0x74, 'F5'],
1222 [0x75, 'F6'],
1223 [0x76, 'F7'],
1224 [0x77, 'F8'],
1225 [0x78, 'F9'],
1226 [0x79, 'F10'],
1227 [0x7a, 'F11'],
1228 [0x7b, 'F12'],
1229 [0x7c, 'F13'],
1230 [0x7d, 'F14'],
1231 [0x7e, 'F15'],
1232 [0x7f, 'F16'],
1233 [0x80, 'F17'],
1234 [0x81, 'F18'],
1235 [0x82, 'F19'],
1236 [0x83, 'F20'],
1237 [0x84, 'F21'],
1238 [0x85, 'F22'],
1239 [0x86, 'F23'],
1240 [0x87, 'F24'],
1241 [0x2f, 'Help'],
1242 [0x24, 'Home'],
1243 [0x2d, 'Insert'],
1244 [0x25, 'Left'],
1245 [0x22, 'PageDown'],
1246 [0x21, 'PageUp'],
1247 [0x13, 'Pause'],
1248 [0x2c, 'PrintScreen'],
1249 [0x27, 'Right'],
1250 [0x91, 'Scroll'],
1251 [0x29, 'Select'],
1252 [0x26, 'Up'],
1253 [0x2e, 'U+007F'], // Standard says that DEL becomes U+007F.
1254 [0xb0, 'MediaNextTrack'],
1255 [0xb1, 'MediaPreviousTrack'],
1256 [0xb2, 'MediaStop'],
1257 [0xb3, 'MediaPlayPause'],
1258 [0xad, 'VolumeMute'],
1259 [0xae, 'VolumeDown'],
1260 [0xaf, 'VolumeUp'],
1261 ]);
1262
1263 /**
1264 * @param {number} keyCode
1265 * @return {string}
1266 */
1267 function keyCodeToKeyIdentifier(keyCode) {
1268 let result = staticKeyIdentifiers.get(keyCode);
Tim van der Lippe1d6e57a2019-09-30 11:55:341269 if (result !== undefined) {
Blink Reformat4c46d092018-04-07 15:32:371270 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:341271 }
Blink Reformat4c46d092018-04-07 15:32:371272 result = 'U+';
1273 const hexString = keyCode.toString(16).toUpperCase();
Tim van der Lippe1d6e57a2019-09-30 11:55:341274 for (let i = hexString.length; i < 4; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371275 result += '0';
Tim van der Lippe1d6e57a2019-09-30 11:55:341276 }
Blink Reformat4c46d092018-04-07 15:32:371277 result += hexString;
1278 return result;
1279 }
1280
1281 function installBackwardsCompatibility() {
Joel Einbinderf55cc942018-10-30 01:59:531282 const majorVersion = getRemoteMajorVersion();
Tim van der Lippe1d6e57a2019-09-30 11:55:341283 if (!majorVersion) {
Blink Reformat4c46d092018-04-07 15:32:371284 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341285 }
Blink Reformat4c46d092018-04-07 15:32:371286
Joel Einbinderf55cc942018-10-30 01:59:531287 /** @type {!Array<string>} */
1288 const styleRules = [];
Joel Einbinder82b1d8e2018-12-08 01:01:371289 // Shadow DOM V0 polyfill
1290 if (majorVersion <= 73 && !Element.prototype.createShadowRoot) {
1291 Element.prototype.createShadowRoot = function() {
1292 try {
1293 return this.attachShadow({mode: 'open'});
1294 } catch (e) {
1295 // some elements we use to add shadow roots can no
1296 // longer have shadow roots.
1297 const fakeShadowHost = document.createElement('span');
1298 this.appendChild(fakeShadowHost);
1299 fakeShadowHost.className = 'fake-shadow-host';
1300 return fakeShadowHost.createShadowRoot();
1301 }
1302 };
1303
1304 const origAdd = DOMTokenList.prototype.add;
1305 DOMTokenList.prototype.add = function(...tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341306 if (tokens[0].startsWith('insertion-point') || tokens[0].startsWith('tabbed-pane-header')) {
Joel Einbinder82b1d8e2018-12-08 01:01:371307 this._myElement.slot = '.' + tokens[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:341308 }
Joel Einbinder82b1d8e2018-12-08 01:01:371309 return origAdd.apply(this, tokens);
1310 };
1311
1312 const origCreateElement = Document.prototype.createElement;
1313 Document.prototype.createElement = function(tagName, ...rest) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341314 if (tagName === 'content') {
Joel Einbinder82b1d8e2018-12-08 01:01:371315 tagName = 'slot';
Tim van der Lippe1d6e57a2019-09-30 11:55:341316 }
Joel Einbinder82b1d8e2018-12-08 01:01:371317 const element = origCreateElement.call(this, tagName, ...rest);
1318 element.classList._myElement = element;
1319 return element;
1320 };
1321
1322 Object.defineProperty(HTMLSlotElement.prototype, 'select', {
Paul Lewis90faf092020-09-02 07:50:341323 set(selector) {
Joel Einbinder82b1d8e2018-12-08 01:01:371324 this.name = selector;
1325 }
1326 });
Joel Einbinderb948ebc2018-12-12 02:01:121327
Joel Einbinderb948ebc2018-12-12 02:01:121328 function overrideCreateElementWithClass() {
1329 window.removeEventListener('DOMContentLoaded', overrideCreateElementWithClass);
1330
1331 const origCreateElementWithClass = Document.prototype.createElementWithClass;
1332 Document.prototype.createElementWithClass = function(tagName, className, ...rest) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341333 if (tagName !== 'button' || (className !== 'soft-dropdown' && className !== 'dropdown-button')) {
Joel Einbinderb948ebc2018-12-12 02:01:121334 return origCreateElementWithClass.call(this, tagName, className, ...rest);
Tim van der Lippe1d6e57a2019-09-30 11:55:341335 }
Joel Einbinderb948ebc2018-12-12 02:01:121336 const element = origCreateElementWithClass.call(this, 'div', className, ...rest);
1337 element.tabIndex = 0;
1338 element.role = 'button';
1339 return element;
1340 };
1341 }
Tim van der Lippeffa78622019-09-16 12:07:121342
1343 // Document.prototype.createElementWithClass is a DevTools method, so we
1344 // need to wait for DOMContentLoaded in order to override it.
1345 if (window.document.head &&
Tim van der Lippe1d6e57a2019-09-30 11:55:341346 (window.document.readyState === 'complete' || window.document.readyState === 'interactive')) {
Tim van der Lippeffa78622019-09-16 12:07:121347 overrideCreateElementWithClass();
Tim van der Lippe1d6e57a2019-09-30 11:55:341348 } else {
Tim van der Lippeffa78622019-09-16 12:07:121349 window.addEventListener('DOMContentLoaded', overrideCreateElementWithClass);
Tim van der Lippe1d6e57a2019-09-30 11:55:341350 }
Joel Einbinderb948ebc2018-12-12 02:01:121351 }
1352
1353 // Custom Elements V0 polyfill
Tim van der Lippeffa78622019-09-16 12:07:121354 if (majorVersion <= 73 && !Document.prototype.hasOwnProperty('registerElement')) {
Joel Einbinderb948ebc2018-12-12 02:01:121355 const fakeRegistry = new Map();
1356 Document.prototype.registerElement = function(typeExtension, options) {
1357 const {prototype, extends: localName} = options;
1358 const document = this;
1359 const callback = function() {
1360 const element = document.createElement(localName || typeExtension);
1361 const skip = new Set(['constructor', '__proto__']);
1362 for (const key of Object.keys(Object.getOwnPropertyDescriptors(prototype.__proto__ || {}))) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341363 if (skip.has(key)) {
Joel Einbinderb948ebc2018-12-12 02:01:121364 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341365 }
Joel Einbinderb948ebc2018-12-12 02:01:121366 element[key] = prototype[key];
1367 }
1368 element.setAttribute('is', typeExtension);
Tim van der Lippe1d6e57a2019-09-30 11:55:341369 if (element['createdCallback']) {
Joel Einbinderb948ebc2018-12-12 02:01:121370 element['createdCallback']();
Tim van der Lippe1d6e57a2019-09-30 11:55:341371 }
Joel Einbinderb948ebc2018-12-12 02:01:121372 return element;
1373 };
1374 fakeRegistry.set(typeExtension, callback);
1375 return callback;
1376 };
1377
1378 const origCreateElement = Document.prototype.createElement;
1379 Document.prototype.createElement = function(tagName, fakeCustomElementType) {
1380 const fakeConstructor = fakeRegistry.get(fakeCustomElementType);
Tim van der Lippe1d6e57a2019-09-30 11:55:341381 if (fakeConstructor) {
Joel Einbinderb948ebc2018-12-12 02:01:121382 return fakeConstructor();
Tim van der Lippe1d6e57a2019-09-30 11:55:341383 }
Joel Einbinderb948ebc2018-12-12 02:01:121384 return origCreateElement.call(this, tagName, fakeCustomElementType);
Joel Einbinder82b1d8e2018-12-08 01:01:371385 };
Pavel Feldman876d7182018-12-14 00:11:051386
1387 // DevTools front-ends mistakenly assume that
1388 // classList.toggle('a', undefined) works as
1389 // classList.toggle('a', false) rather than as
1390 // classList.toggle('a');
1391 const originalDOMTokenListToggle = DOMTokenList.prototype.toggle;
1392 DOMTokenList.prototype.toggle = function(token, force) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341393 if (arguments.length === 1) {
Pavel Feldman876d7182018-12-14 00:11:051394 force = !this.contains(token);
Tim van der Lippe1d6e57a2019-09-30 11:55:341395 }
Tim van der Lipped7cfd142021-01-07 12:17:241396 return originalDOMTokenListToggle.call(this, token, Boolean(force));
Pavel Feldman876d7182018-12-14 00:11:051397 };
Joel Einbinder82b1d8e2018-12-08 01:01:371398 }
Blink Reformat4c46d092018-04-07 15:32:371399
Joel Einbinderf55cc942018-10-30 01:59:531400 if (majorVersion <= 66) {
1401 /** @type {(!function(number, number):Element|undefined)} */
1402 ShadowRoot.prototype.__originalShadowRootElementFromPoint;
1403
1404 if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) {
1405 ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint;
1406 /**
1407 * @param {number} x
1408 * @param {number} y
1409 * @return {Element}
1410 */
1411 ShadowRoot.prototype.elementFromPoint = function(x, y) {
1412 const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments);
Tim van der Lippe1d6e57a2019-09-30 11:55:341413 if (this.host && originalResult === this.host) {
Joel Einbinderf55cc942018-10-30 01:59:531414 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341415 }
Joel Einbinderf55cc942018-10-30 01:59:531416 return originalResult;
1417 };
1418 }
Blink Reformat4c46d092018-04-07 15:32:371419 }
1420
Joel Einbinderf55cc942018-10-30 01:59:531421 if (majorVersion <= 53) {
Blink Reformat4c46d092018-04-07 15:32:371422 Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', {
1423 /**
1424 * @return {string}
1425 * @this {KeyboardEvent}
1426 */
1427 get: function() {
1428 return keyCodeToKeyIdentifier(this.keyCode);
1429 }
1430 });
1431 }
1432
Tim van der Lippe1d6e57a2019-09-30 11:55:341433 if (majorVersion <= 50) {
Joel Einbinderf55cc942018-10-30 01:59:531434 installObjectObserve();
Tim van der Lippe1d6e57a2019-09-30 11:55:341435 }
Blink Reformat4c46d092018-04-07 15:32:371436
Joel Einbinderf55cc942018-10-30 01:59:531437 if (majorVersion <= 45) {
1438 /**
1439 * @param {string} property
1440 * @return {!CSSValue|null}
1441 * @this {CSSStyleDeclaration}
1442 */
1443 function getValue(property) {
1444 // Note that |property| comes from another context, so we can't use === here.
1445 // eslint-disable-next-line eqeqeq
1446 if (property == 'padding-left') {
1447 return /** @type {!CSSValue} */ ({
1448 /**
1449 * @return {number}
1450 * @this {!{__paddingLeft: number}}
1451 */
1452 getFloatValue: function() {
1453 return this.__paddingLeft;
1454 },
1455 __paddingLeft: parseFloat(this.paddingLeft)
1456 });
1457 }
1458 throw new Error('getPropertyCSSValue is undefined');
Blink Reformat4c46d092018-04-07 15:32:371459 }
Joel Einbinderf55cc942018-10-30 01:59:531460
1461 window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue;
1462
1463 function CSSPrimitiveValue() {
1464 }
1465 CSSPrimitiveValue.CSS_PX = 5;
1466 window.CSSPrimitiveValue = CSSPrimitiveValue;
Blink Reformat4c46d092018-04-07 15:32:371467 }
1468
Tim van der Lippe1d6e57a2019-09-30 11:55:341469 if (majorVersion <= 45) {
Joel Einbinderf55cc942018-10-30 01:59:531470 styleRules.push('* { min-width: 0; min-height: 0; }');
Tim van der Lippe1d6e57a2019-09-30 11:55:341471 }
Blink Reformat4c46d092018-04-07 15:32:371472
Joel Einbinderf55cc942018-10-30 01:59:531473 if (majorVersion <= 51) {
1474 // Support for quirky border-image behavior (<M51), see:
1475 // https://bugs.chromium.org/p/chromium/issues/detail?id=559258
1476 styleRules.push('.cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }');
1477 styleRules.push(
1478 '.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }');
Blink Reformat4c46d092018-04-07 15:32:371479 }
Christian Biesinger2d1b2e92018-11-06 01:18:251480 if (majorVersion <= 71) {
1481 styleRules.push(
1482 '.coverage-toolbar-container, .animation-timeline-toolbar-container, .computed-properties { flex-basis: auto; }');
1483 }
Blink Reformat4c46d092018-04-07 15:32:371484
Tim van der Lippe1d6e57a2019-09-30 11:55:341485 if (majorVersion <= 50) {
Joel Einbinderf55cc942018-10-30 01:59:531486 Event.prototype.deepPath = undefined;
Tim van der Lippe1d6e57a2019-09-30 11:55:341487 }
Blink Reformat4c46d092018-04-07 15:32:371488
Joel Einbinderf55cc942018-10-30 01:59:531489 if (majorVersion <= 54) {
1490 window.FileError = /** @type {!function (new: FileError) : ?} */ ({
1491 NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR,
1492 ABORT_ERR: DOMException.ABORT_ERR,
1493 INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR,
1494 NOT_READABLE_ERR: 0 // No matching DOMException, so code will be 0.
1495 });
1496 }
Blink Reformat4c46d092018-04-07 15:32:371497
Joel Einbinderf55cc942018-10-30 01:59:531498 installExtraStyleRules(styleRules);
1499 }
Blink Reformat4c46d092018-04-07 15:32:371500
Joel Einbinderf55cc942018-10-30 01:59:531501 /**
1502 * @return {?number}
1503 */
1504 function getRemoteMajorVersion() {
1505 try {
Joel Einbinder09f48742019-02-28 01:34:421506 const remoteVersion = new URLSearchParams(window.location.search).get('remoteVersion');
Tim van der Lippe1d6e57a2019-09-30 11:55:341507 if (!remoteVersion) {
Joel Einbinderf55cc942018-10-30 01:59:531508 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341509 }
Joel Einbinderf55cc942018-10-30 01:59:531510 const majorVersion = parseInt(remoteVersion.split('.')[0], 10);
1511 return majorVersion;
Joel Einbinder31904782018-11-02 20:52:271512 } catch (e) {
Joel Einbinderf55cc942018-10-30 01:59:531513 return null;
1514 }
1515 }
1516
1517 /**
1518 * @param {!Array<string>} styleRules
1519 */
1520 function installExtraStyleRules(styleRules) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341521 if (!styleRules.length) {
Joel Einbinderf55cc942018-10-30 01:59:531522 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341523 }
Joel Einbinderf55cc942018-10-30 01:59:531524 const styleText = styleRules.join('\n');
1525 document.head.appendChild(createStyleElement(styleText));
1526
1527 const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
1528 HTMLElement.prototype.createShadowRoot = function(...args) {
1529 const shadowRoot = origCreateShadowRoot.call(this, ...args);
1530 shadowRoot.appendChild(createStyleElement(styleText));
1531 return shadowRoot;
1532 };
1533 }
1534
1535 /**
1536 * @param {string} styleText
1537 * @return {!Element}
1538 */
1539 function createStyleElement(styleText) {
1540 const style = document.createElement('style');
Joel Einbinderf55cc942018-10-30 01:59:531541 style.textContent = styleText;
1542 return style;
Blink Reformat4c46d092018-04-07 15:32:371543 }
1544
Joel Einbinderb948ebc2018-12-12 02:01:121545 installBackwardsCompatibility();
Blink Reformat4c46d092018-04-07 15:32:371546
Blink Reformat4c46d092018-04-07 15:32:371547})(window);