blob: 7335c20bb2fa9219e64047e661b8edfc594ffc6c [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
9 /**
10 * @unrestricted
11 */
12 const DevToolsAPIImpl = class {
13 constructor() {
14 /**
15 * @type {number}
16 */
17 this._lastCallId = 0;
18
19 /**
20 * @type {!Object.<number, function(?Object)>}
21 */
22 this._callbacks = {};
Jeff Fisherac799a52019-06-25 21:47:0623
24 /**
25 * @type {!Array.<!ExtensionDescriptor>}
26 */
27 this._pendingExtensionDescriptors = [];
28
29 /**
30 * @type {?function(!ExtensionDescriptor)}
31 */
32 this._addExtensionCallback = null;
Blink Reformat4c46d092018-04-07 15:32:3733 }
34
35 /**
36 * @param {number} id
37 * @param {?Object} arg
38 */
39 embedderMessageAck(id, arg) {
40 const callback = this._callbacks[id];
41 delete this._callbacks[id];
Tim van der Lippe1d6e57a2019-09-30 11:55:3442 if (callback) {
Blink Reformat4c46d092018-04-07 15:32:3743 callback(arg);
Tim van der Lippe1d6e57a2019-09-30 11:55:3444 }
Blink Reformat4c46d092018-04-07 15:32:3745 }
46
47 /**
48 * @param {string} method
49 * @param {!Array.<*>} args
50 * @param {?function(?Object)} callback
51 */
52 sendMessageToEmbedder(method, args, callback) {
53 const callId = ++this._lastCallId;
Tim van der Lippe1d6e57a2019-09-30 11:55:3454 if (callback) {
Blink Reformat4c46d092018-04-07 15:32:3755 this._callbacks[callId] = callback;
Tim van der Lippe1d6e57a2019-09-30 11:55:3456 }
Blink Reformat4c46d092018-04-07 15:32:3757 const message = {'id': callId, 'method': method};
Tim van der Lippe1d6e57a2019-09-30 11:55:3458 if (args.length) {
Blink Reformat4c46d092018-04-07 15:32:3759 message.params = args;
Tim van der Lippe1d6e57a2019-09-30 11:55:3460 }
Blink Reformat4c46d092018-04-07 15:32:3761 DevToolsHost.sendMessageToEmbedder(JSON.stringify(message));
62 }
63
64 /**
65 * @param {string} method
66 * @param {!Array<*>} args
67 */
68 _dispatchOnInspectorFrontendAPI(method, args) {
69 const inspectorFrontendAPI = /** @type {!Object<string, function()>} */ (window['InspectorFrontendAPI']);
70 inspectorFrontendAPI[method].apply(inspectorFrontendAPI, args);
71 }
72
73 // API methods below this line --------------------------------------------
74
75 /**
76 * @param {!Array.<!ExtensionDescriptor>} extensions
77 */
78 addExtensions(extensions) {
79 // Support for legacy front-ends (<M41).
80 if (window['WebInspector'] && window['WebInspector']['addExtensions']) {
81 window['WebInspector']['addExtensions'](extensions);
Jeff Fisherac799a52019-06-25 21:47:0682 } else {
Blink Reformat4c46d092018-04-07 15:32:3783 // The addExtensions command is sent as the onload event happens for
Jeff Fisherac799a52019-06-25 21:47:0684 // DevTools front-end. We should buffer this command until the frontend
85 // is ready for it.
Tim van der Lippe1d6e57a2019-09-30 11:55:3486 if (this._addExtensionCallback) {
Jeff Fisherac799a52019-06-25 21:47:0687 extensions.forEach(this._addExtensionCallback);
Tim van der Lippe1d6e57a2019-09-30 11:55:3488 } else {
Jeff Fisherac799a52019-06-25 21:47:0689 this._pendingExtensionDescriptors.pushAll(extensions);
Tim van der Lippe1d6e57a2019-09-30 11:55:3490 }
Blink Reformat4c46d092018-04-07 15:32:3791 }
92 }
93
94 /**
95 * @param {string} url
96 */
97 appendedToURL(url) {
98 this._dispatchOnInspectorFrontendAPI('appendedToURL', [url]);
99 }
100
101 /**
102 * @param {string} url
103 */
104 canceledSaveURL(url) {
105 this._dispatchOnInspectorFrontendAPI('canceledSaveURL', [url]);
106 }
107
108 contextMenuCleared() {
109 this._dispatchOnInspectorFrontendAPI('contextMenuCleared', []);
110 }
111
112 /**
113 * @param {string} id
114 */
115 contextMenuItemSelected(id) {
116 this._dispatchOnInspectorFrontendAPI('contextMenuItemSelected', [id]);
117 }
118
119 /**
120 * @param {number} count
121 */
122 deviceCountUpdated(count) {
123 this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
124 }
125
126 /**
127 * @param {!Adb.Config} config
128 */
129 devicesDiscoveryConfigChanged(config) {
130 this._dispatchOnInspectorFrontendAPI('devicesDiscoveryConfigChanged', [config]);
131 }
132
133 /**
134 * @param {!Adb.PortForwardingStatus} status
135 */
136 devicesPortForwardingStatusChanged(status) {
137 this._dispatchOnInspectorFrontendAPI('devicesPortForwardingStatusChanged', [status]);
138 }
139
140 /**
141 * @param {!Array.<!Adb.Device>} devices
142 */
143 devicesUpdated(devices) {
144 this._dispatchOnInspectorFrontendAPI('devicesUpdated', [devices]);
145 }
146
147 /**
148 * @param {string} message
149 */
150 dispatchMessage(message) {
151 this._dispatchOnInspectorFrontendAPI('dispatchMessage', [message]);
152 }
153
154 /**
155 * @param {string} messageChunk
156 * @param {number} messageSize
157 */
158 dispatchMessageChunk(messageChunk, messageSize) {
159 this._dispatchOnInspectorFrontendAPI('dispatchMessageChunk', [messageChunk, messageSize]);
160 }
161
162 enterInspectElementMode() {
163 this._dispatchOnInspectorFrontendAPI('enterInspectElementMode', []);
164 }
165
166 /**
167 * @param {!{r: number, g: number, b: number, a: number}} color
168 */
169 eyeDropperPickedColor(color) {
170 this._dispatchOnInspectorFrontendAPI('eyeDropperPickedColor', [color]);
171 }
172
173 /**
174 * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems
175 */
176 fileSystemsLoaded(fileSystems) {
177 this._dispatchOnInspectorFrontendAPI('fileSystemsLoaded', [fileSystems]);
178 }
179
180 /**
181 * @param {string} fileSystemPath
182 */
183 fileSystemRemoved(fileSystemPath) {
184 this._dispatchOnInspectorFrontendAPI('fileSystemRemoved', [fileSystemPath]);
185 }
186
187 /**
188 * @param {?string} error
189 * @param {?{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem
190 */
191 fileSystemAdded(error, fileSystem) {
192 this._dispatchOnInspectorFrontendAPI('fileSystemAdded', [error, fileSystem]);
193 }
194
195 /**
196 * @param {!Array<string>} changedPaths
197 * @param {!Array<string>} addedPaths
198 * @param {!Array<string>} removedPaths
199 */
200 fileSystemFilesChangedAddedRemoved(changedPaths, addedPaths, removedPaths) {
201 // Support for legacy front-ends (<M58)
202 if (window['InspectorFrontendAPI'] && window['InspectorFrontendAPI']['fileSystemFilesChanged']) {
203 this._dispatchOnInspectorFrontendAPI(
204 'fileSystemFilesChanged', [changedPaths.concat(addedPaths).concat(removedPaths)]);
205 } else {
206 this._dispatchOnInspectorFrontendAPI(
207 'fileSystemFilesChangedAddedRemoved', [changedPaths, addedPaths, removedPaths]);
208 }
209 }
210
211 /**
212 * @param {number} requestId
213 * @param {string} fileSystemPath
214 * @param {number} totalWork
215 */
216 indexingTotalWorkCalculated(requestId, fileSystemPath, totalWork) {
217 this._dispatchOnInspectorFrontendAPI('indexingTotalWorkCalculated', [requestId, fileSystemPath, totalWork]);
218 }
219
220 /**
221 * @param {number} requestId
222 * @param {string} fileSystemPath
223 * @param {number} worked
224 */
225 indexingWorked(requestId, fileSystemPath, worked) {
226 this._dispatchOnInspectorFrontendAPI('indexingWorked', [requestId, fileSystemPath, worked]);
227 }
228
229 /**
230 * @param {number} requestId
231 * @param {string} fileSystemPath
232 */
233 indexingDone(requestId, fileSystemPath) {
234 this._dispatchOnInspectorFrontendAPI('indexingDone', [requestId, fileSystemPath]);
235 }
236
237 /**
238 * @param {{type: string, key: string, code: string, keyCode: number, modifiers: number}} event
239 */
240 keyEventUnhandled(event) {
241 event.keyIdentifier = keyCodeToKeyIdentifier(event.keyCode);
242 this._dispatchOnInspectorFrontendAPI('keyEventUnhandled', [event]);
243 }
244
245 /**
Jeff Fisherac799a52019-06-25 21:47:06246 * @param {function(!ExtensionDescriptor)} callback
247 */
248 setAddExtensionCallback(callback) {
249 this._addExtensionCallback = callback;
250 if (this._pendingExtensionDescriptors.length) {
251 this._pendingExtensionDescriptors.forEach(this._addExtensionCallback);
252 this._pendingExtensionDescriptors = [];
253 }
254 }
255
Adithya Srinivasan7a133d22019-10-09 00:27:48256 reattachMainTarget() {
257 this._dispatchOnInspectorFrontendAPI('reattachMainTarget', []);
258 }
259
Jeff Fisherac799a52019-06-25 21:47:06260 /**
Blink Reformat4c46d092018-04-07 15:32:37261 * @param {boolean} hard
262 */
263 reloadInspectedPage(hard) {
264 this._dispatchOnInspectorFrontendAPI('reloadInspectedPage', [hard]);
265 }
266
267 /**
268 * @param {string} url
269 * @param {number} lineNumber
270 * @param {number} columnNumber
271 */
272 revealSourceLine(url, lineNumber, columnNumber) {
273 this._dispatchOnInspectorFrontendAPI('revealSourceLine', [url, lineNumber, columnNumber]);
274 }
275
276 /**
277 * @param {string} url
278 * @param {string=} fileSystemPath
279 */
280 savedURL(url, fileSystemPath) {
281 this._dispatchOnInspectorFrontendAPI('savedURL', [url, fileSystemPath]);
282 }
283
284 /**
285 * @param {number} requestId
286 * @param {string} fileSystemPath
287 * @param {!Array.<string>} files
288 */
289 searchCompleted(requestId, fileSystemPath, files) {
290 this._dispatchOnInspectorFrontendAPI('searchCompleted', [requestId, fileSystemPath, files]);
291 }
292
293 /**
294 * @param {string} tabId
295 */
296 setInspectedTabId(tabId) {
297 // Support for legacy front-ends (<M41).
Tim van der Lippe1d6e57a2019-09-30 11:55:34298 if (window['WebInspector'] && window['WebInspector']['setInspectedTabId']) {
Blink Reformat4c46d092018-04-07 15:32:37299 window['WebInspector']['setInspectedTabId'](tabId);
Tim van der Lippe1d6e57a2019-09-30 11:55:34300 } else {
Blink Reformat4c46d092018-04-07 15:32:37301 this._dispatchOnInspectorFrontendAPI('setInspectedTabId', [tabId]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34302 }
Blink Reformat4c46d092018-04-07 15:32:37303 }
304
305 /**
306 * @param {boolean} useSoftMenu
307 */
308 setUseSoftMenu(useSoftMenu) {
309 this._dispatchOnInspectorFrontendAPI('setUseSoftMenu', [useSoftMenu]);
310 }
311
312 /**
313 * @param {string} panelName
314 */
315 showPanel(panelName) {
316 this._dispatchOnInspectorFrontendAPI('showPanel', [panelName]);
317 }
318
319 /**
320 * @param {number} id
321 * @param {string} chunk
322 * @param {boolean} encoded
323 */
324 streamWrite(id, chunk, encoded) {
325 this._dispatchOnInspectorFrontendAPI('streamWrite', [id, encoded ? this._decodeBase64(chunk) : chunk]);
326 }
327
328 /**
329 * @param {string} chunk
330 * @return {string}
331 */
332 _decodeBase64(chunk) {
333 const request = new XMLHttpRequest();
334 request.open('GET', 'data:text/plain;base64,' + chunk, false);
335 request.send(null);
336 if (request.status === 200) {
337 return request.responseText;
338 } else {
339 console.error('Error while decoding chunk in streamWrite');
340 return '';
341 }
342 }
343 };
344
345 const DevToolsAPI = new DevToolsAPIImpl();
346 window.DevToolsAPI = DevToolsAPI;
347
348 // InspectorFrontendHostImpl --------------------------------------------------
349
350 /**
351 * @implements {InspectorFrontendHostAPI}
352 * @unrestricted
353 */
354 const InspectorFrontendHostImpl = class {
355 /**
Blink Reformat4c46d092018-04-07 15:32:37356 * @return {string}
357 */
358 getSelectionBackgroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02359 return '#6e86ff';
Blink Reformat4c46d092018-04-07 15:32:37360 }
361
362 /**
Blink Reformat4c46d092018-04-07 15:32:37363 * @return {string}
364 */
365 getSelectionForegroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02366 return '#ffffff';
Blink Reformat4c46d092018-04-07 15:32:37367 }
368
369 /**
Blink Reformat4c46d092018-04-07 15:32:37370 * @return {string}
371 */
372 getInactiveSelectionBackgroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02373 return '#c9c8c8';
Blink Reformat4c46d092018-04-07 15:32:37374 }
375
376 /**
Blink Reformat4c46d092018-04-07 15:32:37377 * @return {string}
378 */
379 getInactiveSelectionForegroundColor() {
Pavel Feldman33b40912018-12-22 01:08:02380 return '#323232';
Blink Reformat4c46d092018-04-07 15:32:37381 }
382
383 /**
384 * @override
385 * @return {string}
386 */
387 platform() {
388 return DevToolsHost.platform();
389 }
390
391 /**
392 * @override
393 */
394 loadCompleted() {
395 DevToolsAPI.sendMessageToEmbedder('loadCompleted', [], null);
396 // Support for legacy (<57) frontends.
397 if (window.Runtime && window.Runtime.queryParam) {
398 const panelToOpen = window.Runtime.queryParam('panel');
Tim van der Lippe1d6e57a2019-09-30 11:55:34399 if (panelToOpen) {
Blink Reformat4c46d092018-04-07 15:32:37400 window.DevToolsAPI.showPanel(panelToOpen);
Tim van der Lippe1d6e57a2019-09-30 11:55:34401 }
Blink Reformat4c46d092018-04-07 15:32:37402 }
403 }
404
405 /**
406 * @override
407 */
408 bringToFront() {
409 DevToolsAPI.sendMessageToEmbedder('bringToFront', [], null);
410 }
411
412 /**
413 * @override
414 */
415 closeWindow() {
416 DevToolsAPI.sendMessageToEmbedder('closeWindow', [], null);
417 }
418
419 /**
420 * @override
421 * @param {boolean} isDocked
422 * @param {function()} callback
423 */
424 setIsDocked(isDocked, callback) {
425 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [isDocked], callback);
426 }
427
428 /**
429 * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
430 * @override
431 * @param {{x: number, y: number, width: number, height: number}} bounds
432 */
433 setInspectedPageBounds(bounds) {
434 DevToolsAPI.sendMessageToEmbedder('setInspectedPageBounds', [bounds], null);
435 }
436
437 /**
438 * @override
439 */
440 inspectElementCompleted() {
441 DevToolsAPI.sendMessageToEmbedder('inspectElementCompleted', [], null);
442 }
443
444 /**
445 * @override
446 * @param {string} url
447 * @param {string} headers
448 * @param {number} streamId
449 * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
450 */
451 loadNetworkResource(url, headers, streamId, callback) {
452 DevToolsAPI.sendMessageToEmbedder(
453 'loadNetworkResource', [url, headers, streamId], /** @type {function(?Object)} */ (callback));
454 }
455
456 /**
457 * @override
458 * @param {function(!Object<string, string>)} callback
459 */
460 getPreferences(callback) {
461 DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback));
462 }
463
464 /**
465 * @override
466 * @param {string} name
467 * @param {string} value
468 */
469 setPreference(name, value) {
470 DevToolsAPI.sendMessageToEmbedder('setPreference', [name, value], null);
471 }
472
473 /**
474 * @override
475 * @param {string} name
476 */
477 removePreference(name) {
478 DevToolsAPI.sendMessageToEmbedder('removePreference', [name], null);
479 }
480
481 /**
482 * @override
483 */
484 clearPreferences() {
485 DevToolsAPI.sendMessageToEmbedder('clearPreferences', [], null);
486 }
487
488 /**
489 * @override
490 * @param {string} origin
491 * @param {string} script
492 */
493 setInjectedScriptForOrigin(origin, script) {
494 DevToolsAPI.sendMessageToEmbedder('registerExtensionsAPI', [origin, script], null);
495 }
496
497 /**
498 * @override
499 * @param {string} url
500 */
501 inspectedURLChanged(url) {
502 DevToolsAPI.sendMessageToEmbedder('inspectedURLChanged', [url], null);
503 }
504
505 /**
506 * @override
507 * @param {string} text
508 */
509 copyText(text) {
510 DevToolsHost.copyText(text);
511 }
512
513 /**
514 * @override
515 * @param {string} url
516 */
517 openInNewTab(url) {
518 DevToolsAPI.sendMessageToEmbedder('openInNewTab', [url], null);
519 }
520
521 /**
522 * @override
523 * @param {string} fileSystemPath
524 */
525 showItemInFolder(fileSystemPath) {
526 DevToolsAPI.sendMessageToEmbedder('showItemInFolder', [fileSystemPath], null);
527 }
528
529 /**
530 * @override
531 * @param {string} url
532 * @param {string} content
533 * @param {boolean} forceSaveAs
534 */
535 save(url, content, forceSaveAs) {
536 DevToolsAPI.sendMessageToEmbedder('save', [url, content, forceSaveAs], null);
537 }
538
539 /**
540 * @override
541 * @param {string} url
542 * @param {string} content
543 */
544 append(url, content) {
545 DevToolsAPI.sendMessageToEmbedder('append', [url, content], null);
546 }
547
548 /**
549 * @override
Pavel Feldmanf1a36ee2018-07-28 16:10:25550 * @param {string} url
551 */
552 close(url) {
553 }
554
555 /**
556 * @override
Blink Reformat4c46d092018-04-07 15:32:37557 * @param {string} message
558 */
559 sendMessageToBackend(message) {
560 DevToolsAPI.sendMessageToEmbedder('dispatchProtocolMessage', [message], null);
561 }
562
563 /**
564 * @override
565 * @param {string} actionName
566 * @param {number} actionCode
567 * @param {number} bucketSize
568 */
569 recordEnumeratedHistogram(actionName, actionCode, bucketSize) {
570 // Support for M49 frontend.
Tim van der Lippe1d6e57a2019-09-30 11:55:34571 if (actionName === 'DevTools.DrawerShown') {
Blink Reformat4c46d092018-04-07 15:32:37572 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34573 }
Blink Reformat4c46d092018-04-07 15:32:37574 DevToolsAPI.sendMessageToEmbedder('recordEnumeratedHistogram', [actionName, actionCode, bucketSize], null);
575 }
576
577 /**
578 * @override
James Lissiakd2f1a2f2019-03-26 17:36:51579 * @param {string} histogramName
580 * @param {number} duration
581 */
582 recordPerformanceHistogram(histogramName, duration) {
583 DevToolsAPI.sendMessageToEmbedder('recordPerformanceHistogram', [histogramName, duration], null);
584 }
585
586 /**
587 * @override
James Lissiake21c97b2019-04-29 17:36:43588 * @param {string} umaName
589 */
590 recordUserMetricsAction(umaName) {
591 DevToolsAPI.sendMessageToEmbedder('recordUserMetricsAction', [umaName], null);
592 }
593
594 /**
595 * @override
Blink Reformat4c46d092018-04-07 15:32:37596 */
597 requestFileSystems() {
598 DevToolsAPI.sendMessageToEmbedder('requestFileSystems', [], null);
599 }
600
601 /**
602 * @override
603 * @param {string=} type
604 */
605 addFileSystem(type) {
606 DevToolsAPI.sendMessageToEmbedder('addFileSystem', [type || ''], null);
607 }
608
609 /**
610 * @override
611 * @param {string} fileSystemPath
612 */
613 removeFileSystem(fileSystemPath) {
614 DevToolsAPI.sendMessageToEmbedder('removeFileSystem', [fileSystemPath], null);
615 }
616
617 /**
618 * @override
619 * @param {string} fileSystemId
620 * @param {string} registeredName
621 * @return {?DOMFileSystem}
622 */
623 isolatedFileSystem(fileSystemId, registeredName) {
624 return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName);
625 }
626
627 /**
628 * @override
629 * @param {!FileSystem} fileSystem
630 */
631 upgradeDraggedFileSystemPermissions(fileSystem) {
632 DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem);
633 }
634
635 /**
636 * @override
637 * @param {number} requestId
638 * @param {string} fileSystemPath
639 * @param {string} excludedFolders
640 */
641 indexPath(requestId, fileSystemPath, excludedFolders) {
642 // |excludedFolders| added in M67. For backward compatibility,
643 // pass empty array.
644 excludedFolders = excludedFolders || '[]';
645 DevToolsAPI.sendMessageToEmbedder('indexPath', [requestId, fileSystemPath, excludedFolders], null);
646 }
647
648 /**
649 * @override
650 * @param {number} requestId
651 */
652 stopIndexing(requestId) {
653 DevToolsAPI.sendMessageToEmbedder('stopIndexing', [requestId], null);
654 }
655
656 /**
657 * @override
658 * @param {number} requestId
659 * @param {string} fileSystemPath
660 * @param {string} query
661 */
662 searchInPath(requestId, fileSystemPath, query) {
663 DevToolsAPI.sendMessageToEmbedder('searchInPath', [requestId, fileSystemPath, query], null);
664 }
665
666 /**
667 * @override
668 * @return {number}
669 */
670 zoomFactor() {
671 return DevToolsHost.zoomFactor();
672 }
673
674 /**
675 * @override
676 */
677 zoomIn() {
678 DevToolsAPI.sendMessageToEmbedder('zoomIn', [], null);
679 }
680
681 /**
682 * @override
683 */
684 zoomOut() {
685 DevToolsAPI.sendMessageToEmbedder('zoomOut', [], null);
686 }
687
688 /**
689 * @override
690 */
691 resetZoom() {
692 DevToolsAPI.sendMessageToEmbedder('resetZoom', [], null);
693 }
694
695 /**
696 * @override
697 * @param {string} shortcuts
698 */
699 setWhitelistedShortcuts(shortcuts) {
700 DevToolsAPI.sendMessageToEmbedder('setWhitelistedShortcuts', [shortcuts], null);
701 }
702
703 /**
704 * @override
705 * @param {boolean} active
706 */
707 setEyeDropperActive(active) {
708 DevToolsAPI.sendMessageToEmbedder('setEyeDropperActive', [active], null);
709 }
710
711 /**
712 * @override
713 * @param {!Array<string>} certChain
714 */
715 showCertificateViewer(certChain) {
716 DevToolsAPI.sendMessageToEmbedder('showCertificateViewer', [JSON.stringify(certChain)], null);
717 }
718
719 /**
Connor Clarkca8905e2019-08-23 18:35:10720 * Only needed to run Lighthouse on old devtools.
Blink Reformat4c46d092018-04-07 15:32:37721 * @override
722 * @param {function()} callback
723 */
724 reattach(callback) {
725 DevToolsAPI.sendMessageToEmbedder('reattach', [], callback);
726 }
727
728 /**
729 * @override
730 */
731 readyForTest() {
732 DevToolsAPI.sendMessageToEmbedder('readyForTest', [], null);
733 }
734
735 /**
736 * @override
737 */
738 connectionReady() {
739 DevToolsAPI.sendMessageToEmbedder('connectionReady', [], null);
740 }
741
742 /**
743 * @override
744 * @param {boolean} value
745 */
746 setOpenNewWindowForPopups(value) {
747 DevToolsAPI.sendMessageToEmbedder('setOpenNewWindowForPopups', [value], null);
748 }
749
750 /**
751 * @override
752 * @param {!Adb.Config} config
753 */
754 setDevicesDiscoveryConfig(config) {
755 DevToolsAPI.sendMessageToEmbedder(
756 'setDevicesDiscoveryConfig',
757 [
758 config.discoverUsbDevices, config.portForwardingEnabled, JSON.stringify(config.portForwardingConfig),
759 config.networkDiscoveryEnabled, JSON.stringify(config.networkDiscoveryConfig)
760 ],
761 null);
762 }
763
764 /**
765 * @override
766 * @param {boolean} enabled
767 */
768 setDevicesUpdatesEnabled(enabled) {
769 DevToolsAPI.sendMessageToEmbedder('setDevicesUpdatesEnabled', [enabled], null);
770 }
771
772 /**
773 * @override
774 * @param {string} pageId
775 * @param {string} action
776 */
777 performActionOnRemotePage(pageId, action) {
778 DevToolsAPI.sendMessageToEmbedder('performActionOnRemotePage', [pageId, action], null);
779 }
780
781 /**
782 * @override
783 * @param {string} browserId
784 * @param {string} url
785 */
786 openRemotePage(browserId, url) {
787 DevToolsAPI.sendMessageToEmbedder('openRemotePage', [browserId, url], null);
788 }
789
790 /**
791 * @override
792 */
793 openNodeFrontend() {
794 DevToolsAPI.sendMessageToEmbedder('openNodeFrontend', [], null);
795 }
796
797 /**
798 * @override
799 * @param {number} x
800 * @param {number} y
801 * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
802 * @param {!Document} document
803 */
804 showContextMenuAtPoint(x, y, items, document) {
805 DevToolsHost.showContextMenuAtPoint(x, y, items, document);
806 }
807
808 /**
809 * @override
810 * @return {boolean}
811 */
812 isHostedMode() {
813 return DevToolsHost.isHostedMode();
814 }
815
Jeff Fisherac799a52019-06-25 21:47:06816 /**
817 * @override
818 * @param {function(!ExtensionDescriptor)} callback
819 */
820 setAddExtensionCallback(callback) {
821 DevToolsAPI.setAddExtensionCallback(callback);
822 }
823
Blink Reformat4c46d092018-04-07 15:32:37824 // Backward-compatible methods below this line --------------------------------------------
825
826 /**
827 * Support for legacy front-ends (<M65).
828 * @return {boolean}
829 */
830 isUnderTest() {
831 return false;
832 }
833
834 /**
835 * Support for legacy front-ends (<M50).
836 * @param {string} message
837 */
838 sendFrontendAPINotification(message) {
839 }
840
841 /**
842 * Support for legacy front-ends (<M41).
843 * @return {string}
844 */
845 port() {
846 return 'unknown';
847 }
848
849 /**
850 * Support for legacy front-ends (<M38).
851 * @param {number} zoomFactor
852 */
853 setZoomFactor(zoomFactor) {
854 }
855
856 /**
857 * Support for legacy front-ends (<M34).
858 */
859 sendMessageToEmbedder() {
860 }
861
862 /**
863 * Support for legacy front-ends (<M34).
864 * @param {string} dockSide
865 */
866 requestSetDockSide(dockSide) {
867 DevToolsAPI.sendMessageToEmbedder('setIsDocked', [dockSide !== 'undocked'], null);
868 }
869
870 /**
871 * Support for legacy front-ends (<M34).
872 * @return {boolean}
873 */
874 supportsFileSystems() {
875 return true;
876 }
877
878 /**
Blink Reformat4c46d092018-04-07 15:32:37879 * Support for legacy front-ends (<M44).
880 * @param {number} actionCode
881 */
882 recordActionTaken(actionCode) {
883 this.recordEnumeratedHistogram('DevTools.ActionTaken', actionCode, 100);
884 }
885
886 /**
887 * Support for legacy front-ends (<M44).
888 * @param {number} panelCode
889 */
890 recordPanelShown(panelCode) {
891 this.recordEnumeratedHistogram('DevTools.PanelShown', panelCode, 20);
892 }
893 };
894
895 window.InspectorFrontendHost = new InspectorFrontendHostImpl();
896
897 // DevToolsApp ---------------------------------------------------------------
898
899 function installObjectObserve() {
900 /** @type {!Array<string>} */
901 const properties = [
902 'advancedSearchConfig',
903 'auditsPanelSplitViewState',
904 'auditsSidebarWidth',
905 'blockedURLs',
906 'breakpoints',
907 'cacheDisabled',
908 'colorFormat',
909 'consoleHistory',
910 'consoleTimestampsEnabled',
911 'cpuProfilerView',
912 'cssSourceMapsEnabled',
913 'currentDockState',
914 'customColorPalette',
915 'customDevicePresets',
916 'customEmulatedDeviceList',
917 'customFormatters',
918 'customUserAgent',
919 'databaseTableViewVisibleColumns',
920 'dataGrid-cookiesTable',
921 'dataGrid-DOMStorageItemsView',
922 'debuggerSidebarHidden',
923 'disableDataSaverInfobar',
924 'disablePausedStateOverlay',
925 'domBreakpoints',
926 'domWordWrap',
927 'elementsPanelSplitViewState',
928 'elementsSidebarWidth',
929 'emulation.deviceHeight',
930 'emulation.deviceModeValue',
931 'emulation.deviceOrientationOverride',
932 'emulation.deviceScale',
933 'emulation.deviceScaleFactor',
934 'emulation.deviceUA',
935 'emulation.deviceWidth',
936 'emulation.geolocationOverride',
937 'emulation.showDeviceMode',
938 'emulation.showRulers',
939 'enableAsyncStackTraces',
940 'eventListenerBreakpoints',
941 'fileMappingEntries',
942 'fileSystemMapping',
943 'FileSystemViewSidebarWidth',
944 'fileSystemViewSplitViewState',
945 'filterBar-consoleView',
946 'filterBar-networkPanel',
947 'filterBar-promisePane',
948 'filterBar-timelinePanel',
949 'frameViewerHideChromeWindow',
950 'heapSnapshotRetainersViewSize',
951 'heapSnapshotSplitViewState',
952 'hideCollectedPromises',
953 'hideNetworkMessages',
954 'highlightNodeOnHoverInOverlay',
955 'highResolutionCpuProfiling',
956 'inlineVariableValues',
957 'Inspector.drawerSplitView',
958 'Inspector.drawerSplitViewState',
959 'InspectorView.panelOrder',
960 'InspectorView.screencastSplitView',
961 'InspectorView.screencastSplitViewState',
962 'InspectorView.splitView',
963 'InspectorView.splitViewState',
964 'javaScriptDisabled',
965 'jsSourceMapsEnabled',
966 'lastActivePanel',
967 'lastDockState',
968 'lastSelectedSourcesSidebarPaneTab',
969 'lastSnippetEvaluationIndex',
970 'layerDetailsSplitView',
971 'layerDetailsSplitViewState',
972 'layersPanelSplitViewState',
973 'layersShowInternalLayers',
974 'layersSidebarWidth',
975 'messageLevelFilters',
976 'messageURLFilters',
977 'monitoringXHREnabled',
978 'navigatorGroupByFolder',
979 'navigatorHidden',
980 'networkColorCodeResourceTypes',
981 'networkConditions',
982 'networkConditionsCustomProfiles',
983 'networkHideDataURL',
984 'networkLogColumnsVisibility',
985 'networkLogLargeRows',
986 'networkLogShowOverview',
987 'networkPanelSplitViewState',
988 'networkRecordFilmStripSetting',
989 'networkResourceTypeFilters',
990 'networkShowPrimaryLoadWaterfall',
991 'networkSidebarWidth',
992 'openLinkHandler',
993 'pauseOnCaughtException',
994 'pauseOnExceptionEnabled',
995 'preserveConsoleLog',
996 'prettyPrintInfobarDisabled',
997 'previouslyViewedFiles',
998 'profilesPanelSplitViewState',
999 'profilesSidebarWidth',
1000 'promiseStatusFilters',
1001 'recordAllocationStacks',
1002 'requestHeaderFilterSetting',
1003 'request-info-formData-category-expanded',
1004 'request-info-general-category-expanded',
1005 'request-info-queryString-category-expanded',
1006 'request-info-requestHeaders-category-expanded',
1007 'request-info-requestPayload-category-expanded',
1008 'request-info-responseHeaders-category-expanded',
1009 'resources',
1010 'resourcesLastSelectedItem',
1011 'resourcesPanelSplitViewState',
1012 'resourcesSidebarWidth',
1013 'resourceViewTab',
1014 'savedURLs',
1015 'screencastEnabled',
1016 'scriptsPanelNavigatorSidebarWidth',
1017 'searchInContentScripts',
1018 'selectedAuditCategories',
1019 'selectedColorPalette',
1020 'selectedProfileType',
1021 'shortcutPanelSwitch',
1022 'showAdvancedHeapSnapshotProperties',
1023 'showEventListenersForAncestors',
1024 'showFrameowkrListeners',
1025 'showHeaSnapshotObjectsHiddenProperties',
1026 'showInheritedComputedStyleProperties',
1027 'showMediaQueryInspector',
1028 'showNativeFunctionsInJSProfile',
1029 'showUAShadowDOM',
1030 'showWhitespacesInEditor',
1031 'sidebarPosition',
1032 'skipContentScripts',
1033 'skipStackFramesPattern',
1034 'sourceMapInfobarDisabled',
1035 'sourcesPanelDebuggerSidebarSplitViewState',
1036 'sourcesPanelNavigatorSplitViewState',
1037 'sourcesPanelSplitSidebarRatio',
1038 'sourcesPanelSplitViewState',
1039 'sourcesSidebarWidth',
1040 'standardEmulatedDeviceList',
1041 'StylesPaneSplitRatio',
1042 'stylesPaneSplitViewState',
1043 'textEditorAutocompletion',
1044 'textEditorAutoDetectIndent',
1045 'textEditorBracketMatching',
1046 'textEditorIndent',
Junyi Xiao89142cf2019-04-11 16:01:381047 'textEditorTabMovesFocus',
Blink Reformat4c46d092018-04-07 15:32:371048 'timelineCaptureFilmStrip',
1049 'timelineCaptureLayersAndPictures',
1050 'timelineCaptureMemory',
1051 'timelineCaptureNetwork',
1052 'timeline-details',
1053 'timelineEnableJSSampling',
1054 'timelineOverviewMode',
1055 'timelinePanelDetailsSplitViewState',
1056 'timelinePanelRecorsSplitViewState',
1057 'timelinePanelTimelineStackSplitViewState',
1058 'timelinePerspective',
1059 'timeline-split',
1060 'timelineTreeGroupBy',
1061 'timeline-view',
1062 'timelineViewMode',
1063 'uiTheme',
1064 'watchExpressions',
1065 'WebInspector.Drawer.lastSelectedView',
1066 'WebInspector.Drawer.showOnLoad',
1067 'workspaceExcludedFolders',
1068 'workspaceFolderExcludePattern',
1069 'workspaceInfobarDisabled',
1070 'workspaceMappingInfobarDisabled',
1071 'xhrBreakpoints'
1072 ];
1073
1074 /**
1075 * @this {!{_storage: Object, _name: string}}
1076 */
1077 function settingRemove() {
1078 this._storage[this._name] = undefined;
1079 }
1080
1081 /**
1082 * @param {!Object} object
1083 * @param {function(!Array<!{name: string}>)} observer
1084 */
1085 function objectObserve(object, observer) {
1086 if (window['WebInspector']) {
1087 const settingPrototype = /** @type {!Object} */ (window['WebInspector']['Setting']['prototype']);
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 if (typeof settingPrototype['remove'] === 'function') {
Blink Reformat4c46d092018-04-07 15:32:371089 settingPrototype['remove'] = settingRemove;
Tim van der Lippe1d6e57a2019-09-30 11:55:341090 }
Blink Reformat4c46d092018-04-07 15:32:371091 }
1092 /** @type {!Set<string>} */
1093 const changedProperties = new Set();
1094 let scheduled = false;
1095
1096 function scheduleObserver() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341097 if (scheduled) {
Blink Reformat4c46d092018-04-07 15:32:371098 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341099 }
Blink Reformat4c46d092018-04-07 15:32:371100 scheduled = true;
1101 setImmediate(callObserver);
1102 }
1103
1104 function callObserver() {
1105 scheduled = false;
1106 const changes = /** @type {!Array<!{name: string}>} */ ([]);
1107 changedProperties.forEach(function(name) {
1108 changes.push({name: name});
1109 });
1110 changedProperties.clear();
1111 observer.call(null, changes);
1112 }
1113
1114 /** @type {!Map<string, *>} */
1115 const storage = new Map();
1116
1117 /**
1118 * @param {string} property
1119 */
1120 function defineProperty(property) {
1121 if (property in object) {
1122 storage.set(property, object[property]);
1123 delete object[property];
1124 }
1125
1126 Object.defineProperty(object, property, {
1127 /**
1128 * @return {*}
1129 */
1130 get: function() {
1131 return storage.get(property);
1132 },
1133
1134 /**
1135 * @param {*} value
1136 */
1137 set: function(value) {
1138 storage.set(property, value);
1139 changedProperties.add(property);
1140 scheduleObserver();
1141 }
1142 });
1143 }
1144
Tim van der Lippe1d6e57a2019-09-30 11:55:341145 for (let i = 0; i < properties.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371146 defineProperty(properties[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341147 }
Blink Reformat4c46d092018-04-07 15:32:371148 }
1149
1150 window.Object.observe = objectObserve;
1151 }
1152
1153 /** @type {!Map<number, string>} */
1154 const staticKeyIdentifiers = new Map([
1155 [0x12, 'Alt'],
1156 [0x11, 'Control'],
1157 [0x10, 'Shift'],
1158 [0x14, 'CapsLock'],
1159 [0x5b, 'Win'],
1160 [0x5c, 'Win'],
1161 [0x0c, 'Clear'],
1162 [0x28, 'Down'],
1163 [0x23, 'End'],
1164 [0x0a, 'Enter'],
1165 [0x0d, 'Enter'],
1166 [0x2b, 'Execute'],
1167 [0x70, 'F1'],
1168 [0x71, 'F2'],
1169 [0x72, 'F3'],
1170 [0x73, 'F4'],
1171 [0x74, 'F5'],
1172 [0x75, 'F6'],
1173 [0x76, 'F7'],
1174 [0x77, 'F8'],
1175 [0x78, 'F9'],
1176 [0x79, 'F10'],
1177 [0x7a, 'F11'],
1178 [0x7b, 'F12'],
1179 [0x7c, 'F13'],
1180 [0x7d, 'F14'],
1181 [0x7e, 'F15'],
1182 [0x7f, 'F16'],
1183 [0x80, 'F17'],
1184 [0x81, 'F18'],
1185 [0x82, 'F19'],
1186 [0x83, 'F20'],
1187 [0x84, 'F21'],
1188 [0x85, 'F22'],
1189 [0x86, 'F23'],
1190 [0x87, 'F24'],
1191 [0x2f, 'Help'],
1192 [0x24, 'Home'],
1193 [0x2d, 'Insert'],
1194 [0x25, 'Left'],
1195 [0x22, 'PageDown'],
1196 [0x21, 'PageUp'],
1197 [0x13, 'Pause'],
1198 [0x2c, 'PrintScreen'],
1199 [0x27, 'Right'],
1200 [0x91, 'Scroll'],
1201 [0x29, 'Select'],
1202 [0x26, 'Up'],
1203 [0x2e, 'U+007F'], // Standard says that DEL becomes U+007F.
1204 [0xb0, 'MediaNextTrack'],
1205 [0xb1, 'MediaPreviousTrack'],
1206 [0xb2, 'MediaStop'],
1207 [0xb3, 'MediaPlayPause'],
1208 [0xad, 'VolumeMute'],
1209 [0xae, 'VolumeDown'],
1210 [0xaf, 'VolumeUp'],
1211 ]);
1212
1213 /**
1214 * @param {number} keyCode
1215 * @return {string}
1216 */
1217 function keyCodeToKeyIdentifier(keyCode) {
1218 let result = staticKeyIdentifiers.get(keyCode);
Tim van der Lippe1d6e57a2019-09-30 11:55:341219 if (result !== undefined) {
Blink Reformat4c46d092018-04-07 15:32:371220 return result;
Tim van der Lippe1d6e57a2019-09-30 11:55:341221 }
Blink Reformat4c46d092018-04-07 15:32:371222 result = 'U+';
1223 const hexString = keyCode.toString(16).toUpperCase();
Tim van der Lippe1d6e57a2019-09-30 11:55:341224 for (let i = hexString.length; i < 4; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371225 result += '0';
Tim van der Lippe1d6e57a2019-09-30 11:55:341226 }
Blink Reformat4c46d092018-04-07 15:32:371227 result += hexString;
1228 return result;
1229 }
1230
1231 function installBackwardsCompatibility() {
Joel Einbinderf55cc942018-10-30 01:59:531232 const majorVersion = getRemoteMajorVersion();
Tim van der Lippe1d6e57a2019-09-30 11:55:341233 if (!majorVersion) {
Blink Reformat4c46d092018-04-07 15:32:371234 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341235 }
Blink Reformat4c46d092018-04-07 15:32:371236
Joel Einbinderf55cc942018-10-30 01:59:531237 /** @type {!Array<string>} */
1238 const styleRules = [];
Joel Einbinder82b1d8e2018-12-08 01:01:371239 // Shadow DOM V0 polyfill
1240 if (majorVersion <= 73 && !Element.prototype.createShadowRoot) {
1241 Element.prototype.createShadowRoot = function() {
1242 try {
1243 return this.attachShadow({mode: 'open'});
1244 } catch (e) {
1245 // some elements we use to add shadow roots can no
1246 // longer have shadow roots.
1247 const fakeShadowHost = document.createElement('span');
1248 this.appendChild(fakeShadowHost);
1249 fakeShadowHost.className = 'fake-shadow-host';
1250 return fakeShadowHost.createShadowRoot();
1251 }
1252 };
1253
1254 const origAdd = DOMTokenList.prototype.add;
1255 DOMTokenList.prototype.add = function(...tokens) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341256 if (tokens[0].startsWith('insertion-point') || tokens[0].startsWith('tabbed-pane-header')) {
Joel Einbinder82b1d8e2018-12-08 01:01:371257 this._myElement.slot = '.' + tokens[0];
Tim van der Lippe1d6e57a2019-09-30 11:55:341258 }
Joel Einbinder82b1d8e2018-12-08 01:01:371259 return origAdd.apply(this, tokens);
1260 };
1261
1262 const origCreateElement = Document.prototype.createElement;
1263 Document.prototype.createElement = function(tagName, ...rest) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341264 if (tagName === 'content') {
Joel Einbinder82b1d8e2018-12-08 01:01:371265 tagName = 'slot';
Tim van der Lippe1d6e57a2019-09-30 11:55:341266 }
Joel Einbinder82b1d8e2018-12-08 01:01:371267 const element = origCreateElement.call(this, tagName, ...rest);
1268 element.classList._myElement = element;
1269 return element;
1270 };
1271
1272 Object.defineProperty(HTMLSlotElement.prototype, 'select', {
1273 async set(selector) {
1274 this.name = selector;
1275 }
1276 });
Joel Einbinderb948ebc2018-12-12 02:01:121277
Joel Einbinderb948ebc2018-12-12 02:01:121278 function overrideCreateElementWithClass() {
1279 window.removeEventListener('DOMContentLoaded', overrideCreateElementWithClass);
1280
1281 const origCreateElementWithClass = Document.prototype.createElementWithClass;
1282 Document.prototype.createElementWithClass = function(tagName, className, ...rest) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341283 if (tagName !== 'button' || (className !== 'soft-dropdown' && className !== 'dropdown-button')) {
Joel Einbinderb948ebc2018-12-12 02:01:121284 return origCreateElementWithClass.call(this, tagName, className, ...rest);
Tim van der Lippe1d6e57a2019-09-30 11:55:341285 }
Joel Einbinderb948ebc2018-12-12 02:01:121286 const element = origCreateElementWithClass.call(this, 'div', className, ...rest);
1287 element.tabIndex = 0;
1288 element.role = 'button';
1289 return element;
1290 };
1291 }
Tim van der Lippeffa78622019-09-16 12:07:121292
1293 // Document.prototype.createElementWithClass is a DevTools method, so we
1294 // need to wait for DOMContentLoaded in order to override it.
1295 if (window.document.head &&
Tim van der Lippe1d6e57a2019-09-30 11:55:341296 (window.document.readyState === 'complete' || window.document.readyState === 'interactive')) {
Tim van der Lippeffa78622019-09-16 12:07:121297 overrideCreateElementWithClass();
Tim van der Lippe1d6e57a2019-09-30 11:55:341298 } else {
Tim van der Lippeffa78622019-09-16 12:07:121299 window.addEventListener('DOMContentLoaded', overrideCreateElementWithClass);
Tim van der Lippe1d6e57a2019-09-30 11:55:341300 }
Joel Einbinderb948ebc2018-12-12 02:01:121301 }
1302
1303 // Custom Elements V0 polyfill
Tim van der Lippeffa78622019-09-16 12:07:121304 if (majorVersion <= 73 && !Document.prototype.hasOwnProperty('registerElement')) {
Joel Einbinderb948ebc2018-12-12 02:01:121305 const fakeRegistry = new Map();
1306 Document.prototype.registerElement = function(typeExtension, options) {
1307 const {prototype, extends: localName} = options;
1308 const document = this;
1309 const callback = function() {
1310 const element = document.createElement(localName || typeExtension);
1311 const skip = new Set(['constructor', '__proto__']);
1312 for (const key of Object.keys(Object.getOwnPropertyDescriptors(prototype.__proto__ || {}))) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341313 if (skip.has(key)) {
Joel Einbinderb948ebc2018-12-12 02:01:121314 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341315 }
Joel Einbinderb948ebc2018-12-12 02:01:121316 element[key] = prototype[key];
1317 }
1318 element.setAttribute('is', typeExtension);
Tim van der Lippe1d6e57a2019-09-30 11:55:341319 if (element['createdCallback']) {
Joel Einbinderb948ebc2018-12-12 02:01:121320 element['createdCallback']();
Tim van der Lippe1d6e57a2019-09-30 11:55:341321 }
Joel Einbinderb948ebc2018-12-12 02:01:121322 return element;
1323 };
1324 fakeRegistry.set(typeExtension, callback);
1325 return callback;
1326 };
1327
1328 const origCreateElement = Document.prototype.createElement;
1329 Document.prototype.createElement = function(tagName, fakeCustomElementType) {
1330 const fakeConstructor = fakeRegistry.get(fakeCustomElementType);
Tim van der Lippe1d6e57a2019-09-30 11:55:341331 if (fakeConstructor) {
Joel Einbinderb948ebc2018-12-12 02:01:121332 return fakeConstructor();
Tim van der Lippe1d6e57a2019-09-30 11:55:341333 }
Joel Einbinderb948ebc2018-12-12 02:01:121334 return origCreateElement.call(this, tagName, fakeCustomElementType);
Joel Einbinder82b1d8e2018-12-08 01:01:371335 };
Pavel Feldman876d7182018-12-14 00:11:051336
1337 // DevTools front-ends mistakenly assume that
1338 // classList.toggle('a', undefined) works as
1339 // classList.toggle('a', false) rather than as
1340 // classList.toggle('a');
1341 const originalDOMTokenListToggle = DOMTokenList.prototype.toggle;
1342 DOMTokenList.prototype.toggle = function(token, force) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341343 if (arguments.length === 1) {
Pavel Feldman876d7182018-12-14 00:11:051344 force = !this.contains(token);
Tim van der Lippe1d6e57a2019-09-30 11:55:341345 }
Pavel Feldman876d7182018-12-14 00:11:051346 return originalDOMTokenListToggle.call(this, token, !!force);
1347 };
Joel Einbinder82b1d8e2018-12-08 01:01:371348 }
Blink Reformat4c46d092018-04-07 15:32:371349
Joel Einbinderf55cc942018-10-30 01:59:531350 if (majorVersion <= 66) {
1351 /** @type {(!function(number, number):Element|undefined)} */
1352 ShadowRoot.prototype.__originalShadowRootElementFromPoint;
1353
1354 if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) {
1355 ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint;
1356 /**
1357 * @param {number} x
1358 * @param {number} y
1359 * @return {Element}
1360 */
1361 ShadowRoot.prototype.elementFromPoint = function(x, y) {
1362 const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments);
Tim van der Lippe1d6e57a2019-09-30 11:55:341363 if (this.host && originalResult === this.host) {
Joel Einbinderf55cc942018-10-30 01:59:531364 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341365 }
Joel Einbinderf55cc942018-10-30 01:59:531366 return originalResult;
1367 };
1368 }
Blink Reformat4c46d092018-04-07 15:32:371369 }
1370
Joel Einbinderf55cc942018-10-30 01:59:531371 if (majorVersion <= 53) {
Blink Reformat4c46d092018-04-07 15:32:371372 Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', {
1373 /**
1374 * @return {string}
1375 * @this {KeyboardEvent}
1376 */
1377 get: function() {
1378 return keyCodeToKeyIdentifier(this.keyCode);
1379 }
1380 });
1381 }
1382
Tim van der Lippe1d6e57a2019-09-30 11:55:341383 if (majorVersion <= 50) {
Joel Einbinderf55cc942018-10-30 01:59:531384 installObjectObserve();
Tim van der Lippe1d6e57a2019-09-30 11:55:341385 }
Blink Reformat4c46d092018-04-07 15:32:371386
Joel Einbinderf55cc942018-10-30 01:59:531387 if (majorVersion <= 45) {
1388 /**
1389 * @param {string} property
1390 * @return {!CSSValue|null}
1391 * @this {CSSStyleDeclaration}
1392 */
1393 function getValue(property) {
1394 // Note that |property| comes from another context, so we can't use === here.
1395 // eslint-disable-next-line eqeqeq
1396 if (property == 'padding-left') {
1397 return /** @type {!CSSValue} */ ({
1398 /**
1399 * @return {number}
1400 * @this {!{__paddingLeft: number}}
1401 */
1402 getFloatValue: function() {
1403 return this.__paddingLeft;
1404 },
1405 __paddingLeft: parseFloat(this.paddingLeft)
1406 });
1407 }
1408 throw new Error('getPropertyCSSValue is undefined');
Blink Reformat4c46d092018-04-07 15:32:371409 }
Joel Einbinderf55cc942018-10-30 01:59:531410
1411 window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue;
1412
1413 function CSSPrimitiveValue() {
1414 }
1415 CSSPrimitiveValue.CSS_PX = 5;
1416 window.CSSPrimitiveValue = CSSPrimitiveValue;
Blink Reformat4c46d092018-04-07 15:32:371417 }
1418
Tim van der Lippe1d6e57a2019-09-30 11:55:341419 if (majorVersion <= 45) {
Joel Einbinderf55cc942018-10-30 01:59:531420 styleRules.push('* { min-width: 0; min-height: 0; }');
Tim van der Lippe1d6e57a2019-09-30 11:55:341421 }
Blink Reformat4c46d092018-04-07 15:32:371422
Joel Einbinderf55cc942018-10-30 01:59:531423 if (majorVersion <= 51) {
1424 // Support for quirky border-image behavior (<M51), see:
1425 // https://bugs.chromium.org/p/chromium/issues/detail?id=559258
1426 styleRules.push('.cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }');
1427 styleRules.push(
1428 '.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }');
Blink Reformat4c46d092018-04-07 15:32:371429 }
Christian Biesinger2d1b2e92018-11-06 01:18:251430 if (majorVersion <= 71) {
1431 styleRules.push(
1432 '.coverage-toolbar-container, .animation-timeline-toolbar-container, .computed-properties { flex-basis: auto; }');
1433 }
Blink Reformat4c46d092018-04-07 15:32:371434
Tim van der Lippe1d6e57a2019-09-30 11:55:341435 if (majorVersion <= 50) {
Joel Einbinderf55cc942018-10-30 01:59:531436 Event.prototype.deepPath = undefined;
Tim van der Lippe1d6e57a2019-09-30 11:55:341437 }
Blink Reformat4c46d092018-04-07 15:32:371438
Joel Einbinderf55cc942018-10-30 01:59:531439 if (majorVersion <= 54) {
1440 window.FileError = /** @type {!function (new: FileError) : ?} */ ({
1441 NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR,
1442 ABORT_ERR: DOMException.ABORT_ERR,
1443 INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR,
1444 NOT_READABLE_ERR: 0 // No matching DOMException, so code will be 0.
1445 });
1446 }
Blink Reformat4c46d092018-04-07 15:32:371447
Joel Einbinderf55cc942018-10-30 01:59:531448 installExtraStyleRules(styleRules);
1449 }
Blink Reformat4c46d092018-04-07 15:32:371450
Joel Einbinderf55cc942018-10-30 01:59:531451 /**
1452 * @return {?number}
1453 */
1454 function getRemoteMajorVersion() {
1455 try {
Joel Einbinder09f48742019-02-28 01:34:421456 const remoteVersion = new URLSearchParams(window.location.search).get('remoteVersion');
Tim van der Lippe1d6e57a2019-09-30 11:55:341457 if (!remoteVersion) {
Joel Einbinderf55cc942018-10-30 01:59:531458 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341459 }
Joel Einbinderf55cc942018-10-30 01:59:531460 const majorVersion = parseInt(remoteVersion.split('.')[0], 10);
1461 return majorVersion;
Joel Einbinder31904782018-11-02 20:52:271462 } catch (e) {
Joel Einbinderf55cc942018-10-30 01:59:531463 return null;
1464 }
1465 }
1466
1467 /**
1468 * @param {!Array<string>} styleRules
1469 */
1470 function installExtraStyleRules(styleRules) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341471 if (!styleRules.length) {
Joel Einbinderf55cc942018-10-30 01:59:531472 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341473 }
Joel Einbinderf55cc942018-10-30 01:59:531474 const styleText = styleRules.join('\n');
1475 document.head.appendChild(createStyleElement(styleText));
1476
1477 const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
1478 HTMLElement.prototype.createShadowRoot = function(...args) {
1479 const shadowRoot = origCreateShadowRoot.call(this, ...args);
1480 shadowRoot.appendChild(createStyleElement(styleText));
1481 return shadowRoot;
1482 };
1483 }
1484
1485 /**
1486 * @param {string} styleText
1487 * @return {!Element}
1488 */
1489 function createStyleElement(styleText) {
1490 const style = document.createElement('style');
Joel Einbinderf55cc942018-10-30 01:59:531491 style.textContent = styleText;
1492 return style;
Blink Reformat4c46d092018-04-07 15:32:371493 }
1494
Joel Einbinderb948ebc2018-12-12 02:01:121495 installBackwardsCompatibility();
Blink Reformat4c46d092018-04-07 15:32:371496
Blink Reformat4c46d092018-04-07 15:32:371497})(window);