diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/devtools/front_end')
134 files changed, 2213 insertions, 1784 deletions
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png Binary files differindex b5121c3e878..47735c156da 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png +++ b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js index 5e6e5f1a0eb..46698e7727e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js @@ -66,8 +66,6 @@ var Runtime = class { // eslint-disable-line for (let i = 0; i < descriptors.length; ++i) this._registerModule(descriptors[i]); - - Runtime._runtimeReadyPromiseCallback(); } /** @@ -237,8 +235,8 @@ var Runtime = class { // eslint-disable-line /** * @return {!Promise} */ - static async runtimeReady() { - return Runtime._runtimeReadyPromise; + static async appStarted() { + return Runtime._appStartedPromise; } /** @@ -289,7 +287,8 @@ var Runtime = class { // eslint-disable-line } self.runtime = new Runtime(moduleDescriptors); if (coreModuleNames) - return /** @type {!Promise<undefined>} */ (self.runtime._loadAutoStartModules(coreModuleNames)); + await self.runtime._loadAutoStartModules(coreModuleNames); + Runtime._appStartedPromiseCallback(); } /** @@ -309,7 +308,7 @@ var Runtime = class { // eslint-disable-line * @return {?string} */ static queryParam(name) { - return Runtime._queryParamsObject[name] || null; + return Runtime._queryParamsObject.get(name); } /** @@ -564,12 +563,8 @@ var Runtime = class { // eslint-disable-line } }; -/** - * @type {!Object.<string, string>} - */ -Runtime._queryParamsObject = { - __proto__: null -}; +/** @type {!URLSearchParams} */ +Runtime._queryParamsObject = new URLSearchParams(Runtime.queryParamsString()); Runtime._instanceSymbol = Symbol('instance'); @@ -1069,26 +1064,12 @@ Runtime.Experiment = class { } }; -{ - (function parseQueryParameters() { - const queryParams = Runtime.queryParamsString(); - if (!queryParams) - return; - const params = queryParams.substring(1).split('&'); - for (let i = 0; i < params.length; ++i) { - const pair = params[i].split('='); - const name = pair.shift(); - Runtime._queryParamsObject[name] = pair.join('='); - } - })(); -} - // This must be constructed after the query parameters have been parsed. Runtime.experiments = new Runtime.ExperimentsSupport(); /** @type {Function} */ -Runtime._runtimeReadyPromiseCallback; -Runtime._runtimeReadyPromise = new Promise(fulfil => Runtime._runtimeReadyPromiseCallback = fulfil); +Runtime._appStartedPromiseCallback; +Runtime._appStartedPromise = new Promise(fulfil => Runtime._appStartedPromiseCallback = fulfil); /** * @type {?string} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Tests.js b/chromium/third_party/blink/renderer/devtools/front_end/Tests.js index 574c67c8e39..6fa4ef30d9c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/Tests.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/Tests.js @@ -565,7 +565,7 @@ this._waitForTargets(2, callback.bind(this)); function callback() { - Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches(this.releaseControl.bind(this)); + Protocol.test.deprecatedRunAfterPendingDispatches(this.releaseControl.bind(this)); } }; @@ -591,6 +591,15 @@ } }; + TestSuite.prototype.testSharedWorkerNetworkPanel = function() { + this.takeControl(); + this.showPanel('network').then(() => { + if (!document.querySelector('#network-container')) + this.fail('unable to find #network-container'); + this.releaseControl(); + }); + }; + TestSuite.prototype.enableTouchEmulation = function() { const deviceModeModel = new Emulation.DeviceModeModel(function() {}); deviceModeModel._target = SDK.targetManager.mainTarget(); @@ -1169,7 +1178,7 @@ browserContextIds.push(browserContextId); const {targetId} = await targetAgent.invoke_createTarget({url: 'about:blank', browserContextId}); - await targetAgent.invoke_attachToTarget({targetId}); + await targetAgent.invoke_attachToTarget({targetId, flatten: true}); const target = SDK.targetManager.targets().find(target => target.id() === targetId); const pageAgent = target.pageAgent(); @@ -1278,6 +1287,14 @@ }); await testCase(baseURL + 'echoheader?Cookie', undefined, 200, ['cache-control'], 'devtools-test-cookie=Bar'); + await SDK.targetManager.mainTarget().runtimeAgent().invoke_evaluate({ + expression: `fetch("/set-cookie?devtools-test-cookie=same-site-cookie;SameSite=Lax", + {credentials: 'include'})`, + awaitPromise: true + }); + await testCase( + baseURL + 'echoheader?Cookie', undefined, 200, ['cache-control'], 'devtools-test-cookie=same-site-cookie'); + this.releaseControl(); }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js b/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js index f0c0a2e4ec1..0706be5c305 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityNodeView.js @@ -507,7 +507,9 @@ Accessibility.AXRelatedNodeElement = class { if (this._deferredNode) { valueElement = createElement('span'); element.appendChild(valueElement); - Common.Linkifier.linkify(this._deferredNode).then(linkfied => valueElement.appendChild(linkfied)); + this._deferredNode.resolvePromise().then(node => { + Common.Linkifier.linkify(node).then(linkfied => valueElement.appendChild(linkfied)); + }); } else if (this._idref) { element.classList.add('invalid'); valueElement = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`No node with this ID.`); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityStrings.js b/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityStrings.js index 50d31b2f74c..a6f573bebe9 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityStrings.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/accessibility/AccessibilityStrings.js @@ -14,6 +14,10 @@ Accessibility.AccessibilityStrings.AXAttributes = { description: 'If true, this element\'s user-entered value does not conform to validation requirement.', group: 'AXGlobalStates' }, + 'editable': {name: 'Editable', description: 'If and how this element can be edited.'}, + 'focusable': {name: 'Focusable', description: 'If true, this element can recieve focus.'}, + 'focused': {name: 'Focused', description: 'If true, this element currently has focus.'}, + 'settable': {name: 'Can set value', description: 'Whether the value of this element can be set.'}, 'live': { name: 'Live region', description: 'Whether and what priority of live updates may be expected for this element.', diff --git a/chromium/third_party/blink/renderer/devtools/front_end/animation/animationTimeline.css b/chromium/third_party/blink/renderer/devtools/front_end/animation/animationTimeline.css index 703fb866819..37f109c646e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/animation/animationTimeline.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/animation/animationTimeline.css @@ -97,7 +97,7 @@ circle.animation-keyframe-point { display: flex; background-color: var(--toolbar-bg-color); border-bottom: var(--divider-border); - flex: 0 0; + flex: 0 0 auto; } .animation-timeline-toolbar { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js index 29d10ccfd4f..a0b90cbf450 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js @@ -123,6 +123,10 @@ ApplicationTestRunner.addCacheEntry = function(cacheName, requestUrl, responseTe return TestRunner.callFunctionInPageAsync('addCacheEntry', [cacheName, requestUrl, responseText]); }; +ApplicationTestRunner.addCacheEntryWithNoCorsRequest = function(cacheName, requestUrl) { + return TestRunner.callFunctionInPageAsync('addCacheEntryWithNoCorsRequest', [cacheName, requestUrl]); +}; + ApplicationTestRunner.deleteCache = function(cacheName) { return TestRunner.callFunctionInPageAsync('deleteCache', [cacheName]); }; @@ -159,6 +163,13 @@ TestRunner.deprecatedInitAsync(` }).catch(onCacheStorageError); } + function addCacheEntryWithNoCorsRequest(cacheName, requestUrl) { + return caches.open(cacheName).then(async function(cache) { + let request = new Request(requestUrl, {mode: 'no-cors'}); + return cache.put(request, await fetch(request)); + }).catch(onCacheStorageError); + } + function deleteCache(cacheName) { return caches.delete(cacheName).then(function(success) { if (!success) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js index b7f4d2f7b74..f83e6d9df15 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/application_test_runner/ServiceWorkersTestRunner.js @@ -25,7 +25,8 @@ ApplicationTestRunner.postToServiceWorker = function(scope, message) { ApplicationTestRunner.waitForServiceWorker = function(callback) { function isRightTarget(target) { - return TestRunner.isDedicatedWorker(target) && TestRunner.isServiceWorker(target.parentTarget()); + return target.type() === SDK.Target.Type.Worker && target.parentTarget() && + target.parentTarget().type() === SDK.Target.Type.ServiceWorker; } SDK.targetManager.observeTargets({ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2Panel.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2Panel.js index 109d719b702..3ccfd560b32 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2Panel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2Panel.js @@ -137,9 +137,7 @@ Audits2.Audits2Panel = class extends UI.Panel { const reportContainer = this._auditResultsElement.createChild('div', 'lh-vars lh-root lh-devtools'); const dom = new DOM(/** @type {!Document} */ (this._auditResultsElement.ownerDocument)); - const detailsRenderer = new Audits2.DetailsRenderer(dom); - const categoryRenderer = new CategoryRenderer(dom, detailsRenderer); - const renderer = new Audits2.ReportRenderer(dom, categoryRenderer); + const renderer = new Audits2.ReportRenderer(dom); const templatesHTML = Runtime.cachedResources['audits2/lighthouse/templates.html']; const templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html'); @@ -149,6 +147,7 @@ Audits2.Audits2Panel = class extends UI.Panel { renderer.setTemplateContext(templatesDOM); const el = renderer.renderReport(lighthouseResult, reportContainer); Audits2.ReportRenderer.addViewTraceButton(el, artifacts); + Audits2.ReportRenderer.linkifyNodeDetails(el); this._cachedRenderedReports.set(lighthouseResult, reportContainer); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js index 3d3e6759cc2..92ec440c3cd 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js @@ -5,7 +5,7 @@ Audits2.ProtocolService = class extends Common.Object { constructor() { super(); - /** @type {?Protocol.InspectorBackend.Connection} */ + /** @type {?Protocol.Connection} */ this._rawConnection = null; /** @type {?Services.ServiceManager.Service} */ this._backend = null; @@ -19,7 +19,7 @@ Audits2.ProtocolService = class extends Common.Object { * @return {!Promise<undefined>} */ attach() { - return InspectorMain.interceptMainConnection(this._dispatchProtocolMessage.bind(this)).then(rawConnection => { + return SDK.interceptMainConnection(this._dispatchProtocolMessage.bind(this)).then(rawConnection => { this._rawConnection = rawConnection; }); } @@ -53,7 +53,7 @@ Audits2.ProtocolService = class extends Common.Object { } /** - * @param {string} message + * @param {!Object|string} message */ _dispatchProtocolMessage(message) { this._send('dispatchProtocolMessage', {message: message}); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ReportRenderer.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ReportRenderer.js index b8752401657..24030c45944 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ReportRenderer.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ReportRenderer.js @@ -25,66 +25,44 @@ Audits2.ReportRenderer = class extends ReportRenderer { Timeline.TimelinePanel.instance().loadFromEvents(defaultPassTrace.traceEvents); } } -}; -class ReportUIFeatures { /** - * @param {!ReportRenderer.ReportJSON} report + * @param {!Element} el */ - initFeatures(report) { - } -} - - -Audits2.DetailsRenderer = class extends DetailsRenderer { - /** - * @param {!DOM} dom - */ - constructor(dom) { - super(dom); - this._onLoadPromise = null; - } - - /** - * @override - * @param {!DetailsRenderer.NodeDetailsJSON} item - * @return {!Element} - */ - renderNode(item) { - const element = super.renderNode(item); - this._replaceWithDeferredNodeBlock(element, item); - return element; - } - - /** - * @param {!Element} origElement - * @param {!DetailsRenderer.NodeDetailsJSON} detailsItem - */ - async _replaceWithDeferredNodeBlock(origElement, detailsItem) { + static async linkifyNodeDetails(el) { const mainTarget = SDK.targetManager.mainTarget(); - if (!this._onLoadPromise) { - const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel); - this._onLoadPromise = resourceTreeModel.once(SDK.ResourceTreeModel.Events.Load); - } - - await this._onLoadPromise; + const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel); + await resourceTreeModel.once(SDK.ResourceTreeModel.Events.Load); const domModel = mainTarget.model(SDK.DOMModel); - if (!detailsItem.path) - return; - const nodeId = await domModel.pushNodeByPathToFrontend(detailsItem.path); + for (const origElement of el.getElementsByClassName('lh-node')) { + /** @type {!DetailsRenderer.NodeDetailsJSON} */ + const detailsItem = origElement.dataset; + if (!detailsItem.path) + continue; - if (!nodeId) - return; - const node = domModel.nodeForId(nodeId); - if (!node) - return; + const nodeId = await domModel.pushNodeByPathToFrontend(detailsItem.path); - const element = - await Common.Linkifier.linkify(node, /** @type {!Common.Linkifier.Options} */ ({title: detailsItem.snippet})); - origElement.title = ''; - origElement.textContent = ''; - origElement.appendChild(element); + if (!nodeId) + continue; + const node = domModel.nodeForId(nodeId); + if (!node) + continue; + + const element = + await Common.Linkifier.linkify(node, /** @type {!Common.Linkifier.Options} */ ({title: detailsItem.snippet})); + origElement.title = ''; + origElement.textContent = ''; + origElement.appendChild(element); + } } }; + +class ReportUIFeatures { + /** + * @param {!ReportRenderer.ReportJSON} report + */ + initFeatures(report) { + } +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/module.json b/chromium/third_party/blink/renderer/devtools/front_end/audits2/module.json index a99df715f71..b1f07d06d19 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/module.json @@ -6,7 +6,8 @@ "id": "audits2", "title": "Audits", "order": 90, - "className": "Audits2.Audits2Panel" + "className": "Audits2.Audits2Panel", + "tags": "lighthouse, pwa" } ], "dependencies": [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2_worker/Audits2Service.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2_worker/Audits2Service.js index be445dd56db..9d0bfb1a674 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2_worker/Audits2Service.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2_worker/Audits2Service.js @@ -48,7 +48,7 @@ var Audits2Service = class { // eslint-disable-line }); return Promise.resolve() - .then(_ => self.runLighthouseInWorker(this, params.url, {flags: params.flags}, params.categoryIDs)) + .then(_ => self.runLighthouseInWorker(this, params.url, params.flags, params.categoryIDs)) .then(/** @type {!ReportRenderer.RunnerResult} */ result => { // Keep all artifacts on the result, no trimming return result; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js index 7a43e3c6881..22527be29ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js @@ -439,6 +439,10 @@ Bindings.BreakpointManager.Breakpoint = class { } _updateBreakpoint() { + if (this._uiLocations.size === 0 && this._defaultUILocation) + this._breakpointManager._uiLocationRemoved(this, this._defaultUILocation); + if (this._uiLocations.size === 0 && this._defaultUILocation && !this._isRemoved) + this._breakpointManager._uiLocationAdded(this, this._defaultUILocation); const modelBreakpoints = this._modelBreakpoints.valuesArray(); for (let i = 0; i < modelBreakpoints.length; ++i) modelBreakpoints[i]._scheduleUpdateInDebugger(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js index 846be51b0a1..44c4d83c6df 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js @@ -211,8 +211,10 @@ Bindings.CompilerScriptMapping = class { const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap); this._removeStubUISourceCode(script); - if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) + if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) { + this._sourceMapAttachedForTest(sourceMap); return; + } this._populateSourceMapSources(script, sourceMap); this._sourceMapAttachedForTest(sourceMap); @@ -228,9 +230,11 @@ Bindings.CompilerScriptMapping = class { const bindings = script.isContentScript() ? this._contentScriptsBindings : this._regularBindings; for (const sourceURL of sourceMap.sourceURLs()) { const binding = bindings.get(sourceURL); - binding.removeSourceMap(sourceMap, frameId); - if (!binding._uiSourceCode) - bindings.delete(sourceURL); + if (binding) { + binding.removeSourceMap(sourceMap, frameId); + if (!binding._uiSourceCode) + bindings.delete(sourceURL); + } } this._debuggerWorkspaceBinding.updateLocations(script); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js deleted file mode 100644 index a98df127fc4..00000000000 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @implements {Common.Renderer} - * @implements {UI.ContextMenu.Provider} - */ -BrowserConsole.BrowserConsole = class { - /** - * @override - * @param {!Event} event - * @param {!UI.ContextMenu} contextMenu - * @param {!Object} object - */ - appendApplicableItems(event, contextMenu, object) { - const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object); - const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage); - if (request && SDK.NetworkManager.canReplayRequest(request)) { - contextMenu.debugSection().appendItem( - Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request)); - } - } - - /** - * @override - * @param {!Object} object - * @param {!Common.Renderer.Options} options - * @return {!Promise.<?Node>} - */ - render(object, options) { - const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object); - const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage); - let messageElement = null; - if (request) { - messageElement = createElement('span'); - if (consoleMessage.level === SDK.ConsoleMessage.MessageLevel.Error) { - messageElement.createTextChild(request.requestMethod + ' '); - messageElement.appendChild(Components.Linkifier.linkifyRevealable(request, request.url(), request.url())); - if (request.failed) - messageElement.createTextChildren(' ', request.localizedFailDescription); - if (request.statusCode !== 0) - messageElement.createTextChildren(' ', String(request.statusCode)); - if (request.statusText) - messageElement.createTextChildren(' (', request.statusText, ')'); - } else { - const fragment = Console.ConsoleViewMessage.linkifyWithCustomLinkifier( - consoleMessage.messageText, - title => Components.Linkifier.linkifyRevealable( - /** @type {!SDK.NetworkRequest} */ (request), title, request.url())); - messageElement.appendChild(fragment); - } - } - return Promise.resolve(/** @type {?Node} */ (messageElement)); - } -}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/module.json b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/module.json deleted file mode 100644 index 7dbf71b37a0..00000000000 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/module.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extensions": [ - { - "type": "@UI.ContextMenu.Provider", - "contextTypes": [ - "SDK.ConsoleMessage" - ], - "className": "BrowserConsole.BrowserConsole" - }, - { - "type": "@Common.Renderer", - "contextTypes": [ - "SDK.ConsoleMessage" - ], - "source": "network", - "className": "BrowserConsole.BrowserConsole" - } - ], - "dependencies": [ - "browser_sdk", - "console" - ], - "scripts": [ - "BrowserConsole.js" - ] -} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/README.md b/chromium/third_party/blink/renderer/devtools/front_end/cm/README.md index 68f53037d54..cd6130f90b5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/README.md +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/README.md @@ -14,7 +14,7 @@ construction. This is needed to support in web workers. ## Testing DevTools wrap CodeMirror via `CodeMirrorTextEditor.js` and `cmdevtools.css` files. -Although there are a couple of automated tests (LayoutTests/inspector/editor/) to verify overall sanity of the setup, a manual testing is mandatory before +Although there are a couple of automated tests (web_tests/inspector/editor/) to verify overall sanity of the setup, a manual testing is mandatory before landing a roll. Here is a rough testing scenario outline: 1. Create a new snippet and type in a small function with a few nested for-loops. (The author suggests a bubble-sort). Make sure that: * Words `function`, `for`, `var` are highlighted diff --git a/chromium/third_party/blink/renderer/devtools/front_end/common/ModuleExtensionInterfaces.js b/chromium/third_party/blink/renderer/devtools/front_end/common/ModuleExtensionInterfaces.js index cdc0dd3b146..6d88d494a99 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/common/ModuleExtensionInterfaces.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/common/ModuleExtensionInterfaces.js @@ -5,37 +5,6 @@ /** * @interface */ -Common.Renderer = function() {}; - -Common.Renderer.prototype = { - /** - * @param {!Object} object - * @param {!Common.Renderer.Options} options - * @return {!Promise.<?Node>} - */ - render(object, options) {} -}; - -/** - * @param {?Object} object - * @param {!Common.Renderer.Options=} options - * @return {!Promise.<?Node>} - */ -Common.Renderer.render = function(object, options) { - if (!object) - return Promise.reject(new Error('Can\'t render ' + object)); - return self.runtime.extension(Common.Renderer, object) - .instance() - .then(renderer => renderer.render(object, options || {})); -}; - -/** @typedef {!{title: (string|!Element|undefined), expanded: (boolean|undefined), - * editable: (boolean|undefined) }} */ -Common.Renderer.Options; - -/** - * @interface - */ Common.Revealer = function() {}; /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js index ebc106c12ec..5366548b7f5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js @@ -79,6 +79,19 @@ Common.ResourceType = class { } /** + * @param {string} name + * @return {?Common.ResourceType} + */ + static fromName(name) { + for (const resourceTypeId in Common.resourceTypes) { + const resourceType = Common.resourceTypes[resourceTypeId]; + if (resourceType.name() === name) + return resourceType; + } + return null; + } + + /** * @param {string} url * @return {string|undefined} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js index 9ad19488ade..05753751de3 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js @@ -35,7 +35,7 @@ Components.JSPresentationUtils = {}; * @param {!Components.Linkifier} linkifier * @param {!Protocol.Runtime.StackTrace=} stackTrace * @param {function()=} contentUpdated - * @return {!Element} + * @return {{element: !Element, links: !Array<!Element>}} */ Components.JSPresentationUtils.buildStackTracePreviewContents = function( target, linkifier, stackTrace, contentUpdated) { @@ -44,6 +44,8 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css'); const contentElement = shadowRoot.createChild('table', 'stack-preview-container'); let totalHiddenCallFramesCount = 0; + /** @type {!Array<!Element>} */ + const links = []; /** * @param {!Protocol.Runtime.StackTrace} stackTrace @@ -65,6 +67,7 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( } row.createChild('td').textContent = ' @ '; row.createChild('td').appendChild(link); + links.push(link); } contentElement.appendChild(row); } @@ -94,7 +97,7 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( } if (!stackTrace) - return element; + return {element, links}; appendStackTrace(stackTrace); @@ -132,5 +135,5 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( }, false); } - return element; + return {element, links}; }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/Linkifier.js b/chromium/third_party/blink/renderer/devtools/front_end/components/Linkifier.js index 61f6cbf431d..c4845c3a860 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/components/Linkifier.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/Linkifier.js @@ -402,10 +402,18 @@ Components.Linkifier = class { revealable: null, fallback: null }; - if (!preventClick) - link.addEventListener('click', Components.Linkifier._handleClick, false); - else + if (!preventClick) { + link.addEventListener('click', event => { + if (Components.Linkifier._handleClick(event)) + event.consume(true); + }, false); + link.addEventListener('keydown', event => { + if (isEnterKey(event) && Components.Linkifier._handleClick(event)) + event.consume(true); + }, false); + } else { link.classList.add('devtools-link-prevent-click'); + } return link; } @@ -486,15 +494,18 @@ Components.Linkifier = class { /** * @param {!Event} event + * @return {boolean} */ static _handleClick(event) { const link = /** @type {!Element} */ (event.currentTarget); - event.consume(true); if (UI.isBeingEdited(/** @type {!Node} */ (event.target)) || link.hasSelection()) - return; + return false; const actions = Components.Linkifier._linkActions(link); - if (actions.length) + if (actions.length) { actions[0].handler.call(null); + return true; + } + return false; } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleContextSelector.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleContextSelector.js index 56afa11c4f4..6ff70fcfda7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleContextSelector.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleContextSelector.js @@ -107,13 +107,12 @@ Console.ConsoleContextSelector = class { } let targetDepth = 0; while (target.parentTarget()) { - if (target.parentTarget().hasJSCapability()) { - targetDepth++; - } else { + if (target.parentTarget().type() === SDK.Target.Type.ServiceWorker) { // Special casing service workers to be top-level. targetDepth = 0; break; } + targetDepth++; target = target.parentTarget(); } depth += targetDepth; @@ -153,7 +152,7 @@ Console.ConsoleContextSelector = class { _executionContextCreated(executionContext) { // FIXME(413886): We never want to show execution context for the main thread of shadow page in service/shared worker frontend. // This check could be removed once we do not send this context to frontend. - if (!executionContext.target().hasJSCapability()) + if (executionContext.target().type() === SDK.Target.Type.ServiceWorker) return; this._items.insertWithComparator(executionContext, executionContext.runtimeModel.executionContextComparator()); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js index 182b9780cd1..bf930bf1564 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js @@ -163,6 +163,7 @@ Console.ConsolePin = class extends Common.Object { this._editor.setText(trimmedText); this._committedExpression = trimmedText; pinPane._savePins(); + this._editor.setSelection(TextUtils.TextRange.createFromLocation(Infinity, Infinity)); }); }); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js index 08f4030a53c..ef800623754 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js @@ -20,6 +20,10 @@ Console.ConsolePrompt = class extends UI.Widget { this._innerPreviewElement = this._eagerPreviewElement.createChild('div', 'console-eager-inner-preview'); this._eagerPreviewElement.appendChild(UI.Icon.create('smallicon-command-result', 'preview-result-icon')); + const editorContainerElement = this.element.createChild('div', 'console-prompt-editor-container'); + if (this._isBelowPromptEnabled) + this.element.appendChild(this._eagerPreviewElement); + this._eagerEvalSetting = Common.settings.moduleSetting('consoleEagerEval'); this._eagerEvalSetting.addChangeListener(this._eagerSettingChanged.bind(this)); this._eagerPreviewElement.classList.toggle('hidden', !this._eagerEvalSetting.get()); @@ -50,11 +54,9 @@ Console.ConsolePrompt = class extends UI.Widget { UI.GlassPane.AnchorBehavior.PreferBottom })); this._editor.widget().element.addEventListener('keydown', this._editorKeyDown.bind(this), true); - this._editor.widget().show(this.element); + this._editor.widget().show(editorContainerElement); this._editor.addEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this); this._editor.addEventListener(UI.TextEditor.Events.SuggestionChanged, this._onTextChanged, this); - if (this._isBelowPromptEnabled) - this.element.appendChild(this._eagerPreviewElement); this.setText(this._initialText); delete this._initialText; @@ -239,6 +241,8 @@ Console.ConsolePrompt = class extends UI.Widget { event.consume(true); + // Since we prevent default, manually emulate the native "scroll on key input" behavior. + this.element.scrollIntoView(); this.clearAutocomplete(); const str = this.text(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js index 02091ddf93d..0579fff41ce 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js @@ -679,8 +679,11 @@ Console.ConsoleView = class extends UI.VBox { Common.UIString('Copy visible styled selection'), this._viewport.copyWithStyles.bind(this._viewport)); } - if (consoleMessage) - contextMenu.appendApplicableItems(consoleMessage); + if (consoleMessage) { + const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage); + if (request && SDK.NetworkManager.canReplayRequest(request)) + contextMenu.debugSection().appendItem(ls`Replay XHR`, SDK.NetworkManager.replayRequest.bind(null, request)); + } contextMenu.show(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js index 7ab961e9b90..19a988e3162 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js @@ -45,8 +45,8 @@ Console.ConsoleViewMessage = class { this._repeatCount = 1; this._closeGroupDecorationCount = 0; this._nestingLevel = nestingLevel; - /** @type {!Array<!ObjectUI.ObjectPropertiesSection>} */ - this._focusableChildren = []; + /** @type {!Array<{element: !Element, selectFirst: function()}>} */ + this._selectableChildren = []; /** @type {?DataGrid.DataGrid} */ this._dataGrid = null; @@ -68,16 +68,6 @@ Console.ConsoleViewMessage = class { } /** - * @return {!Promise<!Element>} - */ - async completeElementForTest() { - const element = this.toMessageElement(); - if (this._completeElementForTestPromise) - await this._completeElementForTestPromise; - return element; - } - - /** * @override */ wasShown() { @@ -141,7 +131,7 @@ Console.ConsoleViewMessage = class { if (table) table = this._parameterToRemoteObject(table); if (!table || !table.preview) - return formattedMessage; + return this._buildMessage(); const rawValueColumnSymbol = Symbol('rawValueColumn'); const columnNames = []; @@ -250,23 +240,9 @@ Console.ConsoleViewMessage = class { } } } else { - let rendered = false; - this._completeElementForTestPromise = null; - for (const extension of self.runtime.extensions(Common.Renderer, this._message)) { - if (extension.descriptor()['source'] === this._message.source) { - messageElement = createElement('span'); - let callback; - this._completeElementForTestPromise = new Promise(fulfill => callback = fulfill); - extension.instance().then(renderer => { - renderer.render(this._message) - .then(element => messageElement.appendChild(element || this._format([messageText]))) - .then(callback); - }); - rendered = true; - break; - } - } - if (!rendered) { + if (this._message.source === SDK.ConsoleMessage.MessageSource.Network) { + messageElement = this._formatAsNetworkRequest() || this._format([messageText]); + } else { const messageInParameters = this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]); if (this._message.source === SDK.ConsoleMessage.MessageSource.Violation) @@ -297,6 +273,40 @@ Console.ConsoleViewMessage = class { /** * @return {?Element} */ + _formatAsNetworkRequest() { + const request = SDK.NetworkLog.requestForConsoleMessage(this._message); + if (!request) + return null; + const messageElement = createElement('span'); + if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error) { + messageElement.createTextChild(request.requestMethod + ' '); + const linkElement = Components.Linkifier.linkifyRevealable(request, request.url(), request.url()); + // Focus is handled by the viewport. + linkElement.tabIndex = -1; + this._selectableChildren.push({element: linkElement, selectFirst: () => linkElement.focus()}); + messageElement.appendChild(linkElement); + if (request.failed) + messageElement.createTextChildren(' ', request.localizedFailDescription); + if (request.statusCode !== 0) + messageElement.createTextChildren(' ', String(request.statusCode)); + if (request.statusText) + messageElement.createTextChildren(' (', request.statusText, ')'); + } else { + const fragment = this._linkifyWithCustomLinkifier(this._message.messageText, title => { + const linkElement = Components.Linkifier.linkifyRevealable( + /** @type {!SDK.NetworkRequest} */ (request), title, request.url()); + linkElement.tabIndex = -1; + this._selectableChildren.push({element: linkElement, selectFirst: () => linkElement.focus()}); + return linkElement; + }); + messageElement.appendChild(fragment); + } + return messageElement; + } + + /** + * @return {?Element} + */ _buildMessageAnchor() { let anchorElement = null; if (this._message.scriptId) { @@ -380,7 +390,11 @@ Console.ConsoleViewMessage = class { const stackTraceElement = contentElement.createChild('div'); const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents( this._message.runtimeModel().target(), this._linkifier, this._message.stackTrace); - stackTraceElement.appendChild(stackTracePreview); + stackTraceElement.appendChild(stackTracePreview.element); + for (const linkElement of stackTracePreview.links) { + linkElement.tabIndex = -1; + this._selectableChildren.push({element: linkElement, selectFirst: () => linkElement.focus()}); + } stackTraceElement.classList.add('hidden'); this._expandTrace = expand => { icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right'); @@ -495,7 +509,7 @@ Console.ConsoleViewMessage = class { for (let i = 0; i < parameters.length; ++i) { // Inline strings when formatting. if (shouldFormatMessage && parameters[i].type === 'string') - formattedResult.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(parameters[i].description)); + formattedResult.appendChild(this._linkifyStringAsFragment(parameters[i].description)); else formattedResult.appendChild(this._formatParameter(parameters[i], false, true)); if (i < parameters.length - 1) @@ -610,7 +624,8 @@ Console.ConsoleViewMessage = class { const section = new ObjectUI.ObjectPropertiesSection(obj, titleElement, this._linkifier); section.element.classList.add('console-view-object-properties-section'); section.enableContextMenu(); - this._focusableChildren.push(section); + section.setShowSelectionOnKeyboardFocus(true, true); + this._selectableChildren.push(section); return section.element; } @@ -673,18 +688,20 @@ Console.ConsoleViewMessage = class { const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel); if (!domModel) return result; - domModel.pushObjectAsNodeToFrontend(remoteObject).then(node => { + domModel.pushObjectAsNodeToFrontend(remoteObject).then(async node => { if (!node) { result.appendChild(this._formatParameterAsObject(remoteObject, false)); return; } - Common.Renderer.render(node).then(rendererNode => { - if (rendererNode) - result.appendChild(rendererNode); - else - result.appendChild(this._formatParameterAsObject(remoteObject, false)); - this._formattedParameterAsNodeForTest(); - }); + const renderResult = await UI.Renderer.render(/** @type {!Object} */ (node)); + if (renderResult) { + if (renderResult.tree) + this._selectableChildren.push(renderResult.tree); + result.appendChild(renderResult.node); + } else { + result.appendChild(this._formatParameterAsObject(remoteObject, false)); + } + this._formattedParameterAsNodeForTest(); }); return result; @@ -699,7 +716,7 @@ Console.ConsoleViewMessage = class { */ _formatParameterAsString(output) { const span = createElement('span'); - span.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(output.description || '')); + span.appendChild(this._linkifyStringAsFragment(output.description || '')); const result = createElement('span'); result.createChild('span', 'object-value-string-quote').textContent = '"'; @@ -715,8 +732,7 @@ Console.ConsoleViewMessage = class { _formatParameterAsError(output) { const result = createElement('span'); const errorSpan = this._tryFormatAsError(output.description || ''); - result.appendChild( - errorSpan ? errorSpan : Console.ConsoleViewMessage._linkifyStringAsFragment(output.description || '')); + result.appendChild(errorSpan ? errorSpan : this._linkifyStringAsFragment(output.description || '')); return result; } @@ -869,13 +885,13 @@ Console.ConsoleViewMessage = class { if (typeof b === 'undefined') return a; if (!currentStyle) { - a.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(String(b))); + a.appendChild(this._linkifyStringAsFragment(String(b))); return a; } const lines = String(b).split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i]; - const lineFragment = Console.ConsoleViewMessage._linkifyStringAsFragment(line); + const lineFragment = this._linkifyStringAsFragment(line); const wrapper = createElement('span'); wrapper.style.setProperty('contain', 'paint'); wrapper.style.setProperty('display', 'inline-block'); @@ -1041,9 +1057,9 @@ Console.ConsoleViewMessage = class { * @return {number} */ _focusedChildIndex() { - if (!this._focusableChildren.length) + if (!this._selectableChildren.length) return -1; - return this._focusableChildren.findIndex(child => child.element.hasFocus()); + return this._selectableChildren.findIndex(child => child.element.hasFocus()); } /** @@ -1070,7 +1086,7 @@ Console.ConsoleViewMessage = class { return true; } } - if (!this._focusableChildren.length) + if (!this._selectableChildren.length) return false; if (event.key === 'ArrowLeft') { @@ -1078,46 +1094,63 @@ Console.ConsoleViewMessage = class { return true; } if (event.key === 'ArrowRight') { - if (isWrapperFocused) { - this._focusChild(0); + if (isWrapperFocused && this._selectNearestVisibleChild(0)) return true; - } } if (event.key === 'ArrowUp') { - if (focusedChildIndex === 0) { + const firstVisibleChild = this._nearestVisibleChild(0); + if (this._selectableChildren[focusedChildIndex] === firstVisibleChild && firstVisibleChild) { this._element.focus(); return true; - } else if (focusedChildIndex > 0) { - this._focusChild(focusedChildIndex - 1); + } else if (this._selectNearestVisibleChild(focusedChildIndex - 1, true /* backwards */)) { return true; } } if (event.key === 'ArrowDown') { - if (isWrapperFocused) { - this._focusChild(0); + if (isWrapperFocused && this._selectNearestVisibleChild(0)) return true; - } else if (focusedChildIndex < this._focusableChildren.length - 1) { - this._focusChild(focusedChildIndex + 1); + if (!isWrapperFocused && this._selectNearestVisibleChild(focusedChildIndex + 1)) return true; - } } return false; } /** - * @param {number} index + * @param {number} fromIndex + * @param {boolean=} backwards + * @return {boolean} */ - _focusChild(index) { - const section = this._focusableChildren[index]; - if (!section.objectTreeElement().selected) - section.objectTreeElement().select(); - section.focus(); + _selectNearestVisibleChild(fromIndex, backwards) { + const nearestChild = this._nearestVisibleChild(fromIndex, backwards); + if (nearestChild) { + nearestChild.selectFirst(); + return true; + } + return false; + } + + /** + * @param {number} fromIndex + * @param {boolean=} backwards + * @return {?{element: !Element, selectFirst: function()}} + */ + _nearestVisibleChild(fromIndex, backwards) { + const childCount = this._selectableChildren.length; + if (fromIndex < 0 || fromIndex >= childCount) + return null; + const direction = backwards ? -1 : 1; + let index = fromIndex; + + while (!this._selectableChildren[index].element.offsetParent) { + index += direction; + if (index < 0 || index >= childCount) + return null; + } + return this._selectableChildren[index]; } focusLastChildOrSelf() { - if (this._focusableChildren.length) - this._focusChild(this._focusableChildren.length - 1); - else if (this._element) + if (this._element && !this._selectNearestVisibleChild(this._selectableChildren.length - 1, true /* backwards */)) this._element.focus(); } @@ -1443,15 +1476,17 @@ Console.ConsoleViewMessage = class { const formattedResult = createElement('span'); let start = 0; for (let i = 0; i < links.length; ++i) { - formattedResult.appendChild( - Console.ConsoleViewMessage._linkifyStringAsFragment(string.substring(start, links[i].positionLeft))); - formattedResult.appendChild(this._linkifier.linkifyScriptLocation( - debuggerModel.target(), null, links[i].url, links[i].lineNumber, links[i].columnNumber)); + formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start, links[i].positionLeft))); + const scriptLocationLink = this._linkifier.linkifyScriptLocation( + debuggerModel.target(), null, links[i].url, links[i].lineNumber, links[i].columnNumber); + scriptLocationLink.tabIndex = -1; + this._selectableChildren.push({element: scriptLocationLink, selectFirst: () => scriptLocationLink.focus()}); + formattedResult.appendChild(scriptLocationLink); start = links[i].positionRight; } if (start !== string.length) - formattedResult.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(string.substring(start))); + formattedResult.appendChild(this._linkifyStringAsFragment(string.substring(start))); return formattedResult; @@ -1476,12 +1511,14 @@ Console.ConsoleViewMessage = class { * @param {function(string,string,number=,number=):!Node} linkifier * @return {!DocumentFragment} */ - static linkifyWithCustomLinkifier(string, linkifier) { + _linkifyWithCustomLinkifier(string, linkifier) { if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength) return UI.createExpandableText(string, Console.ConsoleViewMessage._LongStringVisibleLength); const container = createDocumentFragment(); - const tokens = this._tokenizeMessageText(string); + const tokens = Console.ConsoleViewMessage._tokenizeMessageText(string); for (const token of tokens) { + if (!token.text) + continue; switch (token.type) { case 'url': { const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text); @@ -1506,9 +1543,12 @@ Console.ConsoleViewMessage = class { * @param {string} string * @return {!DocumentFragment} */ - static _linkifyStringAsFragment(string) { - return Console.ConsoleViewMessage.linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => { - return Components.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber}); + _linkifyStringAsFragment(string) { + return this._linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => { + const linkElement = Components.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber}); + linkElement.tabIndex = -1; + this._selectableChildren.push({element: linkElement, selectFirst: () => linkElement.focus()}); + return linkElement; }); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js index f1ea217ef04..5b93a99f516 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js @@ -127,11 +127,14 @@ Console.ConsoleViewport = class { const renderedIndex = this._renderedItems.findIndex(item => item.element().isSelfOrAncestor(event.target)); if (renderedIndex !== -1) this._virtualSelectedIndex = this._firstActiveIndex + renderedIndex; + let focusLastChild = false; // Make default selection when moving from external (e.g. prompt) to the container. if (this._virtualSelectedIndex === -1 && this._isOutsideViewport(/** @type {?Element} */ (event.relatedTarget)) && - event.target === this._contentElement) + event.target === this._contentElement) { + focusLastChild = true; this._virtualSelectedIndex = this._itemCount - 1; - this._updateFocusedItem(); + } + this._updateFocusedItem(focusLastChild); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css index 58ba9435ccf..1bebaf91a5e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css @@ -88,7 +88,10 @@ clear: right; position: relative; margin: 0 22px 0 20px; - min-height: 18px; /* Sync with ConsoleViewMessage.js */ +} + +.console-prompt-editor-container { + min-height: 21px; } .console-message, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js index aea6002d6e4..d4d78c8a50e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js @@ -20,14 +20,6 @@ ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpCl ConsoleTestRunner.dumpConsoleMessagesIntoArray(printOriginatingCommand, dumpClassNames, formatter)); }; -ConsoleTestRunner.renderCompleteMessages = async function() { - const consoleView = Console.ConsoleView.instance(); - if (consoleView._needsFullUpdate) - consoleView._updateMessageList(); - const viewMessages = consoleView._visibleViewMessages; - await Promise.all(viewMessages.map(uiMessage => uiMessage.completeElementForTest())); -}; - /** * @param {boolean=} printOriginatingCommand * @param {boolean=} dumpClassNames @@ -536,7 +528,7 @@ ConsoleTestRunner.waitForConsoleMessages = function(expectedCount, callback) { */ ConsoleTestRunner.waitForConsoleMessagesPromise = async function(expectedCount) { await new Promise(fulfill => ConsoleTestRunner.waitForConsoleMessages(expectedCount, fulfill)); - return ConsoleTestRunner.renderCompleteMessages(); + return ConsoleTestRunner.waitForPendingViewportUpdates(); }; /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/coverage/coverageView.css b/chromium/third_party/blink/renderer/devtools/front_end/coverage/coverageView.css index 816ef2abd6f..7efd15d3bc9 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/coverage/coverageView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/coverage/coverageView.css @@ -11,7 +11,7 @@ .coverage-toolbar-container { display: flex; border-bottom: 1px solid #ccc; - flex: 0 0; + flex: 0 0 auto; } .coverage-toolbar { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json index 02e578e0178..40f67e9ee0d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json @@ -7,7 +7,6 @@ { "name": "accessibility", "type": "remote" }, { "name": "animation" }, { "name": "audits2" }, - { "name": "browser_console" }, { "name": "browser_debugger" }, { "name": "cookie_table" }, { "name": "devices" }, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js index 4489c397916..1319616f3ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js @@ -1166,30 +1166,34 @@ } function installBackwardsCompatibility() { - if (window.location.href.indexOf('/remote/') === -1) + const majorVersion = getRemoteMajorVersion(); + if (!majorVersion) return; - // Support for legacy (<M65) frontends. - /** @type {(!function(number, number):Element|undefined)} */ - ShadowRoot.prototype.__originalShadowRootElementFromPoint; + /** @type {!Array<string>} */ + const styleRules = []; - if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) { - ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint; - /** - * @param {number} x - * @param {number} y - * @return {Element} - */ - ShadowRoot.prototype.elementFromPoint = function(x, y) { - const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments); - if (this.host && originalResult === this.host) - return null; - return originalResult; - }; + if (majorVersion <= 66) { + /** @type {(!function(number, number):Element|undefined)} */ + ShadowRoot.prototype.__originalShadowRootElementFromPoint; + + if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) { + ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint; + /** + * @param {number} x + * @param {number} y + * @return {Element} + */ + ShadowRoot.prototype.elementFromPoint = function(x, y) { + const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments); + if (this.host && originalResult === this.host) + return null; + return originalResult; + }; + } } - // Support for legacy (<M53) frontends. - if (!window.KeyboardEvent.prototype.hasOwnProperty('keyIdentifier')) { + if (majorVersion <= 53) { Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', { /** * @return {string} @@ -1201,63 +1205,112 @@ }); } - // Support for legacy (<M50) frontends. - installObjectObserve(); + if (majorVersion <= 50) + installObjectObserve(); - /** - * @param {string} property - * @return {!CSSValue|null} - * @this {CSSStyleDeclaration} - */ - function getValue(property) { - // Note that |property| comes from another context, so we can't use === here. - // eslint-disable-next-line eqeqeq - if (property == 'padding-left') { - return /** @type {!CSSValue} */ ({ - /** - * @return {number} - * @this {!{__paddingLeft: number}} - */ - getFloatValue: function() { - return this.__paddingLeft; - }, - __paddingLeft: parseFloat(this.paddingLeft) - }); + if (majorVersion <= 45) { + /** + * @param {string} property + * @return {!CSSValue|null} + * @this {CSSStyleDeclaration} + */ + function getValue(property) { + // Note that |property| comes from another context, so we can't use === here. + // eslint-disable-next-line eqeqeq + if (property == 'padding-left') { + return /** @type {!CSSValue} */ ({ + /** + * @return {number} + * @this {!{__paddingLeft: number}} + */ + getFloatValue: function() { + return this.__paddingLeft; + }, + __paddingLeft: parseFloat(this.paddingLeft) + }); + } + throw new Error('getPropertyCSSValue is undefined'); } - throw new Error('getPropertyCSSValue is undefined'); + + window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue; + + function CSSPrimitiveValue() { + } + CSSPrimitiveValue.CSS_PX = 5; + window.CSSPrimitiveValue = CSSPrimitiveValue; } - // Support for legacy (<M41) frontends. - window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue; + if (majorVersion <= 45) + styleRules.push('* { min-width: 0; min-height: 0; }'); - function CSSPrimitiveValue() { + if (majorVersion <= 51) { + // Support for quirky border-image behavior (<M51), see: + // https://bugs.chromium.org/p/chromium/issues/detail?id=559258 + styleRules.push('.cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }'); + styleRules.push( + '.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }'); + } + if (majorVersion <= 71) { + styleRules.push( + '.coverage-toolbar-container, .animation-timeline-toolbar-container, .computed-properties { flex-basis: auto; }'); } - CSSPrimitiveValue.CSS_PX = 5; - window.CSSPrimitiveValue = CSSPrimitiveValue; - // Support for legacy (<M44) frontends. - const styleElement = window.document.createElement('style'); - styleElement.type = 'text/css'; - styleElement.textContent = 'html /deep/ * { min-width: 0; min-height: 0; }'; + if (majorVersion <= 50) + Event.prototype.deepPath = undefined; + + if (majorVersion <= 54) { + window.FileError = /** @type {!function (new: FileError) : ?} */ ({ + NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR, + ABORT_ERR: DOMException.ABORT_ERR, + INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR, + NOT_READABLE_ERR: 0 // No matching DOMException, so code will be 0. + }); + } - // Support for quirky border-image behavior (<M51), see: - // https://bugs.chromium.org/p/chromium/issues/detail?id=559258 - styleElement.textContent += - '\nhtml /deep/ .cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }'; - styleElement.textContent += - '\nhtml /deep/ .cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }'; - window.document.head.appendChild(styleElement); + installExtraStyleRules(styleRules); + } + + /** + * @return {?number} + */ + function getRemoteMajorVersion() { + try { + const remoteVersion = new URLSearchParams(window.location.href).get('remoteVersion'); + if (!remoteVersion) + return null; + const majorVersion = parseInt(remoteVersion.split('.')[0], 10); + return majorVersion; + } catch (e) { + return null; + } + } - // Support for legacy (<M49) frontends. - Event.prototype.deepPath = undefined; + /** + * @param {!Array<string>} styleRules + */ + function installExtraStyleRules(styleRules) { + if (!styleRules.length) + return; + const styleText = styleRules.join('\n'); + document.head.appendChild(createStyleElement(styleText)); + + const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot; + HTMLElement.prototype.createShadowRoot = function(...args) { + const shadowRoot = origCreateShadowRoot.call(this, ...args); + shadowRoot.appendChild(createStyleElement(styleText)); + return shadowRoot; + }; + } - // Support for legacy (<53) frontends. - window.FileError = /** @type {!function (new: FileError) : ?} */ ({ - NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR, - ABORT_ERR: DOMException.ABORT_ERR, - INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR, - NOT_READABLE_ERR: 0 // No matching DOMException, so code will be 0. - }); + /** + * @param {string} styleText + * @return {!Element} + */ + function createStyleElement(styleText) { + const style = document.createElement('style'); + style.type = 'text/css'; + style.textContent = styleText; + return style; } function windowLoaded() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/DOMPath.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/DOMPath.js index d37015d5b19..bd58374ecf5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/DOMPath.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/DOMPath.js @@ -42,6 +42,46 @@ Elements.DOMPath.cssPath = function(node, optimized) { /** * @param {!SDK.DOMNode} node + * @return {boolean} + */ +Elements.DOMPath.canGetJSPath = function(node) { + let wp = node; + while (wp) { + if (wp.ancestorShadowRoot() && wp.ancestorShadowRoot().shadowRootType() !== SDK.DOMNode.ShadowRootTypes.Open) + return false; + wp = wp.ancestorShadowHost(); + } + return true; +}; + +/** + * @param {!SDK.DOMNode} node + * @param {boolean=} optimized + * @return {string} + */ +Elements.DOMPath.jsPath = function(node, optimized) { + if (node.nodeType() !== Node.ELEMENT_NODE) + return ''; + + const path = []; + let wp = node; + while (wp) { + path.push(Elements.DOMPath.cssPath(wp, optimized)); + wp = wp.ancestorShadowHost(); + } + path.reverse(); + let result = ''; + for (let i = 0; i < path.length; ++i) { + if (i) + result += `.shadowRoot.querySelector('${path[i]}')`; + else + result += `document.querySelector('${path[i]}')`; + } + return result; +}; + +/** + * @param {!SDK.DOMNode} node * @param {boolean} optimized * @param {boolean} isTargetNode * @return {?Elements.DOMPath.Step} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js index 7ae9081d399..c29c85c3a99 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js @@ -932,14 +932,10 @@ Elements.ElementsActionDelegate = class { treeOutline.toggleEditAsHTML(node); return true; case 'elements.undo': - if (UI.isEditing()) - return false; SDK.domModelUndoStack.undo(); Elements.ElementsPanel.instance()._stylesWidget.forceUpdate(); return true; case 'elements.redo': - if (UI.isEditing()) - return false; SDK.domModelUndoStack.redo(); Elements.ElementsPanel.instance()._stylesWidget.forceUpdate(); return true; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeElement.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeElement.js index 852b49f74ff..be96605f59d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeElement.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeElement.js @@ -338,10 +338,8 @@ Elements.ElementsTreeElement = class extends UI.TreeElement { onselect(selectedByUser) { this.treeOutline.suppressRevealAndSelect = true; this.treeOutline.selectDOMNode(this._node, selectedByUser); - if (selectedByUser) { - this._node.highlight(); + if (selectedByUser) Host.userMetrics.actionTaken(Host.UserMetrics.Action.ChangeInspectedNodeInElementsPanel); - } this._createSelection(); this._createHint(); this.treeOutline.suppressRevealAndSelect = false; @@ -519,8 +517,11 @@ Elements.ElementsTreeElement = class extends UI.TreeElement { Common.UIString('Copy outerHTML'), treeOutline.performCopyOrCut.bind(treeOutline, false, this._node)); menuItem.setShortcut(createShortcut('V', modifier)); } - if (this._node.nodeType() === Node.ELEMENT_NODE) + if (this._node.nodeType() === Node.ELEMENT_NODE) { section.appendItem(Common.UIString('Copy selector'), this._copyCSSPath.bind(this)); + section.appendItem( + Common.UIString('Copy JS path'), this._copyJSPath.bind(this), !Elements.DOMPath.canGetJSPath(this._node)); + } if (!isShadowRoot) section.appendItem(Common.UIString('Copy XPath'), this._copyXPath.bind(this)); if (!isShadowRoot) { @@ -1620,6 +1621,10 @@ Elements.ElementsTreeElement = class extends UI.TreeElement { InspectorFrontendHost.copyText(Elements.DOMPath.cssPath(this._node, true)); } + _copyJSPath() { + InspectorFrontendHost.copyText(Elements.DOMPath.jsPath(this._node, true)); + } + _copyXPath() { InspectorFrontendHost.copyText(Elements.DOMPath.xPath(this._node, true)); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js index f93b5c293a8..083d3089f1c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js @@ -50,6 +50,8 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline { if (hideGutter) this._element.classList.add('elements-hide-gutter'); UI.ARIAUtils.setAccessibleName(this._element, Common.UIString('Page DOM')); + this._element.addEventListener('focusin', this._onfocusin.bind(this), false); + this._element.addEventListener('focusout', this._onfocusout.bind(this), false); this._element.addEventListener('mousedown', this._onmousedown.bind(this), false); this._element.addEventListener('mousemove', this._onmousemove.bind(this), false); this._element.addEventListener('mouseleave', this._onmouseleave.bind(this), false); @@ -541,6 +543,24 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline { }; } + /** + * @param {!Event} event + */ + _onfocusin(event) { + const listItem = event.target.enclosingNodeOrSelfWithNodeName('li'); + if (!listItem || !listItem.treeElement || !listItem.treeElement.selected) + return; + if (event.relatedTarget) + this._highlightTreeElement(/** @type {!UI.TreeElement} */ (listItem.treeElement), true /* showInfo */); + } + + /** + * @param {!Event} event + */ + _onfocusout(event) { + SDK.OverlayModel.hideDOMNodeHighlight(); + } + _onmousedown(event) { const element = this._treeElementFromEvent(event); @@ -574,16 +594,23 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline { return; this.setHoverEffect(element); + this._highlightTreeElement( + /** @type {!UI.TreeElement} */ (element), !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)); + } + /** + * @param {!UI.TreeElement} element + * @param {boolean} showInfo + */ + _highlightTreeElement(element, showInfo) { if (element instanceof Elements.ElementsTreeElement) { - element.node().domModel().overlayModel().highlightDOMNodeWithConfig( - element.node().id, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)}); + element.node().domModel().overlayModel().highlightDOMNodeWithConfig(element.node().id, {mode: 'all', showInfo}); return; } if (element instanceof Elements.ElementsTreeOutline.ShortcutTreeElement) { element.domModel().overlayModel().highlightDOMNodeWithConfig( - undefined, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)}, element.backendNodeId()); + undefined, {mode: 'all', showInfo}, element.backendNodeId()); } } @@ -1203,7 +1230,8 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline { visibleChildren.push(beforePseudoElement); if (node.childNodeCount()) { - let children = node.children(); + // Children may be stale when the outline is not wired to receive DOMModel updates. + let children = node.children() || []; if (!this._showHTMLCommentsSetting.get()) children = children.filter(n => n.nodeType() !== Node.COMMENT_NODE); visibleChildren = visibleChildren.concat(children); @@ -1532,19 +1560,19 @@ Elements.ElementsTreeOutline.UpdateRecord = class { }; /** - * @implements {Common.Renderer} + * @implements {UI.Renderer} */ Elements.ElementsTreeOutline.Renderer = class { /** * @override * @param {!Object} object - * @return {!Promise.<?Node>} + * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>} */ render(object) { return new Promise(renderPromise); /** - * @param {function(!Element)} resolve + * @param {function(!{node: !Node, tree: ?UI.TreeOutline})} resolve * @param {function(!Error)} reject */ function renderPromise(resolve, reject) { @@ -1564,13 +1592,14 @@ Elements.ElementsTreeOutline.Renderer = class { reject(new Error('Could not resolve node.')); return; } - const treeOutline = new Elements.ElementsTreeOutline(false, false, true /* hideGutter */); + const treeOutline = new Elements.ElementsTreeOutline(false, true /* selectEnabled */, true /* hideGutter */); treeOutline.rootDOMNode = node; if (!treeOutline.firstChild().isExpandable()) treeOutline._element.classList.add('single-node'); treeOutline.setVisible(true); treeOutline.element.treeElementForTest = treeOutline.firstChild(); - resolve(treeOutline.element); + treeOutline.setShowSelectionOnKeyboardFocus(true, true); + resolve({node: treeOutline.element, tree: treeOutline}); } } } @@ -1639,7 +1668,6 @@ Elements.ElementsTreeOutline.ShortcutTreeElement = class extends UI.TreeElement onselect(selectedByUser) { if (!selectedByUser) return true; - this._nodeShortcut.deferredNode.highlight(); this._nodeShortcut.deferredNode.resolve(resolved.bind(this)); /** * @param {?SDK.DOMNode} node diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylePropertyTreeElement.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylePropertyTreeElement.js index 70de8d434a7..29a567d7ce5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylePropertyTreeElement.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylePropertyTreeElement.js @@ -130,20 +130,7 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { const swatch = InlineEditor.ColorSwatch.create(); swatch.setColor(color); swatch.setFormat(Common.Color.detectColorFormat(swatch.color())); - const swatchIcon = new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch); - - /** - * @param {?SDK.CSSModel.ContrastInfo} contrastInfo - */ - function computedCallback(contrastInfo) { - swatchIcon.setContrastInfo(contrastInfo); - } - - if (Runtime.experiments.isEnabled('colorContrastRatio') && this.property.name === 'color' && - this._parentPane.cssModel() && this.node()) { - const cssModel = this._parentPane.cssModel(); - cssModel.backgroundColorsPromise(this.node().id).then(computedCallback); - } + this._addColorContrastInfo(new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch)); return swatch; } @@ -175,11 +162,23 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { swatch.setColor(color); swatch.setFormat(Common.Color.detectColorFormat(swatch.color())); swatch.setText(text, computedValue); - new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch); + this._addColorContrastInfo(new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch)); return swatch; } /** + * @param {!Elements.ColorSwatchPopoverIcon} swatchIcon + */ + async _addColorContrastInfo(swatchIcon) { + if (!Runtime.experiments.isEnabled('colorContrastRatio') || this.property.name !== 'color' || + !this._parentPane.cssModel() || !this.node()) + return; + const cssModel = this._parentPane.cssModel(); + const contrastInfo = await cssModel.backgroundColorsPromise(this.node().id); + swatchIcon.setContrastInfo(contrastInfo); + } + + /** * @return {string} */ renderedPropertyText() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css b/chromium/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css index 6e254e769d8..775a2cc3144 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css @@ -34,7 +34,7 @@ white-space: pre; } -.elements-disclosure li.selected .selected-hint:before { +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected .selected-hint:before { opacity: 0.6; color: var(--selection-inactive-fg-color); } @@ -91,13 +91,21 @@ .elements-disclosure li.selected .selection { display: block; +} + +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) .selection { background-color: var(--selection-inactive-bg-color); } +.elements-disclosure .elements-tree-outline.hide-selection-when-blurred li.selected:focus[data-keyboard-focus="true"] .selection { + background: rgba(0, 0, 0, 0.08); + border-radius: 2px; +} + .elements-disclosure ol { list-style-type: none; /** Keep it in sync with ElementsTreeElements.updateDecorators **/ - -webkit-padding-start: 12px; + padding-inline-start: 12px; margin: 0; } @@ -122,19 +130,19 @@ padding-left: 2px; } -.elements-disclosure ol li.selected:focus { +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus { color: var(--selection-fg-color); } -.elements-disclosure ol li.parent.selected:focus::before { +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.parent.selected:focus::before { background-color: var(--selection-fg-color); } -.elements-disclosure ol li.selected:focus * { +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus * { color: inherit; } -.elements-disclosure ol li.selected:focus .selection { +.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .selection { background-color: var(--selection-bg-color); } @@ -299,10 +307,10 @@ ol:hover > li > .elements-tree-shortcut-link { display: none; } -ol li.selected:focus .webkit-html-tag-name, -ol li.selected:focus .webkit-html-close-tag-name, -ol li.selected:focus .webkit-html-attribute-value, -ol li.selected:focus .devtools-link { +.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-tag-name, +.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-close-tag-name, +.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-attribute-value, +.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .devtools-link { color: var(--selection-fg-color); } @@ -339,7 +347,7 @@ li.selected { li.hovered:not(.always-parent) + ol.children, .elements-tree-outline ol.shadow-root, li.selected:not(.always-parent) + ol.children { margin-left: 5px; - -webkit-padding-start: 6px; + padding-inline-start: 6px; border-width: 1px; border-left-style: solid; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json index 6cffd5fed7f..d4996e0def5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json @@ -18,7 +18,7 @@ "className": "Elements.ElementsPanel.ContextMenuProvider" }, { - "type": "@Common.Renderer", + "type": "@UI.Renderer", "contextTypes": [ "SDK.DOMNode", "SDK.DeferredDOMNode" diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/stylesSectionTree.css b/chromium/third_party/blink/renderer/devtools/front_end/elements/stylesSectionTree.css index 43bd7e06d37..b80c7fe3235 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/stylesSectionTree.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/stylesSectionTree.css @@ -89,7 +89,7 @@ ol:not(.tree-outline) { display: none; margin: 0; - -webkit-padding-start: 12px; + padding-inline-start: 12px; list-style: none; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements_test_runner/ElementsTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/elements_test_runner/ElementsTestRunner.js index 762563e96a6..7195398b961 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements_test_runner/ElementsTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements_test_runner/ElementsTestRunner.js @@ -93,6 +93,14 @@ ElementsTestRunner.findNode = async function(matchFunction, callback) { }; /** + * @param {function(!Element): boolean} matchFunction + * @param {!Promise} + */ +ElementsTestRunner.findNodePromise = function(matchFunction) { + return new Promise(resolve => ElementsTestRunner.findNode(matchFunction, resolve)); +}; + +/** * @param {!EventListeners.EventListenersView} eventListenersView * @param {function():void} callback * @param {boolean=} force diff --git a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js index 1f1a885b4ce..fa58d122a76 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js @@ -277,15 +277,15 @@ Extensions.ExtensionSidebarPane = class extends UI.SimpleView { return; } this._objectPropertiesView.element.removeChildren(); - Common.Renderer - .render(object, { - title: title, - expanded: true, - editable: false, - }) - .then(element => { - this._objectPropertiesView.element.appendChild(element); - callback(); - }); + UI.Renderer.render(object, {title, editable: false}).then(result => { + if (!result) { + callback(); + return; + } + if (result.tree && result.tree.firstChild()) + result.tree.firstChild().expand(); + this._objectPropertiesView.element.appendChild(result.node); + callback(); + }); } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js index 14cf5cd5e33..07a39899227 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARFormat.js @@ -163,6 +163,7 @@ HARImporter.HAREntry = class extends HARImporter.HARBase { if (data['_initiator']) this._initiator = new HARImporter.HARInitiator(data['_initiator']); this._priority = HARImporter.HARBase._optionalString(data['_priority']); + this._resourceType = HARImporter.HARBase._optionalString(data['_resourceType']); } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js index 081ac1a7bc0..aa982f445b7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js @@ -116,12 +116,7 @@ HARImporter.Importer = class { // Meta data. request.setRemoteAddress(entry.serverIPAddress || '', 80); // Har does not support port numbers. - let resourceType = (pageLoad && pageLoad.mainRequest === request) ? - Common.resourceTypes.Document : - Common.ResourceType.fromMimeType(entry.response.content.mimeType); - if (!resourceType) - resourceType = Common.ResourceType.fromURL(entry.request.url) || Common.resourceTypes.Other; - request.setResourceType(resourceType); + request.setResourceType(HARImporter.Importer._getResourceType(request, entry, pageLoad)); const priority = entry.customAsString('priority'); if (Protocol.Network.ResourcePriority.hasOwnProperty(priority)) @@ -132,6 +127,34 @@ HARImporter.Importer = class { /** * @param {!SDK.NetworkRequest} request + * @param {!HARImporter.HAREntry} entry + * @param {?SDK.NetworkLog.PageLoad} pageLoad + * @return {!Common.ResourceType} + */ + static _getResourceType(request, entry, pageLoad) { + const customResourceTypeName = entry.customAsString('resourceType'); + if (customResourceTypeName) { + const customResourceType = Common.ResourceType.fromName(customResourceTypeName); + if (customResourceType) + return customResourceType; + } + + if (pageLoad && pageLoad.mainRequest === request) + return Common.resourceTypes.Document; + + const resourceTypeFromMime = Common.ResourceType.fromMimeType(entry.response.content.mimeType); + if (resourceTypeFromMime !== Common.resourceTypes.Other) + return resourceTypeFromMime; + + const resourceTypeFromUrl = Common.ResourceType.fromURL(entry.request.url); + if (resourceTypeFromUrl) + return resourceTypeFromUrl; + + return Common.resourceTypes.Other; + } + + /** + * @param {!SDK.NetworkRequest} request * @param {number} issueTime * @param {number} entryTotalDuration * @param {!HARImporter.HARTimings} timings diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js index ba2379884cf..91193f4f3cd 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js @@ -716,9 +716,9 @@ HeapProfilerTestRunner._profileViewRefresh = function() { HeapProfilerTestRunner.startSamplingHeapProfiler = async function() { if (!UI.context.flavor(SDK.HeapProfilerModel)) await new Promise(resolve => UI.context.addFlavorChangeListener(SDK.HeapProfilerModel, resolve)); - Profiler.SamplingHeapProfileType.instance.startRecordingProfile(); + Profiler.SamplingHeapProfileType.instance._startRecordingProfile(); }; HeapProfilerTestRunner.stopSamplingHeapProfiler = function() { - Profiler.SamplingHeapProfileType.instance.stopRecordingProfile(); + Profiler.SamplingHeapProfileType.instance._stopRecordingProfile(); }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js index 8c67f784b0e..eda95dc235d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js @@ -1282,18 +1282,6 @@ HeapSnapshotWorker.HeapSnapshot = class { } /** - * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action - * @param {boolean=} userRootsOnly - */ - forEachRoot(action, userRootsOnly) { - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { - const node = iter.edge.node(); - if (!userRootsOnly || this.isUserRoot(node)) - action(node); - } - } - - /** * @param {function(!HeapSnapshotWorker.HeapSnapshotNode,!HeapSnapshotWorker.HeapSnapshotEdge):boolean=} filter */ calculateDistances(filter) { @@ -1306,24 +1294,20 @@ HeapSnapshotWorker.HeapSnapshot = class { const nodesToVisit = new Uint32Array(this.nodeCount); let nodesToVisitLength = 0; - /** - * @param {number} distance - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - */ - function enqueueNode(distance, node) { - const ordinal = node.ordinal(); - if (distances[ordinal] !== noDistance) - return; - distances[ordinal] = distance; - nodesToVisit[nodesToVisitLength++] = node.nodeIndex; + // BFS for user root objects. + for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { + const node = iter.edge.node(); + if (this.isUserRoot(node)) { + distances[node.ordinal()] = 1; + nodesToVisit[nodesToVisitLength++] = node.nodeIndex; + } } - - this.forEachRoot(enqueueNode.bind(null, 1), true); this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); - // bfs for the rest of objects - nodesToVisitLength = 0; - this.forEachRoot(enqueueNode.bind(null, HeapSnapshotModel.baseSystemDistance), false); + // BFS for objects not reached from user roots. + distances[this.rootNode().ordinal()] = HeapSnapshotModel.baseSystemDistance; + nodesToVisit[0] = this.rootNode().nodeIndex; + nodesToVisitLength = 1; this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); } @@ -2583,60 +2567,6 @@ HeapSnapshotWorker.JSHeapSnapshot = class extends HeapSnapshotWorker.HeapSnapsho /** * @override - * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action - * @param {boolean=} userRootsOnly - */ - forEachRoot(action, userRootsOnly) { - /** - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - * @param {string} name - * @return {?HeapSnapshotWorker.HeapSnapshotNode} - */ - function getChildNodeByName(node, name) { - for (let iter = node.edges(); iter.hasNext(); iter.next()) { - const child = iter.edge.node(); - if (child.name() === name) - return child; - } - return null; - } - - const visitedNodes = {}; - /** - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - */ - function doAction(node) { - const ordinal = node.ordinal(); - if (!visitedNodes[ordinal]) { - action(node); - visitedNodes[ordinal] = true; - } - } - - const gcRoots = getChildNodeByName(this.rootNode(), '(GC roots)'); - if (!gcRoots) - return; - - if (userRootsOnly) { - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { - const node = iter.edge.node(); - if (this.isUserRoot(node)) - doAction(node); - } - } else { - for (let iter = gcRoots.edges(); iter.hasNext(); iter.next()) { - const subRoot = iter.edge.node(); - for (let iter2 = subRoot.edges(); iter2.hasNext(); iter2.next()) - doAction(iter2.edge.node()); - doAction(subRoot); - } - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) - doAction(iter.edge.node()); - } - } - - /** - * @override * @return {?{map: !Uint32Array, flag: number}} */ userObjectsMapAndFlag() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js index 4b043754231..9e9640e0d03 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js @@ -13,6 +13,36 @@ const commandMenuShortcut = Host.isMac() ? 'Command + Shift + P' : 'Control + Sh /** @type {!Array<!Help.ReleaseNote>} */ Help.releaseNoteText = [ { + version: 14, + header: 'Highlights from the Chrome 72 update', + highlights: [ + { + title: 'Visualize performance metrics', + subtitle: + 'Performance metrics like DOMContentLoaded and First Meaningful Paint are now marked in the Timings section of the Performance panel.', + link: 'https://developers.google.com/web/updates/2018/11/devtools#metrics', + }, + { + title: 'Highlight text nodes', + subtitle: 'Hover over a text node in the DOM Tree to highlight it in the viewport.', + link: 'https://developers.google.com/web/updates/2018/11/devtools#highlight', + }, + { + title: 'Copy JS path', + subtitle: + 'Right-click a DOM node and select "Copy" > "Copy JS path" to quickly get a JavaScript expression that points to that node.', + link: 'https://developers.google.com/web/updates/2018/11/devtools#copy', + }, + { + title: 'Audits panel updates', + subtitle: + 'A new audit that lists detected JS libraries and new keywords for accessing the Audits panel from the Command Menu.', + link: 'https://developers.google.com/web/updates/2018/11/devtools#audits', + }, + ], + link: 'https://developers.google.com/web/updates/2018/11/devtools', + }, + { version: 13, header: 'Highlights from the Chrome 71 update', highlights: [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/host/UserMetrics.js b/chromium/third_party/blink/renderer/devtools/front_end/host/UserMetrics.js index f9e71dddf44..622a509a7cb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/host/UserMetrics.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/host/UserMetrics.js @@ -95,6 +95,7 @@ Host.UserMetrics.Action = { Audits2Finished: 30, ShowedThirdPartyBadges: 31, Audits2ViewTrace: 32, + FilmStripStartedRecording: 33, }; Host.UserMetrics._PanelCodes = { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js index 4666c816957..7f8e3a0011d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js @@ -6,18 +6,15 @@ * @implements {Common.Runnable} */ InspectorMain.InspectorMain = class extends Common.Object { - constructor() { - super(); - /** @type {!Protocol.InspectorBackend.Connection} */ - this._mainConnection; - } - /** * @override */ run() { - this._connectAndCreateMainTarget(); - InspectorFrontendHost.connectionReady(); + SDK.initMainConnection(() => { + const type = Runtime.queryParam('v8only') ? SDK.Target.Type.Node : SDK.Target.Type.Frame; + const target = SDK.targetManager.createTarget('main', Common.UIString('Main'), type, null); + target.runtimeAgent().runIfWaitingForDebugger(); + }, Components.TargetDetachedDialog.webSocketConnectionLost); new InspectorMain.InspectedNodeRevealer(); new InspectorMain.SourcesPanelIndicator(); @@ -29,54 +26,6 @@ InspectorMain.InspectorMain = class extends Common.Object { SDK.ResourceTreeModel.reloadAllPages(hard); }); } - - _connectAndCreateMainTarget() { - const isNodeJS = !!Runtime.queryParam('v8only'); - const target = SDK.targetManager.createTarget( - 'main', Common.UIString('Main'), this._capabilitiesForMainTarget(), this._createMainConnection.bind(this), null, - isNodeJS); - target.runtimeAgent().runIfWaitingForDebugger(); - } - - /** - * @return {number} - */ - _capabilitiesForMainTarget() { - if (Runtime.queryParam('v8only')) - return SDK.Target.Capability.JS; - return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.DeviceEmulation | - SDK.Target.Capability.Emulation | SDK.Target.Capability.Input | SDK.Target.Capability.JS | - SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.ScreenCapture | - SDK.Target.Capability.Security | SDK.Target.Capability.Target | SDK.Target.Capability.Tracing | - SDK.Target.Capability.Inspector; - } - - /** - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createMainConnection(params) { - this._mainConnection = - SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost()); - return this._mainConnection; - } - - /** - * @param {function(string)} onMessage - * @return {!Promise<!Protocol.InspectorBackend.Connection>} - */ - _interceptMainConnection(onMessage) { - const params = {onMessage: onMessage, onDisconnect: this._connectAndCreateMainTarget.bind(this)}; - return this._mainConnection.disconnect().then(this._createMainConnection.bind(this, params)); - } -}; - -/** - * @param {function(string)} onMessage - * @return {!Promise<!Protocol.InspectorBackend.Connection>} - */ -InspectorMain.interceptMainConnection = function(onMessage) { - return self.runtime.sharedInstance(InspectorMain.InspectorMain)._interceptMainConnection(onMessage); }; /** @@ -211,14 +160,14 @@ InspectorMain.BackendSettingsSync = class { this._emulatePageFocusSetting = Common.settings.moduleSetting('emulatePageFocus'); this._emulatePageFocusSetting.addChangeListener(this._update, this); - SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser); + SDK.targetManager.observeTargets(this); } /** * @param {!SDK.Target} target */ _updateTarget(target) { - if (target.parentTarget()) + if (target.type() !== SDK.Target.Type.Frame || target.parentTarget()) return; target.pageAgent().setAdBlockingEnabled(this._adBlockEnabledSetting.get()); target.emulationAgent().setFocusEmulationEnabled(this._emulatePageFocusSetting.get()); @@ -229,7 +178,8 @@ InspectorMain.BackendSettingsSync = class { } _update() { - SDK.targetManager.targets(SDK.Target.Capability.Browser).forEach(this._updateTarget, this); + for (const target of SDK.targetManager.targets()) + this._updateTarget(target); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RenderingOptions.js b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RenderingOptions.js index 5e7700f0c86..4ccb6721c34 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RenderingOptions.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RenderingOptions.js @@ -49,6 +49,9 @@ InspectorMain.RenderingOptionsView = class extends UI.VBox { Common.UIString( 'Highlights elements (teal) that can slow down scrolling, including touch & wheel event handlers and other main-thread scrolling situations.'), Common.moduleSetting('showScrollBottleneckRects')); + this._appendCheckbox( + Common.UIString('Hit-test borders'), Common.UIString('Shows borders around hit-test regions'), + Common.moduleSetting('showHitTestBorders')); this.contentElement.createChild('div').classList.add('panel-section-separator'); const mediaSetting = Common.moduleSetting('emulatedCSSMedia'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RequestAppBannerActionDelegate.js b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RequestAppBannerActionDelegate.js index 87925840567..9dc8491bba6 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RequestAppBannerActionDelegate.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/RequestAppBannerActionDelegate.js @@ -14,7 +14,7 @@ InspectorMain.RequestAppBannerActionDelegate = class { */ handleAction(context, actionId) { const target = SDK.targetManager.mainTarget(); - if (target && target.hasBrowserCapability()) { + if (target && target.type() === SDK.Target.Type.Frame) { target.pageAgent().requestAppBanner(); Common.console.show(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/js_main/JsMain.js b/chromium/third_party/blink/renderer/devtools/front_end/js_main/JsMain.js index 59a109da113..4aef7186d81 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/js_main/JsMain.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/js_main/JsMain.js @@ -11,17 +11,9 @@ JsMain.JsMain = class extends Common.Object { */ run() { Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSDirectly); - const target = SDK.targetManager.createTarget( - 'main', Common.UIString('Main'), SDK.Target.Capability.JS, this._createMainConnection.bind(this), null, true /* isNodeJS */); - target.runtimeAgent().runIfWaitingForDebugger(); - InspectorFrontendHost.connectionReady(); - } - - /** - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createMainConnection(params) { - return SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost()); + SDK.initMainConnection(() => { + const target = SDK.targetManager.createTarget('main', ls`Main`, SDK.Target.Type.Node, null); + target.runtimeAgent().runIfWaitingForDebugger(); + }, Components.TargetDetachedDialog.webSocketConnectionLost); } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/layer_viewer/layerDetailsView.css b/chromium/third_party/blink/renderer/devtools/front_end/layer_viewer/layerDetailsView.css index a36c0e464dc..2e620dd7196 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/layer_viewer/layerDetailsView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/layer_viewer/layerDetailsView.css @@ -18,9 +18,9 @@ table td:first-child { ul { list-style: none; - -webkit-padding-start: 0; - -webkit-margin-before: 0; - -webkit-margin-after: 0; + padding-inline-start: 0; + margin-block-start: 0; + margin-block-end: 0; } a { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/ExecutionContextSelector.js b/chromium/third_party/blink/renderer/devtools/front_end/main/ExecutionContextSelector.js index 52740f0f283..30e04f1af74 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/main/ExecutionContextSelector.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/main/ExecutionContextSelector.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** - * @implements {SDK.TargetManager.Observer} + * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>} * @unrestricted */ Main.ExecutionContextSelector = class { @@ -11,7 +11,6 @@ Main.ExecutionContextSelector = class { * @param {!UI.Context} context */ constructor(targetManager, context) { - targetManager.observeTargets(this, SDK.Target.Capability.JS); context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this); context.addFlavorChangeListener(SDK.Target, this._targetChanged, this); @@ -24,13 +23,14 @@ Main.ExecutionContextSelector = class { this); this._targetManager = targetManager; this._context = context; + targetManager.observeModels(SDK.RuntimeModel, this); } /** * @override - * @param {!SDK.Target} target + * @param {!SDK.RuntimeModel} runtimeModel */ - targetAdded(target) { + modelAdded(runtimeModel) { // Defer selecting default target since we need all clients to get their // targetAdded notifications first. setImmediate(deferred.bind(this)); @@ -41,22 +41,22 @@ Main.ExecutionContextSelector = class { function deferred() { // We always want the second context for the service worker targets. if (!this._context.flavor(SDK.Target)) - this._context.setFlavor(SDK.Target, target); + this._context.setFlavor(SDK.Target, runtimeModel.target()); } } /** * @override - * @param {!SDK.Target} target + * @param {!SDK.RuntimeModel} runtimeModel */ - targetRemoved(target) { + modelRemoved(runtimeModel) { const currentExecutionContext = this._context.flavor(SDK.ExecutionContext); - if (currentExecutionContext && currentExecutionContext.target() === target) + if (currentExecutionContext && currentExecutionContext.runtimeModel === runtimeModel) this._currentExecutionContextGone(); - const targets = this._targetManager.targets(SDK.Target.Capability.JS); - if (this._context.flavor(SDK.Target) === target && targets.length) - this._context.setFlavor(SDK.Target, targets[0]); + const models = this._targetManager.models(SDK.RuntimeModel); + if (this._context.flavor(SDK.Target) === runtimeModel.target() && models.length) + this._context.setFlavor(SDK.Target, models[0].target()); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js index 7b3c363f4e2..d22ecf4e2da 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js @@ -60,7 +60,7 @@ Main.Main = class { async _loaded() { console.timeStamp('Main._loaded'); - await Runtime.runtimeReady(); + await Runtime.appStarted(); Runtime.setPlatform(Host.platform()); InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this)); } @@ -117,6 +117,7 @@ Main.Main = class { Runtime.experiments.register('oopifInlineDOM', 'OOPIF: inline DOM ', true); Runtime.experiments.register('pinnedExpressions', 'Pinned expressions in Console', true); Runtime.experiments.register('protocolMonitor', 'Protocol Monitor'); + Runtime.experiments.register('samplingHeapProfilerTimeline', 'Sampling heap profiler timeline', true); Runtime.experiments.register('sourceDiff', 'Source diff'); Runtime.experiments.register('sourcesPrettyPrint', 'Automatically pretty print in the Sources Panel'); Runtime.experiments.register( @@ -128,7 +129,6 @@ Main.Main = class { Runtime.experiments.register('timelineEventInitiators', 'Timeline: event initiators'); Runtime.experiments.register('timelineFlowEvents', 'Timeline: flow events', true); Runtime.experiments.register('timelineInvalidationTracking', 'Timeline: invalidation tracking', true); - Runtime.experiments.register('timelinePaintTimingMarkers', 'Timeline: paint timing markers', true); Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true); Runtime.experiments.register('timelineTracingJSProfile', 'Timeline: tracing based JS profiler', true); Runtime.experiments.register('timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true); @@ -560,7 +560,7 @@ Main.Main.MainMenuItem = class { } if (Components.dockController.dockSide() === Components.DockController.State.Undocked && - SDK.targetManager.mainTarget() && SDK.targetManager.mainTarget().hasBrowserCapability()) + SDK.targetManager.mainTarget() && SDK.targetManager.mainTarget().type() === SDK.Target.Type.Frame) contextMenu.defaultSection().appendAction('inspector_main.focus-debuggee', Common.UIString('Focus debuggee')); contextMenu.defaultSection().appendAction( @@ -614,7 +614,7 @@ Main.Main.PauseListener = class { */ Main.sendOverProtocol = function(method, params) { return new Promise((resolve, reject) => { - Protocol.InspectorBackend.sendRawMessageForTesting(method, params, (err, ...results) => { + Protocol.test.sendRawMessage(method, params, (err, ...results) => { if (err) return reject(err); return resolve(results); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkItemView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkItemView.js index 37dd4d477f0..fce1e91853f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkItemView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkItemView.js @@ -40,13 +40,17 @@ Network.NetworkItemView = class extends UI.TabbedPane { this._resourceViewTabSetting = Common.settings.createSetting('resourceViewTab', 'preview'); this._headersView = new Network.RequestHeadersView(request); - this.appendTab(Network.NetworkItemView.Tabs.Headers, Common.UIString('Headers'), this._headersView); + this.appendTab( + Network.NetworkItemView.Tabs.Headers, Common.UIString('Headers'), this._headersView, + Common.UIString('Headers and request body')); this.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this); if (request.resourceType() === Common.resourceTypes.WebSocket) { const frameView = new Network.ResourceWebSocketFrameView(request); - this.appendTab(Network.NetworkItemView.Tabs.WsFrames, Common.UIString('Frames'), frameView); + this.appendTab( + Network.NetworkItemView.Tabs.WsFrames, Common.UIString('Frames'), frameView, + Common.UIString('WebSocket frames')); } else if (request.mimeType === 'text/event-stream') { this.appendTab( Network.NetworkItemView.Tabs.EventSource, Common.UIString('EventStream'), @@ -54,24 +58,30 @@ Network.NetworkItemView = class extends UI.TabbedPane { } else { this._responseView = new Network.RequestResponseView(request); const previewView = new Network.RequestPreviewView(request); - this.appendTab(Network.NetworkItemView.Tabs.Preview, Common.UIString('Preview'), previewView); + this.appendTab( + Network.NetworkItemView.Tabs.Preview, Common.UIString('Preview'), previewView, + Common.UIString('Response preview')); if (request.signedExchangeInfo() && request.signedExchangeInfo().errors && request.signedExchangeInfo().errors.length) { const icon = UI.Icon.create('smallicon-error'); icon.title = Common.UIString('SignedExchange error'); this.setTabIcon(Network.NetworkItemView.Tabs.Preview, icon); } - this.appendTab(Network.NetworkItemView.Tabs.Response, Common.UIString('Response'), this._responseView); + this.appendTab( + Network.NetworkItemView.Tabs.Response, Common.UIString('Response'), this._responseView, + Common.UIString('Raw response data')); } if (request.requestCookies || request.responseCookies) { this._cookiesView = new Network.RequestCookiesView(request); - this.appendTab(Network.NetworkItemView.Tabs.Cookies, Common.UIString('Cookies'), this._cookiesView); + this.appendTab( + Network.NetworkItemView.Tabs.Cookies, Common.UIString('Cookies'), this._cookiesView, + Common.UIString('Request and response cookies')); } this.appendTab( Network.NetworkItemView.Tabs.Timing, Common.UIString('Timing'), - new Network.RequestTimingView(request, calculator)); + new Network.RequestTimingView(request, calculator), Common.UIString('Request and response timeline')); this._request = request; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js index 5c804456216..20a28059eab 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js @@ -592,20 +592,31 @@ Network.NetworkLogView = class extends UI.VBox { this._hideRecordingHint(); this._recordingHint = this.element.createChild('div', 'network-status-pane fill'); const hintText = this._recordingHint.createChild('div', 'recording-hint'); - const reloadShortcutNode = this._recordingHint.createChild('b'); - reloadShortcutNode.textContent = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0].name; + + let reloadShortcutNode = null; + const reloadShortcutDescriptor = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0]; + if (reloadShortcutDescriptor) { + reloadShortcutNode = this._recordingHint.createChild('b'); + reloadShortcutNode.textContent = reloadShortcutDescriptor.name; + } if (this._recording) { const recordingText = hintText.createChild('span'); recordingText.textContent = Common.UIString('Recording network activity\u2026'); - hintText.createChild('br'); - hintText.appendChild( - UI.formatLocalized('Perform a request or hit %s to record the reload.', [reloadShortcutNode])); + if (reloadShortcutNode) { + hintText.createChild('br'); + hintText.appendChild( + UI.formatLocalized('Perform a request or hit %s to record the reload.', [reloadShortcutNode])); + } } else { const recordNode = hintText.createChild('b'); recordNode.textContent = UI.shortcutRegistry.shortcutTitleForAction('network.toggle-recording'); - hintText.appendChild(UI.formatLocalized( - 'Record (%s) or reload (%s) to display network activity.', [recordNode, reloadShortcutNode])); + if (reloadShortcutNode) { + hintText.appendChild(UI.formatLocalized( + 'Record (%s) or reload (%s) to display network activity.', [recordNode, reloadShortcutNode])); + } else { + hintText.appendChild(UI.formatLocalized('Record (%s) to display network activity.', [recordNode])); + } } } @@ -747,14 +758,14 @@ Network.NetworkLogView = class extends UI.VBox { appendChunk(Common.UIString('Finish: %s', Number.secondsToString(maxTime - baseTime))); if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) { appendChunk(separator); - const domContentLoadedText = Common.UIString( - 'DOMContentLoaded: %s', Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)); - appendChunk(domContentLoadedText).classList.add('summary-blue'); + const domContentLoadedText = + ls`DOMContentLoaded: ${Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)}`; + appendChunk(domContentLoadedText).classList.add('summary-dcl-event'); } if (this._mainRequestLoadTime !== -1) { appendChunk(separator); - const loadText = Common.UIString('Load: %s', Number.secondsToString(this._mainRequestLoadTime - baseTime)); - appendChunk(loadText).classList.add('summary-red'); + const loadText = ls`Load: ${Number.secondsToString(this._mainRequestLoadTime - baseTime)}`; + appendChunk(loadText).classList.add('summary-load-event'); } } summaryBar.title = text; @@ -849,7 +860,7 @@ Network.NetworkLogView = class extends UI.VBox { const time = /** @type {number} */ (event.data.loadTime); if (time) { this._mainRequestLoadTime = time; - this._columns.addEventDividers([time], 'network-red-divider'); + this._columns.addEventDividers([time], 'network-load-divider'); } } @@ -862,7 +873,7 @@ Network.NetworkLogView = class extends UI.VBox { const data = /** @type {number} */ (event.data); if (data) { this._mainRequestDOMContentLoadedTime = data; - this._columns.addEventDividers([data], 'network-blue-divider'); + this._columns.addEventDividers([data], 'network-dcl-divider'); } } @@ -1174,7 +1185,7 @@ Network.NetworkLogView = class extends UI.VBox { } footerSection.appendItem(Common.UIString('Copy all as HAR'), this._copyAll.bind(this)); - contextMenu.saveSection().appendItem(Common.UIString('Save as HAR with content'), this._exportAll.bind(this)); + contextMenu.saveSection().appendItem(Common.UIString('Save all as HAR with content'), this._exportAll.bind(this)); contextMenu.editSection().appendItem(Common.UIString('Clear browser cache'), this._clearBrowserCache.bind(this)); contextMenu.editSection().appendItem( diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js index 4f2d5ba67dd..938940e45c5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js @@ -549,7 +549,7 @@ Network.NetworkLogViewColumns = class { const content = Components.JSPresentationUtils.buildStackTracePreviewContents( manager ? manager.target() : null, this._popupLinkifier, initiator.stack, () => popover.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent)); - popover.contentElement.appendChild(content); + popover.contentElement.appendChild(content.element); return Promise.resolve(true); }, hide: this._popupLinkifier.reset.bind(this._popupLinkifier) @@ -564,11 +564,11 @@ Network.NetworkLogViewColumns = class { // TODO(allada) Remove this and pass in the color. let color = 'transparent'; switch (className) { - case 'network-blue-divider': - color = 'hsla(240, 100%, 80%, 0.7)'; + case 'network-dcl-divider': + color = '#0867CB'; break; - case 'network-red-divider': - color = 'rgba(255, 0, 0, 0.5)'; + case 'network-load-divider': + color = '#B31412'; break; default: return; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js index 0c9f5ca0705..bcaad0e5ba4 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js @@ -242,7 +242,7 @@ Network.NetworkOverview = class extends PerfUI.TimelineOverviewBase { const height = this.element.offsetHeight; context.lineWidth = 1; context.beginPath(); - context.strokeStyle = '#8080FF'; // Keep in sync with .network-blue-divider CSS rule. + context.strokeStyle = '#0867CB'; // Keep in sync with .summary-dcl-event CSS rule. for (let i = this._domContentLoadedEvents.length - 1; i >= 0; --i) { const x = Math.round(calculator.computePosition(this._domContentLoadedEvents[i])) + 0.5; context.moveTo(x, 0); @@ -251,7 +251,7 @@ Network.NetworkOverview = class extends PerfUI.TimelineOverviewBase { context.stroke(); context.beginPath(); - context.strokeStyle = '#FF8080'; // Keep in sync with .network-red-divider CSS rule. + context.strokeStyle = '#B31412'; // Keep in sync with .summary-load-event CSS rule. for (let i = this._loadEvents.length - 1; i >= 0; --i) { const x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5; context.moveTo(x, 0); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js index 06013d284b8..03ead615c26 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js @@ -368,10 +368,13 @@ Network.NetworkPanel = class extends UI.Panel { } _resetFilmStripView() { + const reloadShortcutDescriptor = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0]; + this._filmStripView.reset(); - this._filmStripView.setStatusText(Common.UIString( - 'Hit %s to reload and capture filmstrip.', - UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0].name)); + if (reloadShortcutDescriptor) { + this._filmStripView.setStatusText( + Common.UIString('Hit %s to reload and capture filmstrip.', reloadShortcutDescriptor.name)); + } } /** @@ -662,6 +665,8 @@ Network.NetworkPanel.FilmStripRecorder = class { this._tracingModel.dispose(); this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage()); this._tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', ''); + + Host.userMetrics.actionTaken(Host.UserMetrics.Action.FilmStripStartedRecording); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js index 6108fd709d4..e2b85ba9af8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js @@ -63,7 +63,7 @@ Network.RequestHTMLView = class extends UI.VBox { const iframe = createElement('iframe'); iframe.className = 'html-preview-frame'; iframe.setAttribute('sandbox', ''); // Forbid to run JavaScript and set unique origin. - iframe.setAttribute('src', this._dataURL); + iframe.setAttribute('src', encodeURI(this._dataURL)); iframe.setAttribute('tabIndex', -1); this.contentElement.appendChild(iframe); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/RequestPreviewView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/RequestPreviewView.js index a0ad048b942..ae4dd41f4df 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/RequestPreviewView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/RequestPreviewView.js @@ -71,7 +71,7 @@ Network.RequestPreviewView = class extends Network.RequestResponseView { return jsonView; const dataURL = Common.ContentProvider.contentAsDataURL( - contentData.content, this.request.mimeType, contentData.encoded, contentData.encoded ? 'utf-8' : null); + contentData.content, this.request.mimeType, contentData.encoded, this.request.charset()); return dataURL ? new Network.RequestHTMLView(dataURL) : null; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js index 526b4c5dac0..42e8b4115cb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js @@ -81,6 +81,7 @@ Network.ResourceWebSocketFrameView = class extends UI.VBox { const mainContainer = new UI.VBox(); mainContainer.element.appendChild(this._mainToolbar.element); this._dataGrid.asWidget().show(mainContainer.element); + mainContainer.setMinimumSize(0, 72); this._splitWidget.setMainWidget(mainContainer); this._frameEmptyWidget = new UI.EmptyWidget(Common.UIString('Select frame to browse its content.')); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/networkLogView.css b/chromium/third_party/blink/renderer/devtools/front_end/network/networkLogView.css index b7240de3d0a..2a1d831bf0a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/networkLogView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/networkLogView.css @@ -264,8 +264,8 @@ color: grey; } -.network-summary-bar .summary-red { - color: red; +.network-summary-bar .summary-load-event { + color: #B31412; } .network-frame-divider { @@ -279,11 +279,11 @@ overflow: hidden; } -.network-summary-bar .summary-blue { - color: blue; +.network-summary-bar .summary-dcl-event { + color: #0867CB; } -.-theme-with-dark-background .network-summary-bar .summary-blue { +.-theme-with-dark-background .network-summary-bar .summary-dcl-event { color: #03A9F4; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js b/chromium/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js index 3a2cb44d46d..b1bb51a8c02 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js @@ -11,11 +11,10 @@ NodeMain.NodeMain = class extends Common.Object { */ run() { Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSFromFrontend); - const target = SDK.targetManager.createTarget( - 'main', Common.UIString('Main'), SDK.Target.Capability.Target, params => new SDK.MainConnection(params), null, - false /* isNodeJS */); - target.setInspectedURL('Node.js'); - InspectorFrontendHost.connectionReady(); + SDK.initMainConnection(() => { + const target = SDK.targetManager.createTarget('main', Common.UIString('Main'), SDK.Target.Type.Browser, null); + target.setInspectedURL('Node.js'); + }, Components.TargetDetachedDialog.webSocketConnectionLost); } }; @@ -31,15 +30,16 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { this._targetManager = parentTarget.targetManager(); this._parentTarget = parentTarget; this._targetAgent = parentTarget.targetAgent(); - /** @type {!Map<string, !SDK.ChildConnection>} */ - this._childConnections = new Map(); + /** @type {!Map<string, !SDK.Target>} */ + this._childTargets = new Map(); parentTarget.registerTargetDispatcher(this); this._targetAgent.setDiscoverTargets(true); - InspectorFrontendHost.setDevicesUpdatesEnabled(true); InspectorFrontendHost.events.addEventListener( InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + InspectorFrontendHost.setDevicesUpdatesEnabled(false); + InspectorFrontendHost.setDevicesUpdatesEnabled(true); } /** @@ -64,7 +64,7 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { InspectorFrontendHost.events.removeEventListener( InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); - for (const sessionId of this._childConnections.keys()) + for (const sessionId of this._childTargets.keys()) this.detachedFromTarget(sessionId, undefined); } @@ -74,7 +74,7 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { */ targetCreated(targetInfo) { if (targetInfo.type === 'node' && !targetInfo.attached) - this._targetAgent.attachToTarget(targetInfo.targetId); + this._targetAgent.attachToTarget(targetInfo.targetId, true /* flatten */); } /** @@ -98,9 +98,10 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { * @param {boolean} waitingForDebugger */ attachedToTarget(sessionId, targetInfo, waitingForDebugger) { + const name = ls`Node.js: ${targetInfo.url}`; const target = this._targetManager.createTarget( - targetInfo.targetId, Common.UIString('Node.js: %s', targetInfo.url), SDK.Target.Capability.JS, - this._createChildConnection.bind(this, this._targetAgent, sessionId), this._parentTarget, true /* isNodeJS */); + targetInfo.targetId, name, SDK.Target.Type.Node, this._parentTarget, sessionId); + this._childTargets.set(sessionId, target); target.runtimeAgent().runIfWaitingForDebugger(); } @@ -110,8 +111,8 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { * @param {string=} childTargetId */ detachedFromTarget(sessionId, childTargetId) { - this._childConnections.get(sessionId).onDisconnect.call(null, 'target terminated'); - this._childConnections.delete(sessionId); + this._childTargets.get(sessionId).dispose('target terminated'); + this._childTargets.delete(sessionId); } /** @@ -121,21 +122,7 @@ NodeMain.NodeChildTargetManager = class extends SDK.SDKModel { * @param {string=} childTargetId */ receivedMessageFromTarget(sessionId, message, childTargetId) { - const connection = this._childConnections.get(sessionId); - if (connection) - connection.onMessage.call(null, message); - } - - /** - * @param {!Protocol.TargetAgent} agent - * @param {string} sessionId - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createChildConnection(agent, sessionId, params) { - const connection = new SDK.ChildConnection(agent, sessionId, params); - this._childConnections.set(sessionId, connection); - return connection; + // We use flatten protocol. } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/CustomPreviewComponent.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/CustomPreviewComponent.js index 937a945abd5..6a561df771c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/CustomPreviewComponent.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/CustomPreviewComponent.js @@ -28,7 +28,7 @@ ObjectUI.CustomPreviewSection = class { return; } - if (customPreview.hasBody) { + if (customPreview.hasBody || customPreview.bodyGetterId) { this._header.classList.add('custom-expandable-section-header'); this._header.addEventListener('click', this._onClick.bind(this), false); this._expandIcon = UI.Icon.create('smallicon-triangle-right', 'custom-expand-icon'); @@ -180,10 +180,16 @@ ObjectUI.CustomPreviewSection = class { } const customPreview = this._object.customPreview(); - const args = [{objectId: customPreview.bindRemoteObjectFunctionId}, {objectId: customPreview.formatterObjectId}]; - if (customPreview.configObjectId) - args.push({objectId: customPreview.configObjectId}); - this._object.callFunctionJSON(load, args).then(onBodyLoaded.bind(this)); + if (customPreview.bindRemoteObjectFunctionId && customPreview.formatterObjectId) { + // Support for V8 version < 7.3. + const args = [{objectId: customPreview.bindRemoteObjectFunctionId}, {objectId: customPreview.formatterObjectId}]; + if (customPreview.configObjectId) + args.push({objectId: customPreview.configObjectId}); + this._object.callFunctionJSON(load, args).then(onBodyLoaded.bind(this)); + } else if (customPreview.bodyGetterId) { + this._object.callFunctionJSON(bodyGetter => bodyGetter(), [{objectId: customPreview.bodyGetterId}]) + .then(onBodyLoaded.bind(this)); + } /** * @param {*} bodyJsonML @@ -217,7 +223,8 @@ ObjectUI.CustomPreviewComponent = class { } expandIfPossible() { - if (this._object.customPreview().hasBody && this._customPreviewSection) + if ((this._object.customPreview().hasBody || this._object.customPreview().bodyGetterId) && + this._customPreviewSection) this._customPreviewSection._loadBody(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js index 7e80eb4432b..745339d1ae9 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js @@ -1381,14 +1381,14 @@ ObjectUI.ObjectPropertiesSectionExpandController._cachedPathSymbol = Symbol('cac ObjectUI.ObjectPropertiesSectionExpandController._treeOutlineId = Symbol('treeOutlineId'); /** - * @implements {Common.Renderer} + * @implements {UI.Renderer} */ ObjectUI.ObjectPropertiesSection.Renderer = class { /** * @override * @param {!Object} object - * @param {!Common.Renderer.Options=} options - * @return {!Promise<?Node>} + * @param {!UI.Renderer.Options=} options + * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>} */ render(object, options) { if (!(object instanceof SDK.RemoteObject)) @@ -1398,9 +1398,8 @@ ObjectUI.ObjectPropertiesSection.Renderer = class { const section = new ObjectUI.ObjectPropertiesSection(object, title); if (!title) section.titleLessMode(); - if (options.expanded) - section.expand(); section.editable = !!options.editable; - return Promise.resolve(section.element); + return Promise.resolve( + /** @type {?{node: !Node, tree: ?UI.TreeOutline}} */ ({node: section.element, tree: section})); } };
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json index d56753b9a10..e2d12364e3d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json @@ -1,7 +1,7 @@ { "extensions": [ { - "type": "@Common.Renderer", + "type": "@UI.Renderer", "contextTypes": [ "SDK.RemoteObject" ], diff --git a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js index 86f2a163a4a..575aa140b1a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js @@ -127,8 +127,10 @@ PerfUI.FlameChart = class extends UI.VBox { this._highlightedEntryIndex = -1; this._selectedEntryIndex = -1; this._rawTimelineDataLength = 0; - /** @type {!Map<string,!Map<string,number>>} */ + /** @type {!Map<string, !Map<string,number>>} */ this._textWidth = new Map(); + /** @type {!Map<number, !{x: number, width: number}>} */ + this._markerPositions = new Map(); this._lastMouseOffsetX = 0; this._selectedGroup = -1; @@ -343,13 +345,7 @@ PerfUI.FlameChart = class extends UI.VBox { } _updateHighlight() { - const inDividersBar = this._lastMouseOffsetY < PerfUI.FlameChart.HeaderHeight; - this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPosition(this._lastMouseOffsetX) : -1; - this._updateMarkerHighlight(); - - const entryIndex = this._highlightedMarkerIndex === -1 ? - this._coordinatesToEntryIndex(this._lastMouseOffsetX, this._lastMouseOffsetY) : - -1; + const entryIndex = this._coordinatesToEntryIndex(this._lastMouseOffsetX, this._lastMouseOffsetY); if (entryIndex === -1) { this.hideHighlight(); const group = @@ -570,48 +566,45 @@ PerfUI.FlameChart = class extends UI.VBox { const offsetFromLevel = y - this._visibleLevelOffsets[cursorLevel]; if (offsetFromLevel > this._levelHeight(cursorLevel)) return -1; + + // Check markers first. + for (const [index, pos] of this._markerPositions) { + if (timelineData.entryLevels[index] !== cursorLevel) + continue; + if (pos.x <= x && x < pos.x + pos.width) + return /** @type {number} */ (index); + } + + // Check regular entries. const entryStartTimes = timelineData.entryStartTimes; - const entryTotalTimes = timelineData.entryTotalTimes; - const entryIndexes = this._timelineLevels[cursorLevel]; - if (!entryIndexes || !entryIndexes.length) + const entriesOnLevel = this._timelineLevels[cursorLevel]; + if (!entriesOnLevel || !entriesOnLevel.length) return -1; - /** - * @param {number} time - * @param {number} entryIndex - * @return {number} - */ - function comparator(time, entryIndex) { - return time - entryStartTimes[entryIndex]; - } const cursorTime = this._chartViewport.pixelToTime(x); - const indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparator) - 1, 0); + const indexOnLevel = Math.max( + entriesOnLevel.upperBound(cursorTime, (time, entryIndex) => time - entryStartTimes[entryIndex]) - 1, 0); /** * @this {PerfUI.FlameChart} - * @param {number} entryIndex + * @param {number|undefined} entryIndex * @return {boolean} */ function checkEntryHit(entryIndex) { if (entryIndex === undefined) return false; const startTime = entryStartTimes[entryIndex]; + const duration = timelineData.entryTotalTimes[entryIndex]; const startX = this._chartViewport.timeToPosition(startTime); - const duration = entryTotalTimes[entryIndex]; - if (isNaN(duration)) { - const dx = startX - x; - const dy = this._levelHeight(cursorLevel) / 2 - offsetFromLevel; - return dx * dx + dy * dy < this._markerRadius * this._markerRadius; - } const endX = this._chartViewport.timeToPosition(startTime + duration); - const /** @const */ barThresholdPx = 3; + const barThresholdPx = 3; return startX - barThresholdPx < x && x < endX + barThresholdPx; } - let entryIndex = entryIndexes[indexOnLevel]; + let entryIndex = entriesOnLevel[indexOnLevel]; if (checkEntryHit.call(this, entryIndex)) return entryIndex; - entryIndex = entryIndexes[indexOnLevel + 1]; + entryIndex = entriesOnLevel[indexOnLevel + 1]; if (checkEntryHit.call(this, entryIndex)) return entryIndex; return -1; @@ -711,6 +704,7 @@ PerfUI.FlameChart = class extends UI.VBox { const minTextWidth = 2 * textPadding + UI.measureTextWidth(context, '\u2026'); const minTextWidthDuration = this._chartViewport.pixelToTimeOffset(minTextWidth); const minVisibleBarLevel = Math.max(this._visibleLevelOffsets.upperBound(top) - 1, 0); + this._markerPositions.clear(); /** @type {!Map<string, !Array<number>>} */ const colorBuckets = new Map(); @@ -729,10 +723,11 @@ PerfUI.FlameChart = class extends UI.VBox { let lastDrawOffset = Infinity; for (let entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) { const entryIndex = levelIndexes[entryIndexOnLevel]; - let duration = entryTotalTimes[entryIndex]; - if (isNaN(duration)) + const duration = entryTotalTimes[entryIndex]; + if (isNaN(duration)) { markerIndices.push(entryIndex); - duration = duration || 0; + continue; + } if (duration >= minTextWidthDuration || this._forceDecorationCache[entryIndex]) titleIndices.push(entryIndex); @@ -771,51 +766,57 @@ PerfUI.FlameChart = class extends UI.VBox { }); context.restore(); - const colors = colorBuckets.keysArray(); - // We don't use for-of here because it's slow. - for (let c = 0; c < colors.length; ++c) { - const color = colors[c]; - const indexes = colorBuckets.get(color); + for (const [color, indexes] of colorBuckets) { context.beginPath(); for (let i = 0; i < indexes.length; ++i) { const entryIndex = indexes[i]; + const duration = entryTotalTimes[entryIndex]; + if (isNaN(duration)) + continue; const entryStartTime = entryStartTimes[entryIndex]; const barX = this._timeToPositionClipped(entryStartTime); - const duration = entryTotalTimes[entryIndex]; const barLevel = entryLevels[entryIndex]; const barHeight = this._levelHeight(barLevel); const barY = this._levelToOffset(barLevel); - if (isNaN(duration)) { - context.moveTo(barX + this._markerRadius, barY + barHeight / 2); - context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2); - continue; - } const barRight = this._timeToPositionClipped(entryStartTime + duration); const barWidth = Math.max(barRight - barX, 1); - if (color) - context.rect(barX, barY, barWidth - 0.4, barHeight - 1); + context.rect(barX, barY, barWidth - 0.4, barHeight - 1); } - if (!color) - continue; context.fillStyle = color; context.fill(); } } + context.textBaseline = 'alphabetic'; context.beginPath(); - for (let m = 0; m < markerIndices.length; ++m) { + let lastMarkerLevel = -1; + let lastMarkerX = -Infinity; + // Markers are sorted top to bottom, right to left. + for (let m = markerIndices.length - 1; m >= 0; --m) { const entryIndex = markerIndices[m]; + const title = this._dataProvider.entryTitle(entryIndex); + if (!title) + continue; const entryStartTime = entryStartTimes[entryIndex]; - const barX = this._timeToPositionClipped(entryStartTime); - const barLevel = entryLevels[entryIndex]; - const y = this._levelToOffset(barLevel) + this._levelHeight(barLevel) / 2; - context.moveTo(barX + this._markerRadius, y); - context.arc(barX, y, this._markerRadius, 0, Math.PI * 2); + const level = entryLevels[entryIndex]; + if (lastMarkerLevel !== level) + lastMarkerX = -Infinity; + const x = Math.max(this._chartViewport.timeToPosition(entryStartTime), lastMarkerX); + const y = this._levelToOffset(level); + const h = this._levelHeight(level); + const padding = 4; + const width = Math.ceil(UI.measureTextWidth(context, title)) + 2 * padding; + lastMarkerX = x + width + 1; + lastMarkerLevel = level; + this._markerPositions.set(entryIndex, {x, width}); + context.fillStyle = this._dataProvider.entryColor(entryIndex); + context.fillRect(x, y, width, h - 1); + context.fillStyle = 'white'; + context.fillText(title, x + padding, y + h - this._textBaseline); } context.strokeStyle = 'rgba(0, 0, 0, 0.2)'; context.stroke(); - context.textBaseline = 'alphabetic'; for (let i = 0; i < titleIndices.length; ++i) { const entryIndex = titleIndices[i]; const entryStartTime = entryStartTimes[entryIndex]; @@ -1591,19 +1592,30 @@ PerfUI.FlameChart = class extends UI.VBox { * @param {number} entryIndex */ _updateElementPosition(element, entryIndex) { - const /** @const */ elementMinWidthPx = 2; - if (element.parentElement) - element.remove(); + const elementMinWidthPx = 2; + element.classList.add('hidden'); if (entryIndex === -1) return; const timelineData = this._timelineData(); const startTime = timelineData.entryStartTimes[entryIndex]; - const endTime = startTime + (timelineData.entryTotalTimes[entryIndex] || 0); - let barX = this._timeToPositionClipped(startTime); - const barRight = this._timeToPositionClipped(endTime); - if (barRight === 0 || barX === this._offsetWidth) + const duration = timelineData.entryTotalTimes[entryIndex]; + let barX = 0; + let barWidth = 0; + let visible = true; + if (Number.isNaN(duration)) { + const position = this._markerPositions.get(entryIndex); + if (position) { + barX = position.x; + barWidth = position.width; + } else { + visible = false; + } + } else { + barX = this._chartViewport.timeToPosition(startTime); + barWidth = duration * this._chartViewport.timeToPixel(); + } + if (barX + barWidth <= 0 || barX >= this._offsetWidth) return; - let barWidth = barRight - barX; const barCenter = barX + barWidth / 2; barWidth = Math.max(barWidth, elementMinWidthPx); barX = barCenter - barWidth / 2; @@ -1615,6 +1627,7 @@ PerfUI.FlameChart = class extends UI.VBox { style.top = barY + 'px'; style.width = barWidth + 'px'; style.height = barHeight - 1 + 'px'; + element.classList.toggle('hidden', !visible); this._viewportElement.appendChild(element); } @@ -1911,7 +1924,7 @@ PerfUI.FlameChartMarker.prototype = { color() {}, /** - * @return {string} + * @return {?string} */ title() {}, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/performance_monitor/PerformanceMonitor.js b/chromium/third_party/blink/renderer/devtools/front_end/performance_monitor/PerformanceMonitor.js index fd819d27304..f8930c7477e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/performance_monitor/PerformanceMonitor.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/performance_monitor/PerformanceMonitor.js @@ -14,7 +14,7 @@ PerformanceMonitor.PerformanceMonitor = class extends UI.HBox { /** @type {!Array<!{timestamp: number, metrics: !Map<string, number>}>} */ this._metricsBuffer = []; /** @const */ - this._pixelsPerMs = 20 / 1000; + this._pixelsPerMs = 10 / 1000; /** @const */ this._pollIntervalMs = 500; /** @const */ @@ -144,8 +144,9 @@ PerformanceMonitor.PerformanceMonitor = class extends UI.HBox { * @param {!CanvasRenderingContext2D} ctx */ _drawHorizontalGrid(ctx) { + const labelDistanceSeconds = 10; const lightGray = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.02)', UI.ThemeSupport.ColorUsage.Foreground); - ctx.font = '9px ' + Host.fontFamily(); + ctx.font = '10px ' + Host.fontFamily(); ctx.fillStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.3)', UI.ThemeSupport.ColorUsage.Foreground); const currentTime = Date.now() / 1000; for (let sec = Math.ceil(currentTime);; --sec) { @@ -155,9 +156,9 @@ PerformanceMonitor.PerformanceMonitor = class extends UI.HBox { ctx.beginPath(); ctx.moveTo(Math.round(x) + 0.5, 0); ctx.lineTo(Math.round(x) + 0.5, this._height); - if (sec >= 0 && sec % 5 === 0) + if (sec >= 0 && sec % labelDistanceSeconds === 0) ctx.fillText(new Date(sec * 1000).toLocaleTimeString(), Math.round(x) + 4, 12); - ctx.strokeStyle = sec % 5 ? lightGray : this._gridColor; + ctx.strokeStyle = sec % labelDistanceSeconds ? lightGray : this._gridColor; ctx.stroke(); } } @@ -517,13 +518,19 @@ PerformanceMonitor.PerformanceMonitor.MetricIndicator = class { * @return {string} */ static _formatNumber(value, info) { + if (!PerformanceMonitor.PerformanceMonitor.MetricIndicator._numberFormatter) { + PerformanceMonitor.PerformanceMonitor.MetricIndicator._numberFormatter = + new Intl.NumberFormat('en-US', {maximumFractionDigits: 1}); + PerformanceMonitor.PerformanceMonitor.MetricIndicator._percentFormatter = + new Intl.NumberFormat('en-US', {maximumFractionDigits: 1, style: 'percent'}); + } switch (info.format) { case PerformanceMonitor.PerformanceMonitor.Format.Percent: - return value.toLocaleString('en-US', {maximumFractionDigits: 1, style: 'percent'}); + return PerformanceMonitor.PerformanceMonitor.MetricIndicator._percentFormatter.format(value); case PerformanceMonitor.PerformanceMonitor.Format.Bytes: return Number.bytesToString(value); default: - return value.toLocaleString('en-US', {maximumFractionDigits: 1}); + return PerformanceMonitor.PerformanceMonitor.MetricIndicator._numberFormatter.format(value); } } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js index 68feae279ac..bc64a00630f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js @@ -166,6 +166,8 @@ Persistence.Automapping = class { if (networkSourceCode[Persistence.Automapping._processingPromise] || networkSourceCode[Persistence.Automapping._status]) return; + if (networkSourceCode.url().startsWith('wasm://')) + return; const createBindingPromise = this._createBinding(networkSourceCode).then(validateStatus.bind(this)).then(onStatus.bind(this)); networkSourceCode[Persistence.Automapping._processingPromise] = createBindingPromise; @@ -217,7 +219,7 @@ Persistence.Automapping = class { const target = Bindings.NetworkProject.targetForUISourceCode(status.network); let isValid = false; - if (target && target.isNodeJS()) { + if (target && target.type() === SDK.Target.Type.Node) { const rewrappedNetworkContent = Persistence.Persistence.rewrapNodeJSContent(status.fileSystem, fileSystemContent, networkContent); isValid = fileSystemContent === rewrappedNetworkContent; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js index 14accb96faf..fac5b9958a8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js @@ -178,7 +178,7 @@ Persistence.Persistence = class extends Common.Object { } const target = Bindings.NetworkProject.targetForUISourceCode(binding.network); - if (target.isNodeJS()) { + if (target.type() === SDK.Target.Type.Node) { const newContent = uiSourceCode.workingCopy(); other.requestContent().then(() => { const nodeJSContent = Persistence.Persistence.rewrapNodeJSContent(other, other.workingCopy(), newContent); @@ -221,7 +221,7 @@ Persistence.Persistence = class extends Common.Object { return; const other = binding.network === uiSourceCode ? binding.fileSystem : binding.network; const target = Bindings.NetworkProject.targetForUISourceCode(binding.network); - if (target.isNodeJS()) { + if (target.type() === SDK.Target.Type.Node) { other.requestContent().then(currentContent => { const nodeJSContent = Persistence.Persistence.rewrapNodeJSContent(other, currentContent, newContent); setContent.call(this, nodeJSContent); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceActions.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceActions.js index 8307698bea7..53ebe75e759 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceActions.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceActions.js @@ -20,7 +20,9 @@ Persistence.PersistenceActions.ContextMenuProvider = class { async function saveAs() { if (contentProvider instanceof Workspace.UISourceCode) /** @type {!Workspace.UISourceCode} */ (contentProvider).commitWorkingCopy(); - const content = await contentProvider.requestContent(); + let content = await contentProvider.requestContent(); + if (await contentProvider.contentEncoded()) + content = window.atob(content); const url = contentProvider.contentURL(); Workspace.fileManager.save(url, /** @type {string} */ (content), true); Workspace.fileManager.close(url); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js index 59308118e36..7f9c03df371 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js @@ -78,6 +78,9 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { * @param {!Persistence.PlatformFileSystem} fileSystem */ _addItem(fileSystem) { + // Support managing only instances of IsolatedFileSystem. + if (!(fileSystem instanceof Persistence.IsolatedFileSystem)) + return; const networkPersistenceProject = Persistence.networkPersistenceManager.project(); if (networkPersistenceProject && Persistence.isolatedFileSystemManager.fileSystem(networkPersistenceProject.fileSystemPath()) === fileSystem) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js index 5b9025df6ae..a901ccf0174 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js @@ -34,10 +34,11 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView { constructor(profileHeader) { super(); this._profileHeader = profileHeader; - this.profile = profileHeader.profileModel(); - this.adjustedTotal = this.profile.profileHead.total; - this.adjustedTotal -= this.profile.idleNode ? this.profile.idleNode.total : 0; this.initialize(new Profiler.CPUProfileView.NodeFormatter(this)); + const profile = profileHeader.profileModel(); + this.adjustedTotal = profile.profileHead.total; + this.adjustedTotal -= profile.idleNode ? profile.idleNode.total : 0; + this.setProfile(profile); } /** @@ -47,7 +48,7 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView { super.wasShown(); const lineLevelProfile = PerfUI.LineLevelProfile.instance(); lineLevelProfile.reset(); - lineLevelProfile.appendCPUProfile(this.profile); + lineLevelProfile.appendCPUProfile(this._profileHeader.profileModel()); } /** @@ -70,7 +71,8 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView { * @return {!PerfUI.FlameChartDataProvider} */ createFlameChartDataProvider() { - return new Profiler.CPUFlameChartDataProvider(this.profile, this._profileHeader._cpuProfilerModel); + return new Profiler.CPUFlameChartDataProvider( + this._profileHeader.profileModel(), this._profileHeader._cpuProfilerModel); } }; @@ -121,10 +123,10 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { */ buttonClicked() { if (this._recording) { - this.stopRecordingProfile(); + this._stopRecordingProfile(); return false; } else { - this.startRecordingProfile(); + this._startRecordingProfile(); return true; } } @@ -148,7 +150,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { this.addProfile(profile); } - startRecordingProfile() { + _startRecordingProfile() { const cpuProfilerModel = UI.context.flavor(SDK.CPUProfilerModel); if (this.profileBeingRecorded() || !cpuProfilerModel) return; @@ -162,7 +164,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesCPUProfileTaken); } - async stopRecordingProfile() { + async _stopRecordingProfile() { this._recording = false; if (!this.profileBeingRecorded() || !this.profileBeingRecorded()._cpuProfilerModel) return; @@ -193,7 +195,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { * @override */ profileBeingRecordedRemoved() { - this.stopRecordingProfile(); + this._stopRecordingProfile(); } }; @@ -272,7 +274,7 @@ Profiler.CPUProfileView.NodeFormatter = class { * @return {string} */ formatPercent(value, node) { - return node.profileNode === this._profileView.profile.idleNode ? '' : Common.UIString('%.2f\xa0%%', value); + return node.profileNode === this._profileView.profile().idleNode ? '' : Common.UIString('%.2f\xa0%%', value); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js index 56604554831..3c220b1d759 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js @@ -1,6 +1,7 @@ // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + /** * @implements {UI.Searchable} * @unrestricted @@ -11,18 +12,110 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { */ constructor(profileHeader) { super(); + this._profileHeader = profileHeader; - this.profile = new Profiler.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile()); - this.adjustedTotal = this.profile.total; + this._profileType = profileHeader.profileType(); const views = [ Profiler.ProfileView.ViewTypes.Flame, Profiler.ProfileView.ViewTypes.Heavy, Profiler.ProfileView.ViewTypes.Tree ]; - const isNativeProfile = [ - Profiler.SamplingNativeHeapProfileType.TypeId, Profiler.SamplingNativeHeapSnapshotType.TypeId - ].includes(profileHeader.profileType().id); + + const isNativeProfile = this._profileType.id === Profiler.SamplingNativeHeapProfileType.TypeId || + this._profileType.id === Profiler.SamplingNativeHeapSnapshotType.TypeId; if (isNativeProfile) views.push(Profiler.ProfileView.ViewTypes.Text); + this.initialize(new Profiler.HeapProfileView.NodeFormatter(this), views); + const profile = new Profiler.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile()); + this.adjustedTotal = profile.total; + this.setProfile(profile); + + this._selectedSizeText = new UI.ToolbarText(); + + if (Runtime.experiments.isEnabled('samplingHeapProfilerTimeline')) { + this._timelineOverview = new Profiler.HeapTimelineOverview(); + this._timelineOverview.addEventListener( + Profiler.HeapTimelineOverview.IdsRangeChanged, this._onIdsRangeChanged.bind(this)); + this._timelineOverview.show(this.element, this.element.firstChild); + this._timelineOverview.start(); + + this._profileType.addEventListener( + Profiler.SamplingHeapProfileType.Events.StatsUpdate, this._onStatsUpdate, this); + this._profileType.once(Profiler.ProfileType.Events.ProfileComplete).then(() => { + this._profileType.removeEventListener( + Profiler.SamplingHeapProfileType.Events.StatsUpdate, this._onStatsUpdate, this); + this._timelineOverview.stop(); + this._timelineOverview.updateGrid(); + }); + } + } + + /** + * @override + * @return {!Array<!UI.ToolbarItem>} + */ + syncToolbarItems() { + return [...super.syncToolbarItems(), this._selectedSizeText]; + } + + /** + * @param {!Common.Event} event + */ + _onIdsRangeChanged(event) { + const minId = /** @type {number} */ (event.data.minId); + const maxId = /** @type {number} */ (event.data.maxId); + this._selectedSizeText.setText(ls`Selected size: ${Number.bytesToString(event.data.size)}`); + this._setSelectionRange(minId, maxId); + } + + /** + * @param {number} minId + * @param {number} maxId + */ + _setSelectionRange(minId, maxId) { + const profile = new Profiler.SamplingHeapProfileModel( + this._profileHeader._profile || this._profileHeader.protocolProfile(), minId, maxId); + this.adjustedTotal = profile.total; + this.setProfile(profile); + } + + /** + * @param {!Common.Event} event + */ + _onStatsUpdate(event) { + const profile = event.data; + + if (!this._totalTime) { + this._timestamps = []; + this._sizes = []; + this._max = []; + this._ordinals = []; + this._totalTime = 30000; + this._lastOrdinal = 0; + } + + this._sizes.fill(0); + this._sizes.push(0); + this._timestamps.push(Date.now()); + this._ordinals.push(this._lastOrdinal + 1); + this._lastOrdinal = profile.samples.reduce((res, sample) => Math.max(res, sample.ordinal), this._lastOrdinal); + for (const sample of profile.samples) { + const bucket = this._ordinals.upperBound(sample.ordinal) - 1; + this._sizes[bucket] += sample.size; + } + this._max.push(this._sizes.peekLast()); + + if (this._timestamps.peekLast() - this._timestamps[0] > this._totalTime) + this._totalTime *= 2; + + const samples = /** @type {!Profiler.HeapTimelineOverview.Samples} */ ({ + sizes: this._sizes, + max: this._max, + ids: this._ordinals, + timestamps: this._timestamps, + totalTime: this._totalTime + }); + + this._timelineOverview.setSamples(samples); } /** @@ -45,7 +138,8 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { * @return {!PerfUI.FlameChartDataProvider} */ createFlameChartDataProvider() { - return new Profiler.HeapFlameChartDataProvider(this.profile, this._profileHeader.heapProfilerModel()); + return new Profiler.HeapFlameChartDataProvider( + /** @type {!Profiler.SamplingHeapProfileModel} */ (this.profile()), this._profileHeader.heapProfilerModel()); } /** @@ -58,10 +152,10 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { `Report Version: 7\n` + `App Version: ${/Chrom\S*/.exec(navigator.appVersion)[0] || 'Unknown'}\n` + `Node Weight: 1 KiB\n` + - `Total Size: ${Math.round(this.profile.root.total / 1024)} KiB\n` + + `Total Size: ${Math.round(this.profile().root.total / 1024)} KiB\n` + `----\n\nCall graph:\n`; - const sortedChildren = this.profile.root.children.sort((a, b) => b.total - a.total); - const modules = this.profile.modules.map( + const sortedChildren = this.profile().root.children.sort((a, b) => b.total - a.total); + const modules = this.profile().modules.map( m => Object.assign({address: BigInt(m.baseAddress), endAddress: BigInt(m.baseAddress) + BigInt(m.size)}, m)); modules.sort((m1, m2) => m1.address > m2.address ? 1 : m1.address < m2.address ? -1 : 0); for (const child of sortedChildren) @@ -121,6 +215,10 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { * @unrestricted */ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType { + /** + * @param {string} typeId + * @param {string} description + */ constructor(typeId, description) { super(typeId, description); this._recording = false; @@ -151,7 +249,7 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType { } get buttonTooltip() { - return this._recording ? Common.UIString('Stop heap profiling') : Common.UIString('Start heap profiling'); + return this._recording ? ls`Stop heap profiling` : ls`Start heap profiling`; } /** @@ -159,37 +257,36 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType { * @return {boolean} */ buttonClicked() { - const wasRecording = this._recording; - if (wasRecording) - this.stopRecordingProfile(); + if (this._recording) + this._stopRecordingProfile(); else - this.startRecordingProfile(); - return !wasRecording; + this._startRecordingProfile(); + return this._recording; } - startRecordingProfile() { + _startRecordingProfile() { const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel); if (this.profileBeingRecorded() || !heapProfilerModel) return; - const profile = new Profiler.SamplingHeapProfileHeader(heapProfilerModel, this); - this.setProfileBeingRecorded(profile); - this.addProfile(profile); - profile.updateStatus(Common.UIString('Recording\u2026')); + const profileHeader = new Profiler.SamplingHeapProfileHeader(heapProfilerModel, this); + this.setProfileBeingRecorded(profileHeader); + this.addProfile(profileHeader); + profileHeader.updateStatus(ls`Recording\u2026`); const icon = UI.Icon.create('smallicon-warning'); - icon.title = Common.UIString('Heap profiler is recording'); + icon.title = ls`Heap profiler is recording`; UI.inspectorView.setPanelIcon('heap_profiler', icon); this._recording = true; this._startSampling(); } - async stopRecordingProfile() { + async _stopRecordingProfile() { this._recording = false; if (!this.profileBeingRecorded() || !this.profileBeingRecorded().heapProfilerModel()) return; - this.profileBeingRecorded().updateStatus(Common.UIString('Stopping\u2026')); + this.profileBeingRecorded().updateStatus(ls`Stopping\u2026`); const profile = await this._stopSampling(); const recordedProfile = this.profileBeingRecorded(); if (recordedProfile) { @@ -215,7 +312,7 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType { * @override */ profileBeingRecordedRemoved() { - this.stopRecordingProfile(); + this._stopRecordingProfile(); } _startSampling() { @@ -230,7 +327,6 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType { } }; - /** * @unrestricted */ @@ -238,6 +334,8 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp constructor() { super(Profiler.SamplingHeapProfileType.TypeId, ls`Allocation sampling`); Profiler.SamplingHeapProfileType.instance = this; + this._updateTimer = null; + this._updateIntervalMs = 200; } get treeItemTitle() { @@ -252,9 +350,19 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp /** * @override + * @return {boolean} + */ + hasTemporaryView() { + return Runtime.experiments.isEnabled('samplingHeapProfilerTimeline'); + } + + /** + * @override */ _startSampling() { this.profileBeingRecorded().heapProfilerModel().startSampling(); + if (Runtime.experiments.isEnabled('samplingHeapProfilerTimeline')) + this._updateTimer = setTimeout(this._updateStats.bind(this), this._updateIntervalMs); } /** @@ -262,12 +370,29 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp * return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>} */ _stopSampling() { + clearTimeout(this._updateTimer); + this._updateTimer = null; + this.dispatchEventToListeners(Profiler.SamplingHeapProfileType.Events.RecordingStopped); return this.profileBeingRecorded().heapProfilerModel().stopSampling(); } + + async _updateStats() { + const profile = await this.profileBeingRecorded().heapProfilerModel().getSamplingProfile(); + if (!this._updateTimer) + return; + this.dispatchEventToListeners(Profiler.SamplingHeapProfileType.Events.StatsUpdate, profile); + this._updateTimer = setTimeout(this._updateStats.bind(this), this._updateIntervalMs); + } }; Profiler.SamplingHeapProfileType.TypeId = 'SamplingHeap'; +/** @enum {symbol} */ +Profiler.SamplingHeapProfileType.Events = { + RecordingStopped: Symbol('RecordingStopped'), + StatsUpdate: Symbol('StatsUpdate') +}; + /** * @unrestricted */ @@ -426,6 +551,8 @@ Profiler.SamplingHeapProfileHeader = class extends Profiler.WritableProfileHeade heapProfilerModel && heapProfilerModel.debuggerModel(), type, title || Common.UIString('Profile %d', type.nextProfileUid())); this._heapProfilerModel = heapProfilerModel; + this._protocolProfile = + /** @type {!Protocol.HeapProfiler.SamplingHeapProfile} */ ({head: {callFrame: {}, children: []}}); } /** @@ -478,29 +605,61 @@ Profiler.SamplingHeapProfileNode = class extends SDK.ProfileNode { Profiler.SamplingHeapProfileModel = class extends SDK.ProfileTreeModel { /** * @param {!Protocol.HeapProfiler.SamplingHeapProfile} profile + * @param {number=} minOrdinal + * @param {number=} maxOrdinal */ - constructor(profile) { + constructor(profile, minOrdinal, maxOrdinal) { super(); - this.initialize(translateProfileTree(profile.head)); this.modules = profile.modules || []; + /** @type {?Map<number, number>} */ + let nodeIdToSizeMap = null; + if (minOrdinal || maxOrdinal) { + nodeIdToSizeMap = new Map(); + minOrdinal = minOrdinal || 0; + maxOrdinal = maxOrdinal || Infinity; + for (const sample of profile.samples) { + if (sample.ordinal < minOrdinal || sample.ordinal > maxOrdinal) + continue; + const size = nodeIdToSizeMap.get(sample.nodeId) || 0; + nodeIdToSizeMap.set(sample.nodeId, size + sample.size); + } + } + + this.initialize(translateProfileTree(profile.head)); + /** * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} root * @return {!Profiler.SamplingHeapProfileNode} */ function translateProfileTree(root) { const resultRoot = new Profiler.SamplingHeapProfileNode(root); - const targetNodeStack = [resultRoot]; const sourceNodeStack = [root]; + const targetNodeStack = [resultRoot]; while (sourceNodeStack.length) { const sourceNode = sourceNodeStack.pop(); - const parentNode = targetNodeStack.pop(); - parentNode.children = sourceNode.children.map(child => new Profiler.SamplingHeapProfileNode(child)); - sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children); - targetNodeStack.push.apply(targetNodeStack, parentNode.children); + const targetNode = targetNodeStack.pop(); + targetNode.children = sourceNode.children.map(child => { + const targetChild = new Profiler.SamplingHeapProfileNode(child); + if (nodeIdToSizeMap) + targetChild.self = nodeIdToSizeMap.get(child.id) || 0; + return targetChild; + }); + sourceNodeStack.pushAll(sourceNode.children); + targetNodeStack.pushAll(targetNode.children); } + pruneEmptyBranches(resultRoot); return resultRoot; } + + /** + * @param {!SDK.ProfileNode} node + * @return {boolean} + */ + function pruneEmptyBranches(node) { + node.children = node.children.filter(pruneEmptyBranches); + return !!(node.children.length || node.self); + } } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js index 482e79554c3..c33e9506279 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js @@ -180,6 +180,7 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView { Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); profileType.addEventListener( Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); + this._trackingOverviewGrid.start(); } } @@ -188,6 +189,8 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView { Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); this._profile.profileType().removeEventListener( Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); + if (this._trackingOverviewGrid) + this._trackingOverviewGrid.stop(); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js index 6b3826573eb..e60c72bfab1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js @@ -29,12 +29,27 @@ Profiler.HeapTimelineOverview = class extends UI.VBox { this._profileSamples = new Profiler.HeapTimelineOverview.Samples(); } + start() { + this._running = true; + const drawFrame = () => { + this.update(); + if (this._running) + this.element.window().requestAnimationFrame(drawFrame); + }; + drawFrame(); + } + + stop() { + this._running = false; + } + /** * @param {!Profiler.HeapTimelineOverview.Samples} samples */ setSamples(samples) { this._profileSamples = samples; - this.update(); + if (!this._running) + this.update(); } /** @@ -49,7 +64,6 @@ Profiler.HeapTimelineOverview = class extends UI.VBox { const topSizes = profileSamples.max; const timestamps = profileSamples.timestamps; const startTime = timestamps[0]; - const endTime = timestamps[timestamps.length - 1]; const scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime); let maxSize = 0; @@ -93,14 +107,16 @@ Profiler.HeapTimelineOverview = class extends UI.VBox { const context = this._overviewCanvas.getContext('2d'); context.scale(window.devicePixelRatio, window.devicePixelRatio); - context.beginPath(); - context.lineWidth = 2; - context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; - const currentX = (endTime - startTime) * scaleFactor; - context.moveTo(currentX, height - 1); - context.lineTo(currentX, 0); - context.stroke(); - context.closePath(); + if (this._running) { + context.beginPath(); + context.lineWidth = 2; + context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; + const currentX = (Date.now() - startTime) * scaleFactor; + context.moveTo(currentX, height - 1); + context.lineTo(currentX, 0); + context.stroke(); + context.closePath(); + } let gridY; let gridValue; @@ -204,30 +220,23 @@ Profiler.HeapTimelineOverview = class extends UI.VBox { this._updateGridTimerId = 0; this._updateBoundaries(); const ids = this._profileSamples.ids; + if (!ids.length) + return; const timestamps = this._profileSamples.timestamps; const sizes = this._profileSamples.sizes; const startTime = timestamps[0]; const totalTime = this._profileSamples.totalTime; const timeLeft = startTime + totalTime * this._windowLeft; const timeRight = startTime + totalTime * this._windowRight; - let minId = 0; - let maxId = ids[ids.length - 1] + 1; + const minIndex = timestamps.lowerBound(timeLeft); + const maxIndex = timestamps.upperBound(timeRight); let size = 0; - for (let i = 0; i < timestamps.length; ++i) { - if (!timestamps[i]) - continue; - if (timestamps[i] > timeRight) - break; - maxId = ids[i]; - if (timestamps[i] < timeLeft) { - minId = ids[i]; - continue; - } + for (let i = minIndex; i < maxIndex; ++i) size += sizes[i]; - } + const minId = minIndex < ids.length ? ids[minIndex] : Infinity; + const maxId = maxIndex < ids.length ? ids[maxIndex] : Infinity; - this.dispatchEventToListeners( - Profiler.HeapTimelineOverview.IdsRangeChanged, {minId: minId, maxId: maxId, size: size}); + this.dispatchEventToListeners(Profiler.HeapTimelineOverview.IdsRangeChanged, {minId, maxId, size}); } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js index c61e126719b..ab3c2e8183d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js @@ -1,6 +1,7 @@ // Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + /** * @implements {UI.Searchable} * @unrestricted @@ -9,6 +10,8 @@ Profiler.ProfileView = class extends UI.SimpleView { constructor() { super(Common.UIString('Profile')); + this._profile = null; + this._searchableView = new UI.SearchableView(this); this._searchableView.setPlaceholder(Common.UIString('Find by cost (>50ms), name or file')); this._searchableView.show(this.element); @@ -62,6 +65,24 @@ Profiler.ProfileView = class extends UI.SimpleView { } /** + * @param {!SDK.ProfileTreeModel} profile + */ + setProfile(profile) { + this._profile = profile; + this._bottomUpProfileDataGridTree = null; + this._topDownProfileDataGridTree = null; + this._changeView(); + this.refresh(); + } + + /** + * @return {?SDK.ProfileTreeModel} + */ + profile() { + return this._profile; + } + + /** * @param {!Profiler.ProfileDataGridNode.Formatter} nodeFormatter * @param {!Array<string>=} viewTypes * @protected @@ -122,7 +143,7 @@ Profiler.ProfileView = class extends UI.SimpleView { /** * @override - * @return {!Array.<!UI.ToolbarItem>} + * @return {!Array<!UI.ToolbarItem>} */ syncToolbarItems() { return [this.viewSelectComboBox, this.focusButton, this.excludeButton, this.resetButton]; @@ -134,7 +155,7 @@ Profiler.ProfileView = class extends UI.SimpleView { _getBottomUpProfileDataGridTree() { if (!this._bottomUpProfileDataGridTree) { this._bottomUpProfileDataGridTree = new Profiler.BottomUpProfileDataGridTree( - this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal); + this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal); } return this._bottomUpProfileDataGridTree; } @@ -145,7 +166,7 @@ Profiler.ProfileView = class extends UI.SimpleView { _getTopDownProfileDataGridTree() { if (!this._topDownProfileDataGridTree) { this._topDownProfileDataGridTree = new Profiler.TopDownProfileDataGridTree( - this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal); + this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal); } return this._topDownProfileDataGridTree; } @@ -158,6 +179,8 @@ Profiler.ProfileView = class extends UI.SimpleView { } refresh() { + if (!this.profileDataGridTree) + return; const selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null; this.dataGrid.rootNode().removeChildren(); @@ -288,7 +311,7 @@ Profiler.ProfileView = class extends UI.SimpleView { } _changeView() { - if (!this.profile) + if (!this._profile) return; this._searchableView.closeSearch(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js index d7d5ffe0aec..eb7ffe825b1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js @@ -328,8 +328,7 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar { if (i !== -1) this._profileToView.splice(i, 1); - const profileType = profile.profileType(); - const typeId = profileType.id; + const typeId = profile.profileType().id; const sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeader(profile); // No other item will be selected if there aren't any other profiles, so @@ -410,11 +409,7 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar { * @return {number} */ _indexOfViewForProfile(profile) { - for (let i = 0; i < this._profileToView.length; i++) { - if (this._profileToView[i].profile === profile) - return i; - } - return -1; + return this._profileToView.findIndex(item => item.profile === profile); } closeVisibleView() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css b/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css index c5f604461b5..7e5ce499e7f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css @@ -70,7 +70,7 @@ flex: auto; } -.heap-snapshot-view .heap-tracking-overview { +.profile-view .heap-tracking-overview { flex: 0 0 80px; height: 80px; } @@ -145,7 +145,7 @@ opacity: 0.6; } -#heap-recording-view .heap-snapshot-view { +#heap-recording-view .profile-view { top: 80px; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js index c8f591949f7..93c140d0d0f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js @@ -36,8 +36,10 @@ Protocol.Error = Symbol('Protocol.Error'); */ Protocol.InspectorBackend = class { constructor() { - this._agentPrototypes = {}; - this._dispatcherPrototypes = {}; + /** @type {!Map<string, !Protocol.InspectorBackend._AgentPrototype>} */ + this._agentPrototypes = new Map(); + /** @type {!Map<string, !Protocol.InspectorBackend._DispatcherPrototype>} */ + this._dispatcherPrototypes = new Map(); this._initialized = false; } @@ -90,12 +92,12 @@ Protocol.InspectorBackend = class { * @return {!Protocol.InspectorBackend._AgentPrototype} */ _agentPrototype(domain) { - if (!this._agentPrototypes[domain]) { - this._agentPrototypes[domain] = new Protocol.InspectorBackend._AgentPrototype(domain); + if (!this._agentPrototypes.has(domain)) { + this._agentPrototypes.set(domain, new Protocol.InspectorBackend._AgentPrototype(domain)); this._addAgentGetterMethodToProtocolTargetPrototype(domain); } - return this._agentPrototypes[domain]; + return this._agentPrototypes.get(domain); } /** @@ -103,9 +105,9 @@ Protocol.InspectorBackend = class { * @return {!Protocol.InspectorBackend._DispatcherPrototype} */ _dispatcherPrototype(domain) { - if (!this._dispatcherPrototypes[domain]) - this._dispatcherPrototypes[domain] = new Protocol.InspectorBackend._DispatcherPrototype(); - return this._dispatcherPrototypes[domain]; + if (!this._dispatcherPrototypes.has(domain)) + this._dispatcherPrototypes.set(domain, new Protocol.InspectorBackend._DispatcherPrototype()); + return this._dispatcherPrototypes.get(domain); } /** @@ -173,167 +175,176 @@ Protocol.InspectorBackend = class { } }; -Protocol.InspectorBackend._ConnectionClosedErrorCode = -32000; -Protocol.InspectorBackend.DevToolsStubErrorCode = -32015; - +Protocol.DevToolsStubErrorCode = -32015; Protocol.inspectorBackend = new Protocol.InspectorBackend(); /** - * @unrestricted + * @interface */ -Protocol.InspectorBackend.Connection = class { +Protocol.Connection = function() {}; + +Protocol.Connection.prototype = { /** - * @param {string} domain - * @param {!Protocol.InspectorBackend.Connection.MessageObject} messageObject + * @param {function((!Object|string))} onMessage */ - sendMessage(domain, messageObject) { - this.sendRawMessage(JSON.stringify(messageObject)); - } + setOnMessage(onMessage) {}, + + /** + * @param {function(string)} onDisconnect + */ + setOnDisconnect(onDisconnect) {}, /** * @param {string} message */ - sendRawMessage(message) {} + sendRawMessage(message) {}, /** * @return {!Promise} */ - disconnect() {} + disconnect() {}, }; -/** - * @typedef {!{ - * id: number, - * method: string, - * params: (!Object|undefined) - * }} - */ -Protocol.InspectorBackend.Connection.MessageObject; +Protocol.test = { + /** + * This will get called for every protocol message. + * Protocol.test.dumpProtocol = console.log + * @type {?function(string)} + */ + dumpProtocol: null, -/** - * @typedef {!{ - * onMessage: function((!Object|string)), - * onDisconnect: function(string) - * }} - */ -Protocol.InspectorBackend.Connection.Params; + /** + * Runs a function when no protocol activity is present. + * Protocol.test.deprecatedRunAfterPendingDispatches(() => console.log('done')) + * @type {?function(function()=)} + */ + deprecatedRunAfterPendingDispatches: null, + + /** + * Sends a raw message over main connection. + * Protocol.test.sendRawMessage('Page.enable', {}, console.log) + */ + sendRawMessage: null, + + /** + * Set to true to not log any errors. + */ + suppressRequestErrors: false, + + /** + * Set to get notified about any messages sent over protocol. + * @type {?function({domain: string, method: string, params: !Object, id: number})} + */ + onMessageSent: null, + + /** + * Set to get notified about any messages received over protocol. + * @type {?function(!Object)} + */ + onMessageReceived: null, +}; /** - * @typedef {function(!Protocol.InspectorBackend.Connection.Params):!Protocol.InspectorBackend.Connection} + * @param {function():!Protocol.Connection} factory */ -Protocol.InspectorBackend.Connection.Factory; +Protocol.Connection.setFactory = function(factory) { + Protocol.Connection._factory = factory; +}; + + +/** @type {function():!Protocol.Connection} */ +Protocol.Connection._factory; /** - * @unrestricted + * Takes error and result. + * @typedef {function(?Object, ?Object)} */ -Protocol.TargetBase = class extends Common.Object { - /** - * @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory - * @param {boolean} isNodeJS - */ - constructor(connectionFactory, isNodeJS) { - super(); - this._connection = - connectionFactory({onMessage: this._onMessage.bind(this), onDisconnect: this._onDisconnect.bind(this)}); +Protocol._Callback; + +// TODO(dgozman): we are not reporting generic errors in tests, but we should +// instead report them and just have some expected errors in test expectations. +Protocol._GenericError = -32000; +Protocol._ConnectionClosedErrorCode = -32001; + +Protocol.SessionRouter = class { + constructor() { + this._connection = Protocol.Connection._factory(); this._lastMessageId = 1; this._pendingResponsesCount = 0; - this._agents = {}; - this._dispatchers = {}; - this._callbacks = {}; - this._initialize(Protocol.inspectorBackend._agentPrototypes, Protocol.inspectorBackend._dispatcherPrototypes); this._domainToLogger = new Map(); - if (!Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches) { - Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches = - this._deprecatedRunAfterPendingDispatches.bind(this); - } - if (!Protocol.InspectorBackend.sendRawMessageForTesting) - Protocol.InspectorBackend.sendRawMessageForTesting = this._sendRawMessageForTesting.bind(this); - this._isNodeJS = isNodeJS; + + /** @type {!Map<string, {target: !Protocol.TargetBase, callbacks: !Map<number, !Protocol._Callback>}>} */ + this._sessions = new Map(); + + /** @type {!Array<function()>} */ + this._pendingScripts = []; + + Protocol.test.deprecatedRunAfterPendingDispatches = this._deprecatedRunAfterPendingDispatches.bind(this); + Protocol.test.sendRawMessage = this._sendRawMessageForTesting.bind(this); + + this._connection.setOnMessage(this._onMessage.bind(this)); + + this._connection.setOnDisconnect(reason => { + const session = this._sessions.get(''); + if (session) + session.target.dispose(reason); + }); } /** - * @param {!Object.<string, !Protocol.InspectorBackend._AgentPrototype>} agentPrototypes - * @param {!Object.<string, !Protocol.InspectorBackend._DispatcherPrototype>} dispatcherPrototypes + * @param {!Protocol.TargetBase} target + * @param {string} sessionId */ - _initialize(agentPrototypes, dispatcherPrototypes) { - for (const domain in agentPrototypes) { - this._agents[domain] = Object.create(agentPrototypes[domain]); - this._agents[domain].setTarget(this); - } - - for (const domain in dispatcherPrototypes) { - this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain]); - this._dispatchers[domain].initialize(); - } + registerSession(target, sessionId) { + this._sessions.set(sessionId, {target, callbacks: new Map()}); } /** - * @return {number} + * @param {string} sessionId */ - _nextMessageId() { - return this._lastMessageId++; + unregisterSession(sessionId) { + const session = this._sessions.get(sessionId); + for (const callback of session.callbacks.values()) + Protocol.SessionRouter.dispatchConnectionError(callback); + this._sessions.delete(sessionId); } /** - * @param {string} domain - * @return {!Protocol.InspectorBackend._AgentPrototype} + * @return {number} */ - _agent(domain) { - return this._agents[domain]; + _nextMessageId() { + return this._lastMessageId++; } /** + * @param {string} sessionId * @param {string} domain * @param {string} method * @param {?Object} params - * @param {?function(*)} callback + * @param {!Protocol._Callback} callback */ - _wrapCallbackAndSendMessageObject(domain, method, params, callback) { - if (!this._connection) { - if (callback) - this._dispatchConnectionErrorResponse(domain, method, callback); - return; - } - + sendMessage(sessionId, domain, method, params, callback) { const messageObject = {}; const messageId = this._nextMessageId(); messageObject.id = messageId; messageObject.method = method; if (params) messageObject.params = params; + if (sessionId) + messageObject.sessionId = sessionId; - const wrappedCallback = this._wrap(callback, domain, method); + if (Protocol.test.dumpProtocol) + Protocol.test.dumpProtocol('frontend: ' + JSON.stringify(messageObject)); - if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages) - this._dumpProtocolMessage('frontend: ' + JSON.stringify(messageObject), '[FE] ' + domain); - if (this.hasEventListeners(Protocol.TargetBase.Events.MessageSent)) { - this.dispatchEventToListeners( - Protocol.TargetBase.Events.MessageSent, - {domain, method, params: JSON.parse(JSON.stringify(params)), id: messageId}); + if (Protocol.test.onMessageSent) { + const paramsObject = JSON.parse(JSON.stringify(params || {})); + Protocol.test.onMessageSent({domain, method, params: /** @type {!Object} */ (paramsObject), id: messageId}); } - this._connection.sendMessage(domain, messageObject); ++this._pendingResponsesCount; - this._callbacks[messageId] = wrappedCallback; - } - - /** - * @param {?function(*)} callback - * @param {string} method - * @param {string} domain - * @return {function(*)} - */ - _wrap(callback, domain, method) { - if (!callback) - callback = function() {}; - - callback.methodName = method; - callback.domain = domain; - if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats) - callback.sendRequestTime = Date.now(); - - return callback; + this._sessions.get(sessionId).callbacks.set(messageId, callback); + this._connection.sendRawMessage(JSON.stringify(messageObject)); } /** @@ -343,47 +354,45 @@ Protocol.TargetBase = class extends Common.Object { */ _sendRawMessageForTesting(method, params, callback) { const domain = method.split('.')[0]; - this._wrapCallbackAndSendMessageObject(domain, method, params, callback); + this.sendMessage('', domain, method, params, callback || (() => {})); } /** * @param {!Object|string} message */ _onMessage(message) { - if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages) { - this._dumpProtocolMessage( - 'backend: ' + ((typeof message === 'string') ? message : JSON.stringify(message)), 'Backend'); - } - if (this.hasEventListeners(Protocol.TargetBase.Events.MessageReceived)) { - this.dispatchEventToListeners(Protocol.TargetBase.Events.MessageReceived, { - message: JSON.parse((typeof message === 'string') ? message : JSON.stringify(message)), - }); - } + if (Protocol.test.dumpProtocol) + Protocol.test.dumpProtocol('backend: ' + ((typeof message === 'string') ? message : JSON.stringify(message))); + if (Protocol.test.onMessageReceived) { + const messageObjectCopy = JSON.parse((typeof message === 'string') ? message : JSON.stringify(message)); + Protocol.test.onMessageReceived(/** @type {!Object} */ (messageObjectCopy)); + } const messageObject = /** @type {!Object} */ ((typeof message === 'string') ? JSON.parse(message) : message); - Protocol.NodeURL.patch(this, messageObject); + const sessionId = messageObject.sessionId || ''; + const session = this._sessions.get(sessionId); + if (!session) { + Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message with wrong session id', messageObject); + return; + } + + if (session.target._needsNodeJSPatching) + Protocol.NodeURL.patch(messageObject); if ('id' in messageObject) { // just a response for some request - const callback = this._callbacks[messageObject.id]; + const callback = session.callbacks.get(messageObject.id); + session.callbacks.delete(messageObject.id); if (!callback) { Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message with wrong id', messageObject); return; } - const timingLabel = 'time-stats: ' + callback.methodName; - if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats) - Protocol.InspectorBackend._timeLogger.time(timingLabel); - - this._agent(callback.domain).dispatchResponse(messageObject, callback.methodName, callback); + callback(messageObject.error, messageObject.result); --this._pendingResponsesCount; - delete this._callbacks[messageObject.id]; - - if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats) - Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel); - if (this._scripts && !this._pendingResponsesCount) + if (this._pendingScripts.length && !this._pendingResponsesCount) this._deprecatedRunAfterPendingDispatches(); } else { if (!('method' in messageObject)) { @@ -393,135 +402,115 @@ Protocol.TargetBase = class extends Common.Object { const method = messageObject.method.split('.'); const domainName = method[0]; - if (!(domainName in this._dispatchers)) { + if (!(domainName in session.target._dispatchers)) { Protocol.InspectorBackend.reportProtocolError( `Protocol Error: the message ${messageObject.method} is for non-existing domain '${domainName}'`, messageObject); return; } - this._dispatchers[domainName].dispatch(method[1], messageObject); + session.target._dispatchers[domainName].dispatch(method[1], messageObject); } } /** - * @param {string} domain - * @param {!Object} dispatcher - */ - registerDispatcher(domain, dispatcher) { - if (!this._dispatchers[domain]) - return; - - this._dispatchers[domain].addDomainDispatcher(dispatcher); - } - - /** * @param {function()=} script */ _deprecatedRunAfterPendingDispatches(script) { - if (!this._scripts) - this._scripts = []; - if (script) - this._scripts.push(script); + this._pendingScripts.push(script); // Execute all promises. - setTimeout(function() { + setTimeout(() => { if (!this._pendingResponsesCount) this._executeAfterPendingDispatches(); else this._deprecatedRunAfterPendingDispatches(); - }.bind(this), 0); + }, 0); } _executeAfterPendingDispatches() { if (!this._pendingResponsesCount) { - const scripts = this._scripts; - this._scripts = []; + const scripts = this._pendingScripts; + this._pendingScripts = []; for (let id = 0; id < scripts.length; ++id) - scripts[id].call(this); + scripts[id](); } } /** - * @param {string} message - * @param {string} context + * @param {!Protocol._Callback} callback */ - _dumpProtocolMessage(message, context) { - if (!this._domainToLogger.get(context)) - this._domainToLogger.set(context, console.context ? console.context(context) : console); - const logger = this._domainToLogger.get(context); - logger.log(message); + static dispatchConnectionError(callback) { + const error = { + message: 'Connection is closed, can\'t dispatch pending call', + code: Protocol._ConnectionClosedErrorCode, + data: null + }; + setTimeout(() => callback(error, null), 0); } +}; +/** + * @unrestricted + */ +Protocol.TargetBase = class { /** - * @param {string} reason + * @param {boolean} needsNodeJSPatching + * @param {?Protocol.TargetBase} parentTarget + * @param {string} sessionId */ - _onDisconnect(reason) { - this._connection = null; - this._runPendingCallbacks(); - this.dispose(); - } + constructor(needsNodeJSPatching, parentTarget, sessionId) { + this._needsNodeJSPatching = needsNodeJSPatching; + this._sessionId = sessionId; - /** - * @protected - */ - dispose() { - } + this._router = parentTarget ? parentTarget._router : new Protocol.SessionRouter(); + this._router.registerSession(this, this._sessionId); - /** - * @return {boolean} - */ - isDisposed() { - return !this._connection; - } + this._agents = {}; + for (const [domain, agentPrototype] of Protocol.inspectorBackend._agentPrototypes) { + this._agents[domain] = Object.create(/** @type {!Protocol.InspectorBackend._AgentPrototype} */ (agentPrototype)); + this._agents[domain]._target = this; + } - _runPendingCallbacks() { - const keys = Object.keys(this._callbacks).map(function(num) { - return parseInt(num, 10); - }); - for (let i = 0; i < keys.length; ++i) { - const callback = this._callbacks[keys[i]]; - this._dispatchConnectionErrorResponse(callback.domain, callback.methodName, callback); + this._dispatchers = {}; + for (const [domain, dispatcherPrototype] of Protocol.inspectorBackend._dispatcherPrototypes) { + this._dispatchers[domain] = + Object.create(/** @type {!Protocol.InspectorBackend._DispatcherPrototype} */ (dispatcherPrototype)); + this._dispatchers[domain]._dispatchers = []; } - this._callbacks = {}; } /** * @param {string} domain - * @param {string} methodName - * @param {function(*)} callback + * @param {!Object} dispatcher */ - _dispatchConnectionErrorResponse(domain, methodName, callback) { - const error = { - message: 'Connection is closed, can\'t dispatch pending ' + methodName, - code: Protocol.InspectorBackend._ConnectionClosedErrorCode, - data: null - }; - const messageObject = {error: error}; - setTimeout( - Protocol.InspectorBackend._AgentPrototype.prototype.dispatchResponse.bind( - this._agent(domain), messageObject, methodName, callback), - 0); + registerDispatcher(domain, dispatcher) { + if (!this._dispatchers[domain]) + return; + this._dispatchers[domain].addDomainDispatcher(dispatcher); + } + + /** + * @param {string} reason + */ + dispose(reason) { + this._router.unregisterSession(this._sessionId); + this._router = null; } /** * @return {boolean} */ - isNodeJS() { - return this._isNodeJS; + isDisposed() { + return !this._router; } markAsNodeJSForTest() { - this._isNodeJS = true; + this._needsNodeJSPatching = true; } }; -Protocol.TargetBase.Events = { - MessageSent: Symbol('MessageSent'), - MessageReceived: Symbol('MessageReceived') -}; - /** * @unrestricted */ @@ -536,13 +525,6 @@ Protocol.InspectorBackend._AgentPrototype = class { } /** - * @param {!Protocol.TargetBase} target - */ - setTarget(target) { - this._target = target; - } - - /** * @param {string} methodName * @param {!Array.<!Object>} signature * @param {!Array.<string>} replyArgs @@ -646,14 +628,24 @@ Protocol.InspectorBackend._AgentPrototype = class { return Promise.resolve(null); return new Promise(resolve => { - this._target._wrapCallbackAndSendMessageObject(this._domain, method, params, (error, result) => { + const callback = (error, result) => { + if (error && !Protocol.test.suppressRequestErrors && error.code !== Protocol.DevToolsStubErrorCode && + error.code !== Protocol._GenericError && error.code !== Protocol._ConnectionClosedErrorCode) + console.error('Request ' + method + ' failed. ' + JSON.stringify(error)); + + if (error) { resolve(null); return; } const args = this._replyArgs[method]; resolve(result && args.length ? result[args[0]] : undefined); - }); + }; + + if (!this._target._router) + Protocol.SessionRouter.dispatchConnectionError(callback); + else + this._target._router.sendMessage(this._target._sessionId, this._domain, method, params, callback); }); } @@ -664,30 +656,24 @@ Protocol.InspectorBackend._AgentPrototype = class { */ _invoke(method, request) { return new Promise(fulfill => { - this._target._wrapCallbackAndSendMessageObject(this._domain, method, request, (error, result) => { + const callback = (error, result) => { + if (error && !Protocol.test.suppressRequestErrors && error.code !== Protocol.DevToolsStubErrorCode && + error.code !== Protocol._GenericError && error.code !== Protocol._ConnectionClosedErrorCode) + console.error('Request ' + method + ' failed. ' + JSON.stringify(error)); + + if (!result) result = {}; if (error) result[Protocol.Error] = error.message; fulfill(result); - }); - }); - } + }; - /** - * @param {!Object} messageObject - * @param {string} methodName - * @param {function(?Protocol.Error, ?Object)} callback - */ - dispatchResponse(messageObject, methodName, callback) { - if (messageObject.error && messageObject.error.code !== Protocol.InspectorBackend._ConnectionClosedErrorCode && - messageObject.error.code !== Protocol.InspectorBackend.DevToolsStubErrorCode && - !Protocol.InspectorBackend.Options.suppressRequestErrors) { - const id = - Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages ? ' with id = ' + messageObject.id : ''; - console.error('Request ' + methodName + id + ' failed. ' + JSON.stringify(messageObject.error)); - } - callback(messageObject.error, messageObject.result); + if (!this._target._router) + Protocol.SessionRouter.dispatchConnectionError(callback); + else + this._target._router.sendMessage(this._target._sessionId, this._domain, method, request, callback); + }); } }; @@ -707,10 +693,6 @@ Protocol.InspectorBackend._DispatcherPrototype = class { this._eventArgs[eventName] = params; } - initialize() { - this._dispatchers = []; - } - /** * @param {!Object} dispatcher */ @@ -739,25 +721,10 @@ Protocol.InspectorBackend._DispatcherPrototype = class { params.push(messageObject.params[paramNames[i]]); } - const timingLabel = 'time-stats: ' + messageObject.method; - if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats) - Protocol.InspectorBackend._timeLogger.time(timingLabel); - for (let index = 0; index < this._dispatchers.length; ++index) { const dispatcher = this._dispatchers[index]; if (functionName in dispatcher) dispatcher[functionName].apply(dispatcher, params); } - - if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats) - Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel); } }; - -Protocol.InspectorBackend.Options = { - dumpInspectorTimeStats: false, - dumpInspectorProtocolMessages: false, - suppressRequestErrors: false -}; - -Protocol.InspectorBackend._timeLogger = console.context ? console.context('Protocol timing') : console; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/protocol/NodeURL.js b/chromium/third_party/blink/renderer/devtools/front_end/protocol/NodeURL.js index b4234cb34da..e69d057cff2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/protocol/NodeURL.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/protocol/NodeURL.js @@ -4,12 +4,10 @@ Protocol.NodeURL = class { /** - * @param {!Protocol.TargetBase} target * @param {!Object} object */ - static patch(target, object) { - if (target.isNodeJS()) - process(object, ''); + static patch(object) { + process(object, ''); /** * @param {!Object} object diff --git a/chromium/third_party/blink/renderer/devtools/front_end/protocol_monitor/ProtocolMonitor.js b/chromium/third_party/blink/renderer/devtools/front_end/protocol_monitor/ProtocolMonitor.js index 540000ca01f..b7208303b3e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/protocol_monitor/ProtocolMonitor.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/protocol_monitor/ProtocolMonitor.js @@ -6,7 +6,6 @@ ProtocolMonitor.ProtocolMonitor = class extends UI.VBox { constructor() { super(true); this._nodes = []; - this._recordingListeners = null; this._started = false; this._startTime = 0; this._nodeForId = {}; @@ -151,22 +150,16 @@ ProtocolMonitor.ProtocolMonitor = class extends UI.VBox { * @param {boolean} recording */ _setRecording(recording) { - if (this._recordingListeners) { - Common.EventTarget.removeEventListeners(this._recordingListeners); - this._recordingListeners = null; - } - if (recording) { - this._recordingListeners = [ - SDK.targetManager.mainTarget().addEventListener( - Protocol.TargetBase.Events.MessageReceived, this._messageRecieved, this), - SDK.targetManager.mainTarget().addEventListener(Protocol.TargetBase.Events.MessageSent, this._messageSent, this) - ]; + Protocol.test.onMessageSent = this._messageSent.bind(this); + Protocol.test.onMessageReceived = this._messageRecieved.bind(this); + } else { + Protocol.test.onMessageSent = null; + Protocol.test.onMessageReceived = null; } } - _messageRecieved(event) { - const message = event.data.message; + _messageRecieved(message) { if ('id' in message) { const node = this._nodeForId[message.id]; if (!node) @@ -189,8 +182,7 @@ ProtocolMonitor.ProtocolMonitor = class extends UI.VBox { this._dataGrid.insertChild(node); } - _messageSent(event) { - const message = event.data; + _messageSent(message) { const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({ method: message.method, direction: 'sent', diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js index 6057f5882e9..58cef467d77 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js @@ -159,7 +159,7 @@ Resources.AppManifestView = class extends UI.VBox { */ _addToHomescreen(event) { const target = SDK.targetManager.mainTarget(); - if (target && target.hasBrowserCapability()) { + if (target && target.type() === SDK.Target.Type.Frame) { target.pageAgent().requestAppBanner(); Common.console.show(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/ClearStorageView.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/ClearStorageView.js index 0872cfaf833..89ff44d6393 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/ClearStorageView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/ClearStorageView.js @@ -36,6 +36,11 @@ Resources.ClearStorageView = class extends UI.ThrottledWidget { const quota = this._reportView.appendSection(Common.UIString('Usage')); this._quotaRow = quota.appendRow(); + const learnMoreRow = quota.appendRow(); + const learnMore = UI.XLink.create( + 'https://developers.google.com/web/tools/chrome-devtools/progressive-web-apps#opaque-responses', + ls`Learn more`); + learnMoreRow.appendChild(learnMore); this._quotaUsage = null; this._pieChart = new PerfUI.PieChart(110, Number.bytesToString, true); this._pieChartLegend = createElement('div'); @@ -44,6 +49,10 @@ Resources.ClearStorageView = class extends UI.ThrottledWidget { usageBreakdownRow.appendChild(this._pieChart.element); usageBreakdownRow.appendChild(this._pieChartLegend); + const clearButtonSection = this._reportView.appendSection('', 'clear-storage-button').appendRow(); + this._clearButton = UI.createTextButton(ls`Clear site data`, this._clear.bind(this)); + clearButtonSection.appendChild(this._clearButton); + const application = this._reportView.appendSection(Common.UIString('Application')); this._appendItem(application, Common.UIString('Unregister service workers'), 'service_workers'); @@ -57,11 +66,7 @@ Resources.ClearStorageView = class extends UI.ThrottledWidget { this._appendItem(caches, Common.UIString('Cache storage'), 'cache_storage'); this._appendItem(caches, Common.UIString('Application cache'), 'appcache'); - SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser); - const footer = this._reportView.appendSection('', 'clear-storage-button').appendRow(); - this._clearButton = UI.createTextButton( - Common.UIString('Clear site data'), this._clear.bind(this), Common.UIString('Clear site data')); - footer.appendChild(this._clearButton); + SDK.targetManager.observeTargets(this); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js index 65ec8edfceb..c102c67324a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js @@ -223,13 +223,9 @@ Resources.IDBDataView = class extends UI.SimpleView { this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this); editorToolbar.appendToolbarItem(this._pageForwardButton); - this._keyInputElement = UI.createInput('toolbar-input'); - editorToolbar.appendToolbarItem(new UI.ToolbarItem(this._keyInputElement)); - this._keyInputElement.placeholder = Common.UIString('Start from key'); - this._keyInputElement.addEventListener('paste', this._keyInputChanged.bind(this), false); - this._keyInputElement.addEventListener('cut', this._keyInputChanged.bind(this), false); - this._keyInputElement.addEventListener('keypress', this._keyInputChanged.bind(this), false); - this._keyInputElement.addEventListener('keydown', this._keyInputChanged.bind(this), false); + this._keyInput = new UI.ToolbarInput(ls`Start from key`, 0.5); + this._keyInput.addEventListener(UI.ToolbarInput.Event.TextChanged, this._updateData.bind(this, false)); + editorToolbar.appendToolbarItem(this._keyInput); editorToolbar.appendToolbarItem(this._needsRefresh); } @@ -250,10 +246,6 @@ Resources.IDBDataView = class extends UI.SimpleView { this._updateData(false); } - _keyInputChanged() { - window.setTimeout(this._updateData.bind(this, false), 0); - } - refreshData() { this._updateData(true); } @@ -292,7 +284,7 @@ Resources.IDBDataView = class extends UI.SimpleView { * @param {boolean} force */ _updateData(force) { - const key = this._parseKey(this._keyInputElement.value); + const key = this._parseKey(this._keyInput.value()); const pageSize = this._pageSize; let skipCount = this._skipCount; let selected = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.data['number'] : 0; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js index 642804df148..1b43324e8df 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js @@ -98,6 +98,7 @@ Resources.ServiceWorkerCacheView = class extends UI.SimpleView { _createDataGrid() { const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([ {id: 'path', title: Common.UIString('Path'), weight: 4, sortable: true}, + {id: 'responseType', title: ls`Response-Type`, weight: 1, align: DataGrid.DataGrid.Align.Right, sortable: true}, {id: 'contentType', title: Common.UIString('Content-Type'), weight: 1, sortable: true}, { id: 'contentLength', title: Common.UIString('Content-Length'), @@ -214,7 +215,7 @@ Resources.ServiceWorkerCacheView = class extends UI.SimpleView { for (const entry of entries) { let node = oldEntries.get(entry.requestURL); if (!node || node.data.responseTime !== entry.responseTime) { - node = new Resources.ServiceWorkerCacheView.DataGridNode(this._createRequest(entry)); + node = new Resources.ServiceWorkerCacheView.DataGridNode(this._createRequest(entry), entry.responseType); node.selectable = true; } rootNode.appendChild(node); @@ -335,13 +336,15 @@ Resources.ServiceWorkerCacheView._RESPONSE_CACHE_SIZE = 10; Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridNode { /** * @param {!SDK.NetworkRequest} request + * @param {!Protocol.CacheStorage.CachedResponseType} responseType */ - constructor(request) { + constructor(request, responseType) { super(request); this._path = Common.ParsedURL.extractPath(request.url()); if (!this._path) this._path = request.url(); this._request = request; + this._responseType = responseType; } /** @@ -352,14 +355,22 @@ Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridN createCell(columnId) { const cell = this.createTD(columnId); let value; - if (columnId === 'path') + if (columnId === 'path') { value = this._path; - else if (columnId === 'contentType') + } else if (columnId === 'responseType') { + if (this._responseType === 'opaqueResponse') + value = 'opaque'; + else if (this._responseType === 'opaqueRedirect') + value = 'opaqueredirect'; + else + value = this._responseType; + } else if (columnId === 'contentType') { value = this._request.mimeType; - else if (columnId === 'contentLength') + } else if (columnId === 'contentLength') { value = (this._request.resourceSize | 0).toLocaleString('en-US'); - else if (columnId === 'responseTime') + } else if (columnId === 'responseTime') { value = new Date(this._request.endTime * 1000).toLocaleString(); + } DataGrid.DataGrid.setElementText(cell, value || '', true); return cell; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js index 6e9691ffe1f..c0ef89cb815 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js @@ -34,6 +34,8 @@ Resources.ServiceWorkersView = class extends UI.VBox { this._otherSWFilter.setAttribute('role', 'switch'); this._otherSWFilter.setAttribute('aria-checked', false); this._otherSWFilter.addEventListener('keydown', event => { + if (event.target !== this._otherSWFilter) + return; if (isEnterKey(event) || event.keyCode === UI.KeyboardShortcut.Keys.Space.code) this._toggleFilter(); }); @@ -534,12 +536,14 @@ Resources.ServiceWorkersView.Section = class { */ _updateClientInfo(element, targetInfo) { if (targetInfo.type !== 'page' && targetInfo.type === 'iframe') { - element.createTextChild(Common.UIString('Worker: %s', targetInfo.url)); + const clientString = element.createChild('span', 'service-worker-client-string'); + clientString.createTextChild(ls`Worker: ` + targetInfo.url); return; } element.removeChildren(); - element.createTextChild(targetInfo.url); - const focusLabel = element.createChild('label', 'link'); + const clientString = element.createChild('span', 'service-worker-client-string'); + clientString.createTextChild(targetInfo.url); + const focusLabel = element.createChild('label', 'link service-worker-client-focus-link'); focusLabel.createTextChild('focus'); focusLabel.addEventListener('click', this._activateTarget.bind(this, targetInfo.targetId), true); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/clearStorageView.css b/chromium/third_party/blink/renderer/devtools/front_end/resources/clearStorageView.css index abbed68132e..9cb3cf5061a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/clearStorageView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/clearStorageView.css @@ -10,7 +10,7 @@ } .clear-storage-button .report-row { - margin: 0 0 0 20px; + margin: 0 0 0 17px; display: flex; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/module.json b/chromium/third_party/blink/renderer/devtools/front_end/resources/module.json index a7034611092..9a0157046b4 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/module.json @@ -6,7 +6,8 @@ "id": "resources", "title": "Application", "order": 70, - "className": "Resources.ResourcesPanel" + "className": "Resources.ResourcesPanel", + "tags": "pwa" }, { "type": "@Common.Revealer", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/serviceWorkersView.css b/chromium/third_party/blink/renderer/devtools/front_end/resources/serviceWorkersView.css index b18d04c89c8..e10e38f2b8a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/serviceWorkersView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/serviceWorkersView.css @@ -107,6 +107,22 @@ min-width: 80px; } +.report-field-value-filename, +.service-worker-client-string { + max-width: 400px; + overflow: hidden; + text-overflow: ellipsis; +} + +.service-worker-client { + display: flex; +} + +.service-worker-client-focus-link { + flex: none; + margin-right: 5px; +} + .service-worker-notification-editor.source-code { /** Simulate CodeMirror that is shown above */ padding: 4px; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js index 559e26aa151..2af3af65392 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js @@ -17,20 +17,20 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { /** @type {!Map<string, !Protocol.Target.TargetInfo>} */ this._targetInfos = new Map(); - /** @type {!Map<string, !SDK.ChildConnection>} */ - this._childConnections = new Map(); + /** @type {!Map<string, !SDK.Target>} */ + this._childTargets = new Map(); parentTarget.registerTargetDispatcher(this); - this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}); + this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true}); - if (!parentTarget.parentTarget()) { + if (!parentTarget.parentTarget() && !Host.isUnderTest()) { this._targetAgent.setDiscoverTargets(true); this._targetAgent.setRemoteLocations([{host: 'localhost', port: 9229}]); } } /** - * @param {function({target: !SDK.Target, waitingForDebugger: boolean})=} attachCallback + * @param {function({target: !SDK.Target, waitingForDebugger: boolean}):!Promise=} attachCallback */ static install(attachCallback) { SDK.ChildTargetManager._attachCallback = attachCallback; @@ -42,7 +42,7 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { * @return {!Promise} */ suspendModel() { - return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false}); + return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false, flatten: true}); } /** @@ -50,37 +50,18 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { * @return {!Promise} */ resumeModel() { - return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}); + return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true}); } /** * @override */ dispose() { - for (const sessionId of this._childConnections.keys()) + for (const sessionId of this._childTargets.keys()) this.detachedFromTarget(sessionId, undefined); } /** - * @param {string} type - * @return {number} - */ - _capabilitiesForType(type) { - if (type === 'worker') { - return SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network | - SDK.Target.Capability.Target; - } - if (type === 'service_worker') - return SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target; - if (type === 'iframe') { - return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS | - SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target | - SDK.Target.Capability.Tracing | SDK.Target.Capability.Emulation | SDK.Target.Capability.Input; - } - return 0; - } - - /** * @override * @param {!Protocol.Target.TargetInfo} targetInfo */ @@ -134,13 +115,26 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + (++SDK.ChildTargetManager._lastAnonymousTargetId); } - const target = this._targetManager.createTarget( - targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type), - this._createChildConnection.bind(this, this._targetAgent, sessionId), this._parentTarget, false /* isNodeJS */); - if (SDK.ChildTargetManager._attachCallback) - SDK.ChildTargetManager._attachCallback({target, waitingForDebugger}); - target.runtimeAgent().runIfWaitingForDebugger(); + let type = SDK.Target.Type.Browser; + if (targetInfo.type === 'iframe') + type = SDK.Target.Type.Frame; + else if (targetInfo.type === 'worker') + type = SDK.Target.Type.Worker; + else if (targetInfo.type === 'service_worker') + type = SDK.Target.Type.ServiceWorker; + + const target = + this._targetManager.createTarget(targetInfo.targetId, targetName, type, this._parentTarget, sessionId); + this._childTargets.set(sessionId, target); + + if (SDK.ChildTargetManager._attachCallback) { + SDK.ChildTargetManager._attachCallback({target, waitingForDebugger}).then(() => { + target.runtimeAgent().runIfWaitingForDebugger(); + }); + } else { + target.runtimeAgent().runIfWaitingForDebugger(); + } } /** @@ -149,8 +143,8 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { * @param {string=} childTargetId */ detachedFromTarget(sessionId, childTargetId) { - this._childConnections.get(sessionId).onDisconnect.call(null, 'target terminated'); - this._childConnections.delete(sessionId); + this._childTargets.get(sessionId).dispose('target terminated'); + this._childTargets.delete(sessionId); } /** @@ -160,21 +154,7 @@ SDK.ChildTargetManager = class extends SDK.SDKModel { * @param {string=} childTargetId */ receivedMessageFromTarget(sessionId, message, childTargetId) { - const connection = this._childConnections.get(sessionId); - if (connection) - connection.onMessage.call(null, message); - } - - /** - * @param {!Protocol.TargetAgent} agent - * @param {string} sessionId - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createChildConnection(agent, sessionId, params) { - const connection = new SDK.ChildConnection(agent, sessionId, params); - this._childConnections.set(sessionId, connection); - return connection; + // We use flatten protocol. } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js index 112423b791f..7bd231e8c56 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js @@ -3,17 +3,14 @@ // found in the LICENSE file. /** - * @unrestricted + * @implements {Protocol.Connection} */ -SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { - /** - * @param {!Protocol.InspectorBackend.Connection.Params} params - */ - constructor(params) { - super(); - this._onMessage = params.onMessage; - this._onDisconnect = params.onDisconnect; - this._disconnected = false; +SDK.MainConnection = class { + constructor() { + this._onMessage = null; + this._onDisconnect = null; + this._messageBuffer = ''; + this._messageSize = 0; this._eventListeners = [ InspectorFrontendHost.events.addEventListener( InspectorFrontendHostAPI.Events.DispatchMessage, this._dispatchMessage, this), @@ -24,10 +21,26 @@ SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { /** * @override + * @param {function((!Object|string))} onMessage + */ + setOnMessage(onMessage) { + this._onMessage = onMessage; + } + + /** + * @override + * @param {function(string)} onDisconnect + */ + setOnDisconnect(onDisconnect) { + this._onDisconnect = onDisconnect; + } + + /** + * @override * @param {string} message */ sendRawMessage(message) { - if (!this._disconnected) + if (this._onMessage) InspectorFrontendHost.sendMessageToBackend(message); } @@ -35,7 +48,8 @@ SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { * @param {!Common.Event} event */ _dispatchMessage(event) { - this._onMessage.call(null, /** @type {string} */ (event.data)); + if (this._onMessage) + this._onMessage.call(null, /** @type {string} */ (event.data)); } /** @@ -65,12 +79,12 @@ SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { Common.EventTarget.removeEventListeners(this._eventListeners); this._onDisconnect = null; this._onMessage = null; - this._disconnected = true; let fulfill; const promise = new Promise(f => fulfill = f); InspectorFrontendHost.reattach(() => { - onDisconnect.call(null, 'force disconnect'); + if (onDisconnect) + onDisconnect.call(null, 'force disconnect'); fulfill(); }); return promise; @@ -78,28 +92,46 @@ SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { }; /** - * @unrestricted + * @implements {Protocol.Connection} */ -SDK.WebSocketConnection = class extends Protocol.InspectorBackend.Connection { +SDK.WebSocketConnection = class { /** * @param {string} url * @param {function()} onWebSocketDisconnect - * @param {!Protocol.InspectorBackend.Connection.Params} params */ - constructor(url, onWebSocketDisconnect, params) { - super(); + constructor(url, onWebSocketDisconnect) { this._socket = new WebSocket(url); this._socket.onerror = this._onError.bind(this); this._socket.onopen = this._onOpen.bind(this); - this._socket.onmessage = messageEvent => params.onMessage.call(null, /** @type {string} */ (messageEvent.data)); + this._socket.onmessage = messageEvent => { + if (this._onMessage) + this._onMessage.call(null, /** @type {string} */ (messageEvent.data)); + }; this._socket.onclose = this._onClose.bind(this); - this._onDisconnect = params.onDisconnect; + this._onMessage = null; + this._onDisconnect = null; this._onWebSocketDisconnect = onWebSocketDisconnect; this._connected = false; this._messages = []; } + /** + * @override + * @param {function((!Object|string))} onMessage + */ + setOnMessage(onMessage) { + this._onMessage = onMessage; + } + + /** + * @override + * @param {function(string)} onDisconnect + */ + setOnDisconnect(onDisconnect) { + this._onDisconnect = onDisconnect; + } + _onError() { this._onWebSocketDisconnect.call(null); // This is called if error occurred while connecting. @@ -153,7 +185,8 @@ SDK.WebSocketConnection = class extends Protocol.InspectorBackend.Connection { let fulfill; const promise = new Promise(f => fulfill = f); this._close(() => { - this._onDisconnect.call(null, 'force disconnect'); + if (this._onDisconnect) + this._onDisconnect.call(null, 'force disconnect'); fulfill(); }); return promise; @@ -161,16 +194,28 @@ SDK.WebSocketConnection = class extends Protocol.InspectorBackend.Connection { }; /** - * @unrestricted + * @implements {Protocol.Connection} */ -SDK.StubConnection = class extends Protocol.InspectorBackend.Connection { +SDK.StubConnection = class { + constructor() { + this._onMessage = null; + this._onDisconnect = null; + } + /** - * @param {!Protocol.InspectorBackend.Connection.Params} params + * @override + * @param {function((!Object|string))} onMessage */ - constructor(params) { - super(); - this._onMessage = params.onMessage; - this._onDisconnect = params.onDisconnect; + setOnMessage(onMessage) { + this._onMessage = onMessage; + } + + /** + * @override + * @param {function(string)} onDisconnect + */ + setOnDisconnect(onDisconnect) { + this._onDisconnect = onDisconnect; } /** @@ -188,10 +233,11 @@ SDK.StubConnection = class extends Protocol.InspectorBackend.Connection { const messageObject = JSON.parse(message); const error = { message: 'This is a stub connection, can\'t dispatch message.', - code: Protocol.InspectorBackend.DevToolsStubErrorCode, + code: Protocol.DevToolsStubErrorCode, data: messageObject }; - this._onMessage.call(null, {id: messageObject.id, error: error}); + if (this._onMessage) + this._onMessage.call(null, {id: messageObject.id, error: error}); } /** @@ -199,59 +245,60 @@ SDK.StubConnection = class extends Protocol.InspectorBackend.Connection { * @return {!Promise} */ disconnect() { - this._onDisconnect.call(null, 'force disconnect'); + if (this._onDisconnect) + this._onDisconnect.call(null, 'force disconnect'); this._onDisconnect = null; this._onMessage = null; return Promise.resolve(); } }; -SDK.ChildConnection = class extends Protocol.InspectorBackend.Connection { - /** - * @param {!Protocol.TargetAgent} agent - * @param {string} sessionId - * @param {!Protocol.InspectorBackend.Connection.Params} params - */ - constructor(agent, sessionId, params) { - super(); - this._agent = agent; - this._sessionId = sessionId; - this.onMessage = params.onMessage; - this.onDisconnect = params.onDisconnect; - } - - /** - * @override - * @param {string} message - */ - sendRawMessage(message) { - this._agent.sendMessageToTarget(message, this._sessionId); - } - - /** - * @override - * @return {!Promise} - */ - disconnect() { - throw 'Not implemented'; - } +/** + * @param {function()} createMainTarget + * @param {function()} websocketConnectionLost + */ +SDK.initMainConnection = function(createMainTarget, websocketConnectionLost) { + SDK._websocketConnectionLost = websocketConnectionLost; + SDK._createMainTarget = createMainTarget; + Protocol.Connection.setFactory(SDK._createMainConnection); + SDK._createMainTarget(); + InspectorFrontendHost.connectionReady(); }; /** - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @param {function()} connectionLostCallback - * @return {!Protocol.InspectorBackend.Connection} + * @return {!Protocol.Connection} */ -SDK.createMainConnection = function(params, connectionLostCallback) { +SDK._createMainConnection = function() { const wsParam = Runtime.queryParam('ws'); const wssParam = Runtime.queryParam('wss'); - if (wsParam || wssParam) { const ws = wsParam ? `ws://${wsParam}` : `wss://${wssParam}`; - return new SDK.WebSocketConnection(ws, connectionLostCallback, params); + SDK._mainConnection = new SDK.WebSocketConnection(ws, SDK._websocketConnectionLost); + } else if (InspectorFrontendHost.isHostedMode()) { + SDK._mainConnection = new SDK.StubConnection(); + } else { + SDK._mainConnection = new SDK.MainConnection(); } + return SDK._mainConnection; +}; + +/** @type {!Protocol.Connection} */ +SDK._mainConnection; - if (InspectorFrontendHost.isHostedMode()) - return new SDK.StubConnection(params); - return new SDK.MainConnection(params); +/** @type {function()} */ +SDK._createMainTarget; + +/** @type {function()} */ +SDK._websocketConnectionLost; + +/** + * @param {function((!Object|string))} onMessage + * @return {!Promise<!Protocol.Connection>} + */ +SDK.interceptMainConnection = async function(onMessage) { + await SDK._mainConnection.disconnect(); + const connection = SDK._createMainConnection(); + connection.setOnMessage(onMessage); + connection.setOnDisconnect(SDK._createMainTarget); + return connection; }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DOMModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DOMModel.js index 65be108c064..eebd73a792d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DOMModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DOMModel.js @@ -1594,9 +1594,11 @@ SDK.DOMModel = class extends SDK.SDKModel { * @param {boolean} includeUserAgentShadowDOM * @return {!Promise<?SDK.DOMNode>} */ - nodeForLocation(x, y, includeUserAgentShadowDOM) { - return this._agent.getNodeForLocation(x, y, includeUserAgentShadowDOM) - .then(nodeId => nodeId ? this.nodeForId(nodeId) : null); + async nodeForLocation(x, y, includeUserAgentShadowDOM) { + const response = await this._agent.invoke_getNodeForLocation({x, y, includeUserAgentShadowDOM}); + if (response[Protocol.Error] || !response.nodeId) + return null; + return this.nodeForId(response.nodeId); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js index ac6ec6fe0f9..d77ced84d19 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js @@ -136,6 +136,14 @@ SDK.DebuggerModel = class extends SDK.SDKModel { return; SDK.DebuggerModel._debuggerIdToModel.set(debuggerId, this); this._debuggerId = debuggerId; + this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerIsReadyToPause, this); + } + + /** + * @return {boolean} + */ + isReadyToPause() { + return !!this._debuggerId; } /** @@ -220,6 +228,9 @@ SDK.DebuggerModel = class extends SDK.SDKModel { } scheduleStepIntoAsync() { + // Node v8.x does not support breakOnAsyncCall flag but supports old style schdeuleStepIntoAsync. + // End-of-life of Node 8.x is around December 2019. + this._agent.scheduleStepIntoAsync(); this._agent.invoke_stepInto({breakOnAsyncCall: true}); } @@ -252,7 +263,7 @@ SDK.DebuggerModel = class extends SDK.SDKModel { async setBreakpointByURL(url, lineNumber, columnNumber, condition) { // Convert file url to node-js path. let urlRegex; - if (this.target().isNodeJS()) { + if (this.target().type() === SDK.Target.Type.Node) { const platformPath = Common.ParsedURL.urlToPlatformPath(url, Host.isWin()); urlRegex = `${platformPath.escapeForRegExp()}|${url.escapeForRegExp()}`; } @@ -929,7 +940,8 @@ SDK.DebuggerModel.Events = { DiscardedAnonymousScriptSource: Symbol('DiscardedAnonymousScriptSource'), GlobalObjectCleared: Symbol('GlobalObjectCleared'), CallFrameSelected: Symbol('CallFrameSelected'), - ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame') + ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame'), + DebuggerIsReadyToPause: Symbol('DebuggerIsReadyToPause'), }; /** @enum {string} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js index e39b3fe5eb7..6bc75d286b2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js @@ -169,7 +169,8 @@ SDK.HARLog.Entry = class { // IPv6 address should not have square brackets per (https://tools.ietf.org/html/rfc2373#section-2.2). serverIPAddress: ipAddress.replace(/\[\]/g, ''), _initiator: exportedInitiator, - _priority: harEntry._request.priority() + _priority: harEntry._request.priority(), + _resourceType: harEntry._request.resourceType().name() }; // Chrome specific. diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js index 7de66309643..60c222e8e70 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js @@ -45,10 +45,16 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { * @return {!Promise<?Protocol.HeapProfiler.SamplingHeapProfile>} */ stopSampling() { - this._isRecording = false; return this._heapProfilerAgent.stopSampling(); } + /** + * @return {!Promise<?Protocol.HeapProfiler.SamplingHeapProfile>} + */ + getSamplingProfile() { + return this._heapProfilerAgent.getSamplingProfile(); + } + startNativeSampling() { const defaultSamplingIntervalInBytes = 65536; this._memoryAgent.startSampling(defaultSamplingIntervalInBytes); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkManager.js index a9b236a71cf..6790512da8e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkManager.js @@ -886,7 +886,7 @@ SDK.NetworkDispatcher = class { }; /** - * @implements {SDK.TargetManager.Observer} + * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>} * @unrestricted */ SDK.MultitargetNetworkManager = class extends Common.Object { @@ -911,7 +911,7 @@ SDK.MultitargetNetworkManager = class extends Common.Object { /** @type {!Multimap<!SDK.MultitargetNetworkManager.RequestInterceptor, !SDK.MultitargetNetworkManager.InterceptionPattern>} */ this._urlsForRequestInterceptor = new Multimap(); - SDK.targetManager.observeTargets(this, SDK.Target.Capability.Network); + SDK.targetManager.observeModels(SDK.NetworkManager, this); } /** @@ -929,10 +929,10 @@ SDK.MultitargetNetworkManager = class extends Common.Object { /** * @override - * @param {!SDK.Target} target + * @param {!SDK.NetworkManager} networkManager */ - targetAdded(target) { - const networkAgent = target.networkAgent(); + modelAdded(networkManager) { + const networkAgent = networkManager.target().networkAgent(); if (this._extraHeaders) networkAgent.setExtraHTTPHeaders(this._extraHeaders); if (this._currentUserAgent()) @@ -948,16 +948,16 @@ SDK.MultitargetNetworkManager = class extends Common.Object { /** * @override - * @param {!SDK.Target} target + * @param {!SDK.NetworkManager} networkManager */ - targetRemoved(target) { + modelRemoved(networkManager) { for (const entry of this._inflightMainResourceRequests) { const manager = SDK.NetworkManager.forRequest(/** @type {!SDK.NetworkRequest} */ (entry[1])); - if (manager.target() !== target) + if (manager !== networkManager) continue; this._inflightMainResourceRequests.delete(/** @type {string} */ (entry[0])); } - this._agents.delete(target.networkAgent()); + this._agents.delete(networkManager.target().networkAgent()); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js index a00645cc6ad..b5e422346a1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js @@ -1151,12 +1151,13 @@ SDK.NetworkRequest = class extends Common.Object { async populateImageSource(image) { const {content, encoded} = await this.contentData(); let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, encoded); - if (imageSrc === null) { + if (imageSrc === null && !this._failed) { const cacheControl = this.responseHeaderValue('cache-control') || ''; if (!cacheControl.includes('no-cache')) imageSrc = this._url; } - image.src = imageSrc; + if (imageSrc !== null) + image.src = imageSrc; } /** @@ -1244,6 +1245,24 @@ SDK.NetworkRequest = class extends Common.Object { this._backendRequestId = requestId; this._requestId = requestId; } + + /** + * @return {?string} + */ + charset() { + const contentTypeHeader = this.responseHeaderValue('content-type'); + if (!contentTypeHeader) + return null; + + const responseCharsets = contentTypeHeader.replace(/ /g, '') + .split(';') + .filter(parameter => parameter.toLowerCase().startsWith('charset=')) + .map(parameter => parameter.slice('charset='.length)); + if (responseCharsets.length) + return responseCharsets[0]; + + return null; + } }; /** @enum {symbol} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js index e2ca71a5876..ad2bd2d2014 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js @@ -58,6 +58,13 @@ SDK.OverlayModel = class extends SDK.SDKModel { () => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get())); if (this._showScrollBottleneckRectsSetting.get()) this._overlayAgent.setShowScrollBottleneckRects(true); + + this._showHitTestBordersSetting = Common.moduleSetting('showHitTestBorders'); + this._showHitTestBordersSetting.addChangeListener( + () => this._overlayAgent.setShowHitTestBorders(this._showHitTestBordersSetting.get())); + if (this._showHitTestBordersSetting.get()) + this._overlayAgent.setShowHitTestBorders(true); + if (target.suspended()) this._overlayAgent.setSuspended(true); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js index a8da06aef2c..3262081af36 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js @@ -695,10 +695,12 @@ SDK.ExecutionContext = class { */ function targetWeight(target) { if (!target.parentTarget()) + return 5; + if (target.type() === SDK.Target.Type.Frame) return 4; - if (target.hasBrowserCapability()) + if (target.type() === SDK.Target.Type.ServiceWorker) return 3; - if (target.hasJSCapability()) + if (target.type() === SDK.Target.Type.Worker) return 2; return 1; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/ServiceWorkerManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/ServiceWorkerManager.js index bbe4f76f2cb..4a6e9084e55 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/ServiceWorkerManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/ServiceWorkerManager.js @@ -580,7 +580,7 @@ SDK.ServiceWorkerContextNamer = class { const parent = target.parentTarget(); if (!parent || parent.parentTarget() !== this._target) return null; - return parent.id(); + return parent.type() === SDK.Target.Type.ServiceWorker ? parent.id() : null; } _updateAllContextLabels() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Target.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Target.js index 9ed9f30a07a..96473067591 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Target.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Target.js @@ -12,18 +12,46 @@ SDK.Target = class extends Protocol.TargetBase { * @param {!SDK.TargetManager} targetManager * @param {string} id * @param {string} name - * @param {number} capabilitiesMask - * @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory + * @param {!SDK.Target.Type} type * @param {?SDK.Target} parentTarget + * @param {string} sessionId * @param {boolean} suspended - * @param {boolean} isNodeJS */ - constructor(targetManager, id, name, capabilitiesMask, connectionFactory, parentTarget, suspended, isNodeJS) { - super(connectionFactory, isNodeJS); + constructor(targetManager, id, name, type, parentTarget, sessionId, suspended) { + const needsNodeJSPatching = type === SDK.Target.Type.Node; + super(needsNodeJSPatching, parentTarget, sessionId); this._targetManager = targetManager; this._name = name; this._inspectedURL = ''; - this._capabilitiesMask = capabilitiesMask; + this._capabilitiesMask = 0; + switch (type) { + case SDK.Target.Type.Frame: + this._capabilitiesMask = SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS | + SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target | + SDK.Target.Capability.Tracing | SDK.Target.Capability.Emulation | SDK.Target.Capability.Input; + if (!parentTarget) { + this._capabilitiesMask |= SDK.Target.Capability.DeviceEmulation | SDK.Target.Capability.ScreenCapture | + SDK.Target.Capability.Security | SDK.Target.Capability.Inspector; + } + break; + case SDK.Target.Type.ServiceWorker: + this._capabilitiesMask = + SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target; + if (!parentTarget) + this._capabilitiesMask |= SDK.Target.Capability.Browser | SDK.Target.Capability.Inspector; + break; + case SDK.Target.Type.Worker: + this._capabilitiesMask = SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network | + SDK.Target.Capability.Target; + break; + case SDK.Target.Type.Node: + this._capabilitiesMask = SDK.Target.Capability.JS; + break; + case SDK.Target.Type.Browser: + this._capabilitiesMask = SDK.Target.Capability.Target; + break; + } + this._type = type; this._parentTarget = parentTarget; this._id = id; this._modelByConstructor = new Map(); @@ -58,6 +86,21 @@ SDK.Target = class extends Protocol.TargetBase { } /** + * @return {!SDK.Target.Type} + */ + type() { + return this._type; + } + + /** + * @override + */ + markAsNodeJSForTest() { + super.markAsNodeJSForTest(); + this._type = SDK.Target.Type.Node; + } + + /** * @return {!SDK.TargetManager} */ targetManager() { @@ -69,6 +112,8 @@ SDK.Target = class extends Protocol.TargetBase { * @return {boolean} */ hasAllCapabilities(capabilitiesMask) { + // TODO(dgozman): get rid of this method, once we never observe targets with + // capability mask. return (this._capabilitiesMask & capabilitiesMask) === capabilitiesMask; } @@ -77,49 +122,8 @@ SDK.Target = class extends Protocol.TargetBase { * @return {string} */ decorateLabel(label) { - return !this.hasBrowserCapability() ? '\u2699 ' + label : label; - } - - /** - * @return {boolean} - */ - hasBrowserCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.Browser); - } - - /** - * @return {boolean} - */ - hasJSCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.JS); - } - - /** - * @return {boolean} - */ - hasLogCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.Log); - } - - /** - * @return {boolean} - */ - hasNetworkCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.Network); - } - - /** - * @return {boolean} - */ - hasTargetCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.Target); - } - - /** - * @return {boolean} - */ - hasDOMCapability() { - return this.hasAllCapabilities(SDK.Target.Capability.DOM); + return (this._type === SDK.Target.Type.Worker || this._type === SDK.Target.Type.ServiceWorker) ? '\u2699 ' + label : + label; } /** @@ -131,8 +135,10 @@ SDK.Target = class extends Protocol.TargetBase { /** * @override + * @param {string} reason */ - dispose() { + dispose(reason) { + super.dispose(reason); this._targetManager.removeTarget(this); for (const model of this._modelByConstructor.valuesArray()) model.dispose(); @@ -241,8 +247,17 @@ SDK.Target.Capability = { DeviceEmulation: 1 << 12, None: 0, +}; - AllForTests: (1 << 13) - 1 +/** + * @enum {string} + */ +SDK.Target.Type = { + Frame: 'frame', + ServiceWorker: 'service-worker', + Worker: 'worker', + Node: 'node', + Browser: 'browser', }; /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/TargetManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/TargetManager.js index bf2bad76d02..976eba20150 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/TargetManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/TargetManager.js @@ -11,7 +11,6 @@ SDK.TargetManager = class extends Common.Object { this._targets = []; /** @type {!Array.<!SDK.TargetManager.Observer>} */ this._observers = []; - this._observerCapabiliesMaskSymbol = Symbol('observerCapabilitiesMask'); /** @type {!Multimap<symbol, !{modelClass: !Function, thisObject: (!Object|undefined), listener: function(!Common.Event)}>} */ this._modelListeners = new Multimap(); /** @type {!Multimap<function(new:SDK.SDKModel, !SDK.Target), !SDK.SDKModelObserver>} */ @@ -150,13 +149,12 @@ SDK.TargetManager = class extends Common.Object { /** * @param {!SDK.TargetManager.Observer} targetObserver - * @param {number=} capabilitiesMask */ - observeTargets(targetObserver, capabilitiesMask) { - if (this._observerCapabiliesMaskSymbol in targetObserver) + observeTargets(targetObserver) { + if (this._observers.indexOf(targetObserver) !== -1) throw new Error('Observer can only be registered once'); - targetObserver[this._observerCapabiliesMaskSymbol] = capabilitiesMask || 0; - this.targets(capabilitiesMask).forEach(targetObserver.targetAdded.bind(targetObserver)); + for (const target of this._targets) + targetObserver.targetAdded(target); this._observers.push(targetObserver); } @@ -164,28 +162,25 @@ SDK.TargetManager = class extends Common.Object { * @param {!SDK.TargetManager.Observer} targetObserver */ unobserveTargets(targetObserver) { - delete targetObserver[this._observerCapabiliesMaskSymbol]; this._observers.remove(targetObserver); } /** * @param {string} id * @param {string} name - * @param {number} capabilitiesMask - * @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory + * @param {!SDK.Target.Type} type * @param {?SDK.Target} parentTarget - * @param {boolean} isNodeJS + * @param {string=} sessionId * @return {!SDK.Target} */ - createTarget(id, name, capabilitiesMask, connectionFactory, parentTarget, isNodeJS) { - const target = - new SDK.Target(this, id, name, capabilitiesMask, connectionFactory, parentTarget, this._isSuspended, isNodeJS); + createTarget(id, name, type, parentTarget, sessionId) { + const target = new SDK.Target(this, id, name, type, parentTarget, sessionId || '', this._isSuspended); target.createModels(new Set(this._modelObservers.keysArray())); this._targets.push(target); - const copy = this._observersForTarget(target); - for (let i = 0; i < copy.length; ++i) - copy[i].targetAdded(target); + const copy = this._observers.slice(0); + for (const observer of copy) + observer.targetAdded(target); for (const modelClass of target.models().keys()) this.modelAdded(target, modelClass, target.models().get(modelClass)); @@ -203,15 +198,6 @@ SDK.TargetManager = class extends Common.Object { /** * @param {!SDK.Target} target - * @return {!Array<!SDK.TargetManager.Observer>} - */ - _observersForTarget(target) { - return this._observers.filter( - observer => target.hasAllCapabilities(observer[this._observerCapabiliesMaskSymbol] || 0)); - } - - /** - * @param {!SDK.Target} target */ removeTarget(target) { if (!this._targets.includes(target)) @@ -221,9 +207,9 @@ SDK.TargetManager = class extends Common.Object { for (const modelClass of target.models().keys()) this._modelRemoved(target, modelClass, target.models().get(modelClass)); - const copy = this._observersForTarget(target); - for (let i = 0; i < copy.length; ++i) - copy[i].targetRemoved(target); + const copy = this._observers.slice(0); + for (const observer of copy) + observer.targetRemoved(target); for (const key of this._modelListeners.keysArray()) { for (const info of this._modelListeners.get(key)) { @@ -235,14 +221,10 @@ SDK.TargetManager = class extends Common.Object { } /** - * @param {number=} capabilitiesMask * @return {!Array.<!SDK.Target>} */ - targets(capabilitiesMask) { - if (!capabilitiesMask) - return this._targets.slice(); - else - return this._targets.filter(target => target.hasAllCapabilities(capabilitiesMask || 0)); + targets() { + return this._targets.slice(); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json index 89048fb52ac..2ece8d277b6 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json @@ -189,6 +189,24 @@ { "type": "setting", "category": "Rendering", + "settingName": "showHitTestBorders", + "settingType": "boolean", + "storageType": "session", + "options": [ + { + "value": true, + "title": "Show hit-test borders" + }, + { + "value": false, + "title": "Hide hit-test borders" + } + ], + "defaultValue": false + }, + { + "type": "setting", + "category": "Rendering", "settingName": "emulatedCSSMedia", "settingType": "enum", "storageType": "session", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js index d062f78d520..bc5263a36b2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js @@ -13,23 +13,12 @@ function nextId(prefix) { return (prefix || '') + ++id; } -SDKTestRunner.connectToPage = function(targetName, pageMock, makeMainTarget) { - const mockTarget = SDK.targetManager.createTarget( - nextId('mock-target-'), targetName, pageMock.capabilities(), params => pageMock.createConnection(params)); - - if (makeMainTarget) { - SDK.targetManager._targets = SDK.targetManager._targets.filter(target => target !== mockTarget); - SDK.targetManager._targets.unshift(mockTarget); - } - - return mockTarget; -}; - SDKTestRunner.PageMock = class { constructor(url) { this._url = url; - this._capabilities = SDK.Target.Capability.DOM | SDK.Target.Capability.JS | SDK.Target.Capability.Browser; + this._type = SDK.Target.Type.Frame; this._enabledDomains = new Set(); + this._children = new Map(); this._mainFrame = {id: nextId(), loaderId: nextId(), mimeType: 'text/html', securityOrigin: this._url, url: this._url}; @@ -49,18 +38,50 @@ SDKTestRunner.PageMock = class { }; } - capabilities() { - return this._capabilities; + turnIntoWorker() { + this._type = SDK.Target.Type.Worker; } - disableDOMCapability() { - this._capabilities = this._capabilities & ~SDK.Target.Capability.DOM; + connectAsMainTarget(targetName) { + Bindings.debuggerWorkspaceBinding._resetForTest(TestRunner.mainTarget); + Bindings.resourceMapping._resetForTest(TestRunner.mainTarget); + this._enabledDomains.clear(); + SDK.targetManager._targets = []; + + const oldFactory = Protocol.Connection._factory; + Protocol.Connection._factory = () => { + this._connection = new MockPageConnection(this); + return this._connection; + }; + const target = SDK.targetManager.createTarget(nextId('mock-target-'), targetName, this._type, null); + Protocol.Connection._factory = oldFactory; + + this._target = target; + return target; } - createConnection(params) { + connectAsChildTarget(targetName, parentMock) { this._enabledDomains.clear(); - this._connection = new MockPageConnection(this, params); - return this._connection; + this._sessionId = nextId('mock-target-'); + this._root = parentMock._root || parentMock; + this._root._children.set(this._sessionId, this); + const target = + SDK.targetManager.createTarget(this._sessionId, targetName, this._type, parentMock._target, this._sessionId); + this._target = target; + return target; + } + + disconnect() { + if (this._root) { + this._root._children.delete(this._sessionId); + this._target.dispose(); + this._root = null; + this._sessionId = null; + } else { + this._connection.disconnect(); + this._connection = null; + } + this._target = null; } evalScript(url, content, isContentScript) { @@ -71,6 +92,7 @@ SDKTestRunner.PageMock = class { if (!context) { context = this._createExecutionContext(this._mainFrame, isContentScript); + this._executionContexts.push(context); this._fireEvent('Runtime.executionContextCreated', {context: context}); } @@ -98,6 +120,14 @@ SDKTestRunner.PageMock = class { this._fireEvent('Debugger.scriptParsed', script); } + removeContentScripts() { + const index = this._executionContexts.findIndex(context => !context.auxData.isDefault); + if (index !== -1) { + this._fireEvent('Runtime.executionContextDestroyed', {executionContextId: this._executionContexts[index].id}); + this._executionContexts.splice(index, 1); + } + } + reload() { this._fireEvent('Page.frameStartedLoading', {frameId: this._mainFrame.id}); @@ -124,13 +154,6 @@ SDKTestRunner.PageMock = class { this._fireEvent('Page.domContentEventFired', {timestamp: Date.now() / 1000}); } - close() { - if (this._connection) { - this._connection.disconnect(); - this._connection = null; - } - } - _createExecutionContext(frame, isContentScript) { return { id: nextId(), @@ -138,7 +161,7 @@ SDKTestRunner.PageMock = class { auxData: {isDefault: !isContentScript, frameId: frame.id}, origin: frame.securityOrigin, - name: '' + name: isContentScript ? 'content-script-context' : '' }; } @@ -185,26 +208,36 @@ SDKTestRunner.PageMock = class { const domain = methodName.split('.')[0]; if (domain === 'Page') - return !!(this._capabilities & SDK.Target.Capability.DOM); + return this._type === SDK.Target.Type.Frame; return true; } - _dispatch(id, methodName, params) { + _dispatch(sessionId, id, methodName, params) { + if (sessionId) { + const child = this._children.get(sessionId); + if (child) + child._dispatch('', id, methodName, params); + return; + } + const handler = (this._isSupportedDomain(methodName) ? this._dispatchMap[methodName] : null); if (handler) return handler.call(this, id, params); this._sendResponse( - id, undefined, - {message: 'Can\'t handle command ' + methodName, code: Protocol.InspectorBackend.DevToolsStubErrorCode}); + id, undefined, {message: 'Can\'t handle command ' + methodName, code: Protocol.DevToolsStubErrorCode}); } _sendResponse(id, result, error) { const message = {id: id, result: result, error: error}; - - this._connection.sendMessageToDevTools(message); + if (this._root) { + message.sessionId = this._sessionId; + this._root._connection.sendMessageToDevTools(message); + } else { + this._connection.sendMessageToDevTools(message); + } } _fireEvent(methodName, params) { @@ -214,24 +247,35 @@ SDKTestRunner.PageMock = class { return; const message = {method: methodName, params: params}; - - this._connection.sendMessageToDevTools(message); + if (this._root) { + message.sessionId = this._sessionId; + this._root._connection.sendMessageToDevTools(message); + } else { + this._connection.sendMessageToDevTools(message); + } } }; MockPageConnection = class { - constructor(page, params) { + constructor(page) { this._page = page; - this._onMessage = params.onMessage; - this._onDisconnect = params.onDisconnect; + } + + setOnMessage(onMessage) { + this._onMessage = onMessage; + } + + setOnDisconnect(onDisconnect) { + this._onDisconnect = onDisconnect; } sendMessageToDevTools(message) { setTimeout(() => this._onMessage.call(null, JSON.stringify(message)), 0); } - sendMessage(domain, message) { - this._page._dispatch(message.id, message.method, message.params); + sendRawMessage(messageString) { + const message = JSON.parse(messageString); + this._page._dispatch(message.sessionId, message.id, message.method, message.params || {}); } disconnect() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/search/searchResultsPane.css b/chromium/third_party/blink/renderer/devtools/front_end/search/searchResultsPane.css index 5e2a66234b9..829dc110610 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/search/searchResultsPane.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/search/searchResultsPane.css @@ -110,6 +110,7 @@ ol.children.expanded { .search-match-link { overflow: hidden; text-overflow: ellipsis; + margin-left: 9px; } .search-result-qualifier { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js index 44f890f37f7..833df59f21d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js @@ -15,6 +15,7 @@ Security.SecurityPanel = class extends UI.PanelWithSidebar { title.textContent = Common.UIString('Overview'); this._sidebarMainViewElement = new Security.SecurityPanelSidebarTreeElement( title, this._setVisibleView.bind(this, this._mainView), 'security-main-view-sidebar-tree-item', 'lock-icon'); + this._sidebarMainViewElement.tooltip = title.textContent; this._sidebarTree = new Security.SecurityPanelSidebarTree(this._sidebarMainViewElement, this.showOrigin.bind(this)); this.panelSidebarElement().appendChild(this._sidebarTree.element); @@ -445,6 +446,7 @@ Security.SecurityPanelSidebarTree = class extends UI.TreeOutlineInShadow { const originElement = new Security.SecurityPanelSidebarTreeElement( Security.SecurityPanel.createHighlightedUrl(origin, securityState), this._showOriginInPanel.bind(this, origin), 'security-sidebar-tree-item', 'security-property'); + originElement.tooltip = origin; this._elementsByOrigin.set(origin, originElement); this.updateOrigin(origin, securityState); } @@ -649,6 +651,12 @@ Security.SecurityMainView = class extends UI.VBox { text.appendChild(Security.SecurityPanel.createCertificateViewerButtonForCert( Common.UIString('View certificate'), explanation.certificate)); } + + if (explanation.recommendations && explanation.recommendations.length) { + const recommendationList = text.createChild('ul', 'security-explanation-recommendations'); + for (const recommendation of explanation.recommendations) + recommendationList.createChild('li').textContent = recommendation; + } return text; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/security/mainView.css b/chromium/third_party/blink/renderer/devtools/front_end/security/mainView.css index 03a8f32c049..4979fb3c38d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/security/mainView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/security/mainView.css @@ -87,7 +87,6 @@ background: #fff; border-color: rgb(217, 217, 217); - color: rgba(0, 0, 0, 36); } .security-summary-secure .triangle-pointer, @@ -96,11 +95,6 @@ color: #0b8043; } -.security-summary-neutral .triangle-pointer, -.security-summary-neutral .security-summary-text { - color: rgb(253, 177, 48); -} - .security-summary-insecure .triangle-pointer, .security-summary-insecure .security-summary-text, .security-explanation-title-neutral, @@ -132,7 +126,7 @@ display: flex; white-space: nowrap; border: none; - color: #8c8c8c; + color: rgb(90, 90, 90); } .security-explanation-text { @@ -153,7 +147,7 @@ } .security-explanation-title { - color: rgb(90, 90, 90); + color: rgb(48, 57, 66); margin-top: 1px; margin-bottom: 8px; } @@ -173,3 +167,11 @@ .security-mixed-content { margin-top: 8px; } + +.security-explanation-recommendations { + padding-inline-start: 16px; +} + +.security-explanation-recommendations > li { + margin-bottom: 4px; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/xmlTree.css b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/xmlTree.css index cd810c2e063..e65786761b7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/xmlTree.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/xmlTree.css @@ -8,11 +8,11 @@ list-style: none; padding: 0; margin: 0; - -webkit-padding-start: 16px; + padding-inline-start: 16px; } ol.tree-outline { - -webkit-padding-start: 0; + padding-inline-start: 0; } .tree-outline li { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js new file mode 100644 index 00000000000..7e34fd60680 --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js @@ -0,0 +1,71 @@ +/* + * Copyright 2018 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +Sources.BreakpointEditDialog = class extends UI.Widget { + /** + * @param {number} editorLineNumber + * @param {string} oldCondition + * @param {function({committed: boolean, condition: string})} onFinish + */ + constructor(editorLineNumber, oldCondition, onFinish) { + super(true); + this.registerRequiredCSS('sources/breakpointEditDialog.css'); + this._onFinish = onFinish; + this._finished = false; + /** @type {?UI.TextEditor} */ + this._editor = null; + + const labelElement = this.contentElement.createChild('label', 'source-frame-breakpoint-message'); + labelElement.htmlFor = 'source-frame-breakpoint-condition'; + labelElement.createTextChild( + Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1)); + + self.runtime.extension(UI.TextEditorFactory).instance().then(factory => { + this._editor = + factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true}); + this._editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor)); + if (oldCondition) + this._editor.setText(oldCondition); + this._editor.widget().show(this.contentElement); + this._editor.widget().element.id = 'source-frame-breakpoint-condition'; + this._editor.setSelection(this._editor.fullRange()); + this._editor.widget().focus(); + this._editor.widget().element.addEventListener('keydown', this._onKeyDown.bind(this), true); + this._editor.widget().element.addEventListener('blur', event => { + if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this._editor.widget().element)) + this._finishEditing(true); + }, true); + }); + } + + /** + * @param {boolean} committed + */ + _finishEditing(committed) { + if (this._finished) + return; + this._finished = true; + this._editor.widget().detach(); + const condition = this._editor.text(); + this._onFinish({committed, condition}); + } + + /** + * @param {!Event} event + */ + async _onKeyDown(event) { + if (isEnterKey(event) && !event.shiftKey) { + event.consume(true); + const expression = this._editor.text(); + if (event.ctrlKey || await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(expression)) + this._finishEditing(true); + else + this._editor.newlineAndIndent(); + } + if (isEscKey(event)) + this._finishEditing(false); + } +}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js index 341ce045ea3..11e54def1a8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js @@ -634,63 +634,22 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { * @param {?{lineNumber: number, columnNumber: number}} location */ async _editBreakpointCondition(editorLineNumber, breakpoint, location) { - const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition'); - - const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message'); - labelElement.htmlFor = 'source-frame-breakpoint-condition'; - labelElement.createTextChild( - Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1)); - - - this._textEditor.addDecoration(conditionElement, editorLineNumber); - - /** @type {!UI.TextEditorFactory} */ - const factory = await self.runtime.extension(UI.TextEditorFactory).instance(); - const editor = - factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true}); - editor.widget().show(conditionElement); - if (breakpoint) - editor.setText(breakpoint.condition()); - editor.setSelection(editor.fullRange()); - editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(editor)); - editor.widget().element.addEventListener('keydown', async event => { - if (isEnterKey(event) && !event.shiftKey) { - event.consume(true); - const expression = editor.text(); - if (event.ctrlKey || await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(expression)) - finishEditing.call(this, true); - else - editor.newlineAndIndent(); - } - if (isEscKey(event)) - finishEditing.call(this, false); - }, true); - editor.widget().focus(); - editor.widget().element.id = 'source-frame-breakpoint-condition'; - editor.widget().element.addEventListener('blur', event => { - if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(editor.widget().element)) - finishEditing.call(this, true); - }, true); - let finished = false; - /** - * @this {Sources.DebuggerPlugin} - */ - function finishEditing(committed) { - if (finished) + const oldCondition = breakpoint ? breakpoint.condition() : ''; + const decorationElement = createElement('div'); + const dialog = new Sources.BreakpointEditDialog(editorLineNumber, oldCondition, result => { + dialog.detach(); + this._textEditor.removeDecoration(decorationElement, editorLineNumber); + if (!result.committed) return; - finished = true; - editor.widget().detach(); - this._textEditor.removeDecoration(/** @type {!Element} */ (conditionElement), editorLineNumber); - if (!committed) - return; - if (breakpoint) - breakpoint.setCondition(editor.text().trim()); + breakpoint.setCondition(result.condition); else if (location) - this._setBreakpoint(location.lineNumber, location.columnNumber, editor.text().trim(), true); + this._setBreakpoint(location.lineNumber, location.columnNumber, result.condition, true); else - this._createNewBreakpoint(editorLineNumber, editor.text().trim(), true); - } + this._createNewBreakpoint(editorLineNumber, result.condition, true); + }); + this._textEditor.addDecoration(decorationElement, editorLineNumber); + dialog.show(decorationElement); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js index 668372bba1f..a2016cac9e2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js @@ -527,7 +527,8 @@ Sources.NavigatorView = class extends UI.VBox { if (!targetNode) { targetNode = new Sources.NavigatorGroupTreeNode( this, project, 'target:' + target.id(), - !target.hasBrowserCapability() ? Sources.NavigatorView.Types.Worker : Sources.NavigatorView.Types.Frame, + target.type() === SDK.Target.Type.Frame ? Sources.NavigatorView.Types.Frame : + Sources.NavigatorView.Types.Worker, target.name()); this._rootNode.appendChild(targetNode); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css b/chromium/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css new file mode 100644 index 00000000000..4555060cf55 --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css @@ -0,0 +1,34 @@ +/* + * Copyright 2018 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +:host { + z-index: 30; + padding: 4px; + background-color: #e6e6e6; + border-radius: 7px; + border: 2px solid #bababa; + width: 90%; + pointer-events: auto; +} + +.source-frame-breakpoint-message { + background-color: transparent; + font-weight: normal; + text-align: left; + text-shadow: none; + color: rgb(85, 85, 85); + cursor: default; + margin: 0 0 2px 0; +} + +#source-frame-breakpoint-condition { + margin: 0; + border: 1px inset rgb(190, 190, 190) !important; + width: 100%; + box-shadow: none !important; + outline: none !important; + background: white; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/javaScriptBreakpointsSidebarPane.css b/chromium/third_party/blink/renderer/devtools/front_end/sources/javaScriptBreakpointsSidebarPane.css index 301b8be4449..8a2f7817492 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/javaScriptBreakpointsSidebarPane.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/javaScriptBreakpointsSidebarPane.css @@ -25,6 +25,7 @@ text-overflow: ellipsis; overflow: hidden; white-space: nowrap; + margin-left: 22px; } .breakpoints-list-deactivated { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json index 451a843622c..472a8670feb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json @@ -27,7 +27,7 @@ "toggledIconClass": "largeicon-resume", "className": "Sources.SourcesPanel.RevealingActionDelegate", "contextTypes": [ - "Sources.SourcesPanel", + "Sources.SourcesView", "UI.ShortcutRegistry.ForwardedShortcut" ], "options": [ @@ -137,7 +137,7 @@ "title": "Run snippet", "iconClass": "largeicon-play", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -158,7 +158,7 @@ "toggledIconClass": "largeicon-activate-breakpoints", "className": "Sources.SourcesPanel.DebuggingActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "options": [ { @@ -560,7 +560,7 @@ "actionId": "sources.jump-to-previous-location", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -573,7 +573,7 @@ "actionId": "sources.jump-to-next-location", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -586,7 +586,7 @@ "actionId": "sources.close-editor-tab", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -599,7 +599,7 @@ "actionId": "sources.go-to-line", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -612,7 +612,7 @@ "actionId": "sources.go-to-member", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -658,7 +658,7 @@ "actionId": "sources.save", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -676,7 +676,7 @@ "actionId": "sources.save-all", "className": "Sources.SourcesView.ActionDelegate", "contextTypes": [ - "Sources.SourcesPanel" + "Sources.SourcesView" ], "bindings": [ { @@ -834,6 +834,7 @@ ], "scripts": [ "AddSourceMapURLDialog.js", + "BreakpointEditDialog.js", "CallStackSidebarPane.js", "DebuggerPausedMessage.js", "SimpleHistoryManager.js", @@ -867,6 +868,7 @@ "ScriptOriginPlugin.js" ], "resources": [ + "breakpointEditDialog.css", "callStackSidebarPane.css", "debuggerPausedMessage.css", "javaScriptBreakpointsSidebarPane.css", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css index 42b8ab26914..8fe79b5786f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css @@ -59,35 +59,6 @@ background-color: #444; } -.source-frame-breakpoint-condition { - z-index: 30; - padding: 4px; - background-color: #e6e6e6; - border-radius: 7px; - border: 2px solid #bababa; - width: 90%; - pointer-events: auto; -} - -.source-frame-breakpoint-message { - background-color: transparent; - font-weight: normal; - text-align: left; - text-shadow: none; - color: rgb(85, 85, 85); - cursor: default; - margin: 0 0 2px 0; -} - -#source-frame-breakpoint-condition { - margin: 0; - border: 1px inset rgb(190, 190, 190) !important; - width: 100%; - box-shadow: none !important; - outline: none !important; - background: white; -} - @-webkit-keyframes source-frame-value-update-highlight-animation { from { background-color: inherit; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js index 8ea7e66bfd3..0c423a99706 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js @@ -698,17 +698,17 @@ SourcesTestRunner.evaluateOnCurrentCallFrame = function(code) { return TestRunner.debuggerModel.evaluateOnSelectedCallFrame({expression: code, objectGroup: 'console'}); }; -SourcesTestRunner.waitDebuggerPluginBreakpoints = function(sourceFrame) { - return waitUpdate().then(checkIfReady); +SourcesTestRunner.waitDebuggerPluginDecorations = function(sourceFrame) { + return TestRunner.addSnifferPromise(Sources.DebuggerPlugin.prototype, '_breakpointDecorationsUpdatedForTest'); +}; - async function waitUpdate() { - await TestRunner.addSnifferPromise(Sources.DebuggerPlugin.prototype, '_breakpointDecorationsUpdatedForTest'); - } +SourcesTestRunner.waitDebuggerPluginBreakpoints = function(sourceFrame) { + return SourcesTestRunner.waitDebuggerPluginDecorations().then(checkIfReady); function checkIfReady() { for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) { if (breakpoint._uiLocations.size === 0 && breakpoint.enabled()) - return waitUpdate().then(checkIfReady); + return SourcesTestRunner.waitDebuggerPluginDecorations().then(checkIfReady); } return Promise.resolve(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js index 38f6d191791..53d51db56b2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js @@ -13,7 +13,7 @@ self.testRunner; /** - * Only tests in /LayoutTests/http/tests/devtools/startup/ need to call + * Only tests in web_tests/http/tests/devtools/startup/ need to call * this method because these tests need certain activities to be exercised * in the inspected page prior to the DevTools session. * @param {string} path @@ -504,9 +504,7 @@ TestRunner.check = function(passCondition, failureText) { * @param {!Function} callback */ TestRunner.deprecatedRunAfterPendingDispatches = function(callback) { - const targets = SDK.targetManager.targets(); - const promises = targets.map(target => new Promise(resolve => target._deprecatedRunAfterPendingDispatches(resolve))); - Promise.all(promises).then(TestRunner.safeWrap(callback)); + Protocol.test.deprecatedRunAfterPendingDispatches(callback); }; /** @@ -641,11 +639,7 @@ TestRunner.markStep = function(title) { }; TestRunner.startDumpingProtocolMessages = function() { - // TODO(chenwilliam): stop abusing Closure interface which is why - // we need to opt out of type checking here - const untypedConnection = /** @type {*} */ (Protocol.InspectorBackend.Connection); - untypedConnection.prototype._dumpProtocolMessage = self.testRunner.logToStderr.bind(self.testRunner); - Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages = 1; + Protocol.test.dumpProtocol = self.testRunner.logToStderr.bind(self.testRunner); }; /** @@ -1221,37 +1215,6 @@ TestRunner.dumpLoadedModules = function(relativeTo) { }; /** - * @param {!SDK.Target} target - * @return {boolean} - */ -TestRunner.isDedicatedWorker = function(target) { - return target && !target.hasBrowserCapability() && target.hasJSCapability() && target.hasLogCapability(); -}; - -/** - * @param {!SDK.Target} target - * @return {boolean} - */ -TestRunner.isServiceWorker = function(target) { - return target && !target.hasBrowserCapability() && !target.hasJSCapability() && target.hasNetworkCapability() && - target.hasTargetCapability(); -}; - -/** - * @param {!SDK.Target} target - * @return {string} - */ -TestRunner.describeTargetType = function(target) { - if (TestRunner.isDedicatedWorker(target)) - return 'worker'; - if (TestRunner.isServiceWorker(target)) - return 'service-worker'; - if (!target.parentTarget()) - return 'page'; - return 'frame'; -}; - -/** * @param {string} urlSuffix * @param {!Workspace.projectTypes=} projectType * @return {!Promise} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js index 601007786a1..65317dd75f5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js @@ -162,7 +162,6 @@ TextEditor.CodeMirrorTextEditor = class extends UI.VBox { this._codeMirror.on('changes', this._changes.bind(this)); this._codeMirror.on('beforeSelectionChange', this._beforeSelectionChange.bind(this)); - this._codeMirror.on('keyHandled', this._onKeyHandled.bind(this)); this.element.style.overflow = 'hidden'; this._codeMirrorElement.classList.add('source-code'); @@ -374,10 +373,6 @@ TextEditor.CodeMirrorTextEditor = class extends UI.VBox { return this; } - _onKeyHandled() { - UI.shortcutRegistry.dismissPendingShortcutAction(); - } - /** * @param {number} lineNumber * @param {number} lineLength diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartDataProvider.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartDataProvider.js index 0de9b0ab89d..197a54c4469 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartDataProvider.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartDataProvider.js @@ -57,6 +57,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { this._headerLevel2 = this._buildGroupStyle({padding: 2, nestingLevel: 1, collapsible: false}); this._staticHeader = this._buildGroupStyle({collapsible: false}); this._framesHeader = this._buildGroupStyle({useFirstLineForOverview: true}); + this._timingsHeader = this._buildGroupStyle({shareHeaderLine: true, useFirstLineForOverview: true}); this._screenshotsHeader = this._buildGroupStyle({useFirstLineForOverview: true, nestingLevel: 1, collapsible: false, itemsHeight: 150}); this._interactionsHeaderLevel1 = this._buildGroupStyle({useFirstLineForOverview: true}); @@ -115,8 +116,9 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { return event.name + ':' + event.args['step']; if (event._blackboxRoot) return Common.UIString('Blackboxed'); + if (this._performanceModel.timelineModel().isMarkerEvent(event)) + return Timeline.TimelineUIUtils.markerShortTitle(event); const name = Timeline.TimelineUIUtils.eventStyle(event).title; - // TODO(yurys): support event dividers const detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(event, this._model.targetByEvent(event)); if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame && detailsText) @@ -235,7 +237,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { } _processInspectorTrace() { - this._appendFrameBars(); + this._appendFrames(); this._appendInteractionRecords(); const eventEntryType = Timeline.TimelineFlameChartDataProvider.EntryType.Event; @@ -246,7 +248,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { return 0; case TimelineModel.TimelineModel.TrackType.Animation: return 1; - case TimelineModel.TimelineModel.TrackType.UserTiming: + case TimelineModel.TimelineModel.TrackType.Timings: return 2; case TimelineModel.TimelineModel.TrackType.Console: return 3; @@ -278,9 +280,12 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { track, ls`Animation`, track.asyncEvents, this._interactionsHeaderLevel2, eventEntryType, false /* selectable */); break; - case TimelineModel.TimelineModel.TrackType.UserTiming: + case TimelineModel.TimelineModel.TrackType.Timings: + const group = this._appendHeader(ls`Timings`, this._timingsHeader, true /* selectable */); + group._track = track; + this._appendPageMetrics(); this._appendAsyncEventsGroup( - track, ls`User Timing`, track.asyncEvents, this._headerLevel1, eventEntryType, true /* selectable */); + track, null, track.asyncEvents, this._timingsHeader, eventEntryType, true /* selectable */); break; case TimelineModel.TimelineModel.TrackType.Console: this._appendAsyncEventsGroup( @@ -401,10 +406,9 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { group = this._appendHeader(title, style, selectable); group._track = track; } - const markerEventsFilter = Timeline.TimelineUIUtils.paintEventsFilter(); for (let i = 0; i < events.length; ++i) { const e = events[i]; - if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e) && markerEventsFilter.accept(e)) { + if (!isExtension && this._performanceModel.timelineModel().isMarkerEvent(e)) { this._markers.push(new Timeline.TimelineFlameChartMarker( e.startTime, e.startTime - this._model.minimumRecordTime(), Timeline.TimelineUIUtils.markerStyleForEvent(e))); @@ -438,7 +442,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { const index = this._appendEvent(e, level); if (openEvents.length) this._entryParent[index] = openEvents.peekLast(); - if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e)) + if (!isExtension && this._performanceModel.timelineModel().isMarkerEvent(e)) this._timelineData.entryTotalTimes[this._entryData.length] = undefined; maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1); @@ -472,7 +476,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { /** * @param {?TimelineModel.TimelineModel.Track} track - * @param {string} header + * @param {?string} header * @param {!Array<!SDK.TracingModel.AsyncEvent>} events * @param {!PerfUI.FlameChart.GroupStyle} style * @param {!Timeline.TimelineFlameChartDataProvider.EntryType} entryType @@ -488,7 +492,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { const asyncEvent = events[i]; if (!this._performanceModel.isVisible(asyncEvent)) continue; - if (!group) { + if (!group && header) { group = this._appendHeader(header, style, selectable); if (selectable) group._track = track; @@ -522,13 +526,37 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartDataProvider.EntryType.InteractionRecord; } - _appendFrameBars() { + _appendPageMetrics() { + this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Event; + + /** @type {!Array<!SDK.TracingModel.Event>} */ + const metricEvents = []; + for (const track of this._model.tracks()) { + for (const event of track.events) { + if (!this._performanceModel.timelineModel().isMarkerEvent(event)) + continue; + metricEvents.push(event); + } + } + + metricEvents.stableSort(SDK.TracingModel.Event.compareStartTime); + const totalTimes = this._timelineData.entryTotalTimes; + for (const event of metricEvents) { + this._appendEvent(event, this._currentLevel); + totalTimes[totalTimes.length - 1] = Number.NaN; + } + + ++this._currentLevel; + } + + _appendFrames() { const screenshots = this._performanceModel.filmStripModel().frames(); const hasFilmStrip = !!screenshots.length; this._framesHeader.collapsible = hasFilmStrip; this._appendHeader(Common.UIString('Frames'), this._framesHeader, false /* selectable */); this._frameGroup = this._timelineData.groups.peekLast(); const style = Timeline.TimelineUIUtils.markerStyleForFrame(); + this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Frame; for (const frame of this._performanceModel.frames()) { this._markers.push(new Timeline.TimelineFlameChartMarker( @@ -536,6 +564,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { this._appendFrame(frame); } ++this._currentLevel; + if (!hasFilmStrip) return; this._appendHeader('', this._screenshotsHeader, false /* selectable */); @@ -583,7 +612,10 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { '%s (self %s)', Number.millisToString(totalTime, true), Number.millisToString(selfTime, true)) : Number.millisToString(totalTime, true); } - title = this.entryTitle(entryIndex); + if (this._performanceModel.timelineModel().isMarkerEvent(event)) + title = Timeline.TimelineUIUtils.eventTitle(event); + else + title = this.entryTitle(entryIndex); warning = Timeline.TimelineUIUtils.eventWarning(event); } else if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) { const frame = /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex]); @@ -632,6 +664,8 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); if (this._model.isGenericTrace()) return this._genericTraceEventColor(event); + if (this._performanceModel.timelineModel().isMarkerEvent(event)) + return Timeline.TimelineUIUtils.markerStyleForEvent(event).color; if (!SDK.TracingModel.isAsyncPhase(event.phase)) return this._colorForEvent(event); if (event.hasCategory(TimelineModel.TimelineModel.Category.Console) || diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartView.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartView.js index 0abf8b041aa..afaea6a44ad 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartView.js @@ -463,11 +463,13 @@ Timeline.TimelineFlameChartMarker = class { /** * @override - * @return {string} + * @return {?string} */ title() { + if (this._style.lowPriority) + return null; const startTime = Number.millisToString(this._startOffset); - return Common.UIString('%s at %s', this._style.title, startTime); + return ls`${this._style.title} at ${startTime}`; } /** @@ -482,23 +484,14 @@ Timeline.TimelineFlameChartMarker = class { if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs) return; - context.save(); - - if (!this._style.lowPriority) { - context.strokeStyle = this._style.color; - context.lineWidth = 2; - context.beginPath(); - context.moveTo(x, 0); - context.lineTo(x, height); - context.stroke(); - } + context.save(); if (this._style.tall) { context.strokeStyle = this._style.color; context.lineWidth = this._style.lineWidth; context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5); context.beginPath(); - context.moveTo(x, height); + context.moveTo(x, 0); context.setLineDash(this._style.dashStyle); context.lineTo(x, context.canvas.height); context.stroke(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js index 920d3442256..8318111afaf 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js @@ -746,12 +746,9 @@ Timeline.TimelinePanel = class extends UI.Panel { const markers = new Map(); const recordTypes = TimelineModel.TimelineModel.RecordType; const zeroTime = timelineModel.minimumRecordTime(); - const filter = Timeline.TimelineUIUtils.paintEventsFilter(); for (const event of timelineModel.timeMarkerEvents()) { if (event.name === recordTypes.TimeStamp || event.name === recordTypes.ConsoleTime) continue; - if (!filter.accept(event)) - continue; markers.set(event.startTime, Timeline.TimelineUIUtils.createEventDivider(event, zeroTime)); } this._overviewPane.setMarkers(markers); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js index 9e7c3642c72..5334c9e60ec 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js @@ -110,19 +110,17 @@ Timeline.TimelineUIUtils = class { eventStyles[recordTypes.ParseScriptOnBackground] = new Timeline.TimelineRecordStyle(Common.UIString('Parse Script'), categories['scripting']); eventStyles[recordTypes.FrameStartedLoading] = - new Timeline.TimelineRecordStyle(Common.UIString('Frame Started Loading'), categories['loading'], true); + new Timeline.TimelineRecordStyle(ls`Frame Started Loading`, categories['loading'], true); eventStyles[recordTypes.MarkLoad] = - new Timeline.TimelineRecordStyle(Common.UIString('Load event'), categories['scripting'], true); + new Timeline.TimelineRecordStyle(ls`Onload Event`, categories['scripting'], true); eventStyles[recordTypes.MarkDOMContent] = - new Timeline.TimelineRecordStyle(Common.UIString('DOMContentLoaded event'), categories['scripting'], true); + new Timeline.TimelineRecordStyle(ls`DOMContentLoaded Event`, categories['scripting'], true); eventStyles[recordTypes.MarkFirstPaint] = - new Timeline.TimelineRecordStyle(Common.UIString('First paint'), categories['painting'], true); + new Timeline.TimelineRecordStyle(ls`First Paint`, categories['painting'], true); eventStyles[recordTypes.MarkFCP] = - new Timeline.TimelineRecordStyle(Common.UIString('First contentful paint'), categories['rendering'], true); + new Timeline.TimelineRecordStyle(ls`First Contentful Paint`, categories['rendering'], true); eventStyles[recordTypes.MarkFMP] = - new Timeline.TimelineRecordStyle(Common.UIString('First meaningful paint'), categories['rendering'], true); - eventStyles[recordTypes.MarkFMPCandidate] = - new Timeline.TimelineRecordStyle(Common.UIString('Meaningful paint candidate'), categories['rendering'], true); + new Timeline.TimelineRecordStyle(ls`First Meaningful Paint`, categories['rendering'], true); eventStyles[recordTypes.TimeStamp] = new Timeline.TimelineRecordStyle(Common.UIString('Timestamp'), categories['scripting']); eventStyles[recordTypes.ConsoleTime] = @@ -792,8 +790,9 @@ Timeline.TimelineUIUtils = class { let relatedNodeLabel; const contentHelper = new Timeline.TimelineDetailsContentHelper(model.targetByEvent(event), linkifier); - contentHelper.addSection( - Timeline.TimelineUIUtils.eventTitle(event), Timeline.TimelineUIUtils.eventStyle(event).category.color); + const color = model.isMarkerEvent(event) ? Timeline.TimelineUIUtils.markerStyleForEvent(event).color : + Timeline.TimelineUIUtils.eventStyle(event).category.color; + contentHelper.addSection(Timeline.TimelineUIUtils.eventTitle(event), color); const eventData = event.args['data']; const timelineData = TimelineModel.TimelineData.forEvent(event); @@ -805,9 +804,9 @@ Timeline.TimelineUIUtils = class { if (event.name === recordTypes.JSFrame && eventData['deoptReason']) contentHelper.appendWarningRow(event, TimelineModel.TimelineModel.WarningType.V8Deopt); - if (detailed) { - contentHelper.appendTextRow(Common.UIString('Total Time'), Number.millisToString(event.duration || 0, true)); - contentHelper.appendTextRow(Common.UIString('Self Time'), Number.millisToString(event.selfTime, true)); + if (detailed && !Number.isNaN(event.duration + 0)) { + contentHelper.appendTextRow(ls`Total Time`, Number.millisToString(event.duration, true)); + contentHelper.appendTextRow(ls`Self Time`, Number.millisToString(event.selfTime, true)); } if (model.isGenericTrace()) { @@ -826,26 +825,26 @@ Timeline.TimelineUIUtils = class { case recordTypes.MajorGC: case recordTypes.MinorGC: const delta = event.args['usedHeapSizeBefore'] - event.args['usedHeapSizeAfter']; - contentHelper.appendTextRow(Common.UIString('Collected'), Number.bytesToString(delta)); + contentHelper.appendTextRow(ls`Collected`, Number.bytesToString(delta)); break; case recordTypes.JSFrame: case recordTypes.FunctionCall: const detailsNode = Timeline.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.targetByEvent(event), linkifier); if (detailsNode) - contentHelper.appendElementRow(Common.UIString('Function'), detailsNode); + contentHelper.appendElementRow(ls`Function`, detailsNode); break; case recordTypes.TimerFire: case recordTypes.TimerInstall: case recordTypes.TimerRemove: - contentHelper.appendTextRow(Common.UIString('Timer ID'), eventData['timerId']); + contentHelper.appendTextRow(ls`Timer ID`, eventData['timerId']); if (event.name === recordTypes.TimerInstall) { - contentHelper.appendTextRow(Common.UIString('Timeout'), Number.millisToString(eventData['timeout'])); - contentHelper.appendTextRow(Common.UIString('Repeats'), !eventData['singleShot']); + contentHelper.appendTextRow(ls`Timeout`, Number.millisToString(eventData['timeout'])); + contentHelper.appendTextRow(ls`Repeats`, !eventData['singleShot']); } break; case recordTypes.FireAnimationFrame: - contentHelper.appendTextRow(Common.UIString('Callback ID'), eventData['id']); + contentHelper.appendTextRow(ls`Callback ID`, eventData['id']); break; case recordTypes.ResourceSendRequest: case recordTypes.ResourceReceiveResponse: @@ -853,101 +852,87 @@ Timeline.TimelineUIUtils = class { case recordTypes.ResourceFinish: url = timelineData.url; if (url) - contentHelper.appendElementRow(Common.UIString('Resource'), Components.Linkifier.linkifyURL(url)); + contentHelper.appendElementRow(ls`Resource`, Components.Linkifier.linkifyURL(url)); if (eventData['requestMethod']) - contentHelper.appendTextRow(Common.UIString('Request Method'), eventData['requestMethod']); + contentHelper.appendTextRow(ls`Request Method`, eventData['requestMethod']); if (typeof eventData['statusCode'] === 'number') - contentHelper.appendTextRow(Common.UIString('Status Code'), eventData['statusCode']); + contentHelper.appendTextRow(ls`Status Code`, eventData['statusCode']); if (eventData['mimeType']) - contentHelper.appendTextRow(Common.UIString('MIME Type'), eventData['mimeType']); + contentHelper.appendTextRow(ls`MIME Type`, eventData['mimeType']); if ('priority' in eventData) { const priority = PerfUI.uiLabelForNetworkPriority(eventData['priority']); - contentHelper.appendTextRow(Common.UIString('Priority'), priority); - } - if (eventData['encodedDataLength']) { - contentHelper.appendTextRow( - Common.UIString('Encoded Data'), Common.UIString('%d Bytes', eventData['encodedDataLength'])); - } - if (eventData['decodedBodyLength']) { - contentHelper.appendTextRow( - Common.UIString('Decoded Body'), Common.UIString('%d Bytes', eventData['decodedBodyLength'])); + contentHelper.appendTextRow(ls`Priority`, priority); } + if (eventData['encodedDataLength']) + contentHelper.appendTextRow(ls`Encoded Data`, ls`${eventData['encodedDataLength']} Bytes`); + if (eventData['decodedBodyLength']) + contentHelper.appendTextRow(ls`Decoded Body`, ls`${eventData['decodedBodyLength']} Bytes`); break; case recordTypes.CompileModule: - contentHelper.appendLocationRow(Common.UIString('Module'), event.args['fileName'], 0); + contentHelper.appendLocationRow(ls`Module`, event.args['fileName'], 0); break; case recordTypes.CompileScript: url = eventData && eventData['url']; - if (url) { - contentHelper.appendLocationRow( - Common.UIString('Script'), url, eventData['lineNumber'], eventData['columnNumber']); - } - contentHelper.appendTextRow(Common.UIString('Streamed'), Common.UIString('%s', eventData['streamed'])); + if (url) + contentHelper.appendLocationRow(ls`Script`, url, eventData['lineNumber'], eventData['columnNumber']); + contentHelper.appendTextRow(ls`Streamed`, eventData['streamed']); const cacheProduceOptions = eventData && eventData['cacheProduceOptions']; if (cacheProduceOptions) { - contentHelper.appendTextRow( - Common.UIString('Cache Produce Options'), Common.UIString('%s', cacheProduceOptions)); - contentHelper.appendTextRow( - Common.UIString('Produced Cache Size'), Common.UIString('%d', eventData['producedCacheSize'])); + contentHelper.appendTextRow(ls`Cache Produce Options`, cacheProduceOptions); + contentHelper.appendTextRow(ls`Produced Cache Size`, eventData['producedCacheSize']); } const cacheConsumeOptions = eventData && eventData['cacheConsumeOptions']; if (cacheConsumeOptions) { - contentHelper.appendTextRow( - Common.UIString('Cache Consume Options'), Common.UIString('%s', cacheConsumeOptions)); - contentHelper.appendTextRow( - Common.UIString('Consumed Cache Size'), Common.UIString('%d', eventData['consumedCacheSize'])); - contentHelper.appendTextRow( - Common.UIString('Cache Rejected'), Common.UIString('%s', eventData['cacheRejected'])); + contentHelper.appendTextRow(ls`Cache Consume Options`, cacheConsumeOptions); + contentHelper.appendTextRow(ls`Consumed Cache Size`, eventData['consumedCacheSize']); + contentHelper.appendTextRow(ls`Cache Rejected`, eventData['cacheRejected']); } break; case recordTypes.EvaluateScript: url = eventData && eventData['url']; - if (url) { - contentHelper.appendLocationRow( - Common.UIString('Script'), url, eventData['lineNumber'], eventData['columnNumber']); - } + if (url) + contentHelper.appendLocationRow(ls`Script`, url, eventData['lineNumber'], eventData['columnNumber']); break; case recordTypes.Paint: const clip = eventData['clip']; - contentHelper.appendTextRow(Common.UIString('Location'), Common.UIString('(%d, %d)', clip[0], clip[1])); + contentHelper.appendTextRow(ls`Location`, ls`(${clip[0]}, ${clip[1]})`); const clipWidth = Timeline.TimelineUIUtils.quadWidth(clip); const clipHeight = Timeline.TimelineUIUtils.quadHeight(clip); - contentHelper.appendTextRow(Common.UIString('Dimensions'), Common.UIString('%d × %d', clipWidth, clipHeight)); - // Fall-through intended. + contentHelper.appendTextRow(ls`Dimensions`, ls`${clipWidth} × ${clipHeight}`); + // Fall-through intended. case recordTypes.PaintSetup: case recordTypes.Rasterize: case recordTypes.ScrollLayer: - relatedNodeLabel = Common.UIString('Layer Root'); + relatedNodeLabel = ls`Layer Root`; break; case recordTypes.PaintImage: case recordTypes.DecodeLazyPixelRef: case recordTypes.DecodeImage: case recordTypes.ResizeImage: case recordTypes.DrawLazyPixelRef: - relatedNodeLabel = Common.UIString('Owner Element'); + relatedNodeLabel = ls`Owner Element`; url = timelineData.url; if (url) - contentHelper.appendElementRow(Common.UIString('Image URL'), Components.Linkifier.linkifyURL(url)); + contentHelper.appendElementRow(ls`Image URL`, Components.Linkifier.linkifyURL(url)); break; case recordTypes.ParseAuthorStyleSheet: url = eventData['styleSheetUrl']; if (url) - contentHelper.appendElementRow(Common.UIString('Stylesheet URL'), Components.Linkifier.linkifyURL(url)); + contentHelper.appendElementRow(ls`Stylesheet URL`, Components.Linkifier.linkifyURL(url)); break; case recordTypes.UpdateLayoutTree: // We don't want to see default details. case recordTypes.RecalculateStyles: - contentHelper.appendTextRow(Common.UIString('Elements Affected'), event.args['elementCount']); + contentHelper.appendTextRow(ls`Elements Affected`, event.args['elementCount']); break; case recordTypes.Layout: const beginData = event.args['beginData']; contentHelper.appendTextRow( - Common.UIString('Nodes That Need Layout'), - Common.UIString('%s of %s', beginData['dirtyObjects'], beginData['totalObjects'])); - relatedNodeLabel = Common.UIString('Layout root'); + ls`Nodes That Need Layout`, ls`${beginData['dirtyObjects']} of ${beginData['totalObjects']}`); + relatedNodeLabel = ls`Layout root`; break; case recordTypes.ConsoleTime: - contentHelper.appendTextRow(Common.UIString('Message'), event.name); + contentHelper.appendTextRow(ls`Message`, event.name); break; case recordTypes.WebSocketCreate: case recordTypes.WebSocketSendHandshakeRequest: @@ -955,18 +940,18 @@ Timeline.TimelineUIUtils = class { case recordTypes.WebSocketDestroy: const initiatorData = initiator ? initiator.args['data'] : eventData; if (typeof initiatorData['webSocketURL'] !== 'undefined') - contentHelper.appendTextRow(Common.UIString('URL'), initiatorData['webSocketURL']); + contentHelper.appendTextRow(ls`URL`, initiatorData['webSocketURL']); if (typeof initiatorData['webSocketProtocol'] !== 'undefined') - contentHelper.appendTextRow(Common.UIString('WebSocket Protocol'), initiatorData['webSocketProtocol']); + contentHelper.appendTextRow(ls`WebSocket Protocol`, initiatorData['webSocketProtocol']); if (typeof eventData['message'] !== 'undefined') - contentHelper.appendTextRow(Common.UIString('Message'), eventData['message']); + contentHelper.appendTextRow(ls`Message`, eventData['message']); break; case recordTypes.EmbedderCallback: - contentHelper.appendTextRow(Common.UIString('Callback Function'), eventData['callbackName']); + contentHelper.appendTextRow(ls`Callback Function`, eventData['callbackName']); break; case recordTypes.Animation: if (event.phase === SDK.TracingModel.Phase.NestableAsyncInstant) - contentHelper.appendTextRow(Common.UIString('State'), eventData['state']); + contentHelper.appendTextRow(ls`State`, eventData['state']); break; case recordTypes.ParseHTML: { const beginData = event.args['beginData']; @@ -974,29 +959,41 @@ Timeline.TimelineUIUtils = class { const endLine = event.args['endData'] ? event.args['endData']['endLine'] - 1 : undefined; url = beginData['url']; if (url) - contentHelper.appendLocationRange(Common.UIString('Range'), url, startLine, endLine); + contentHelper.appendLocationRange(ls`Range`, url, startLine, endLine); break; } case recordTypes.FireIdleCallback: - contentHelper.appendTextRow( - Common.UIString('Allotted Time'), Number.millisToString(eventData['allottedMilliseconds'])); - contentHelper.appendTextRow(Common.UIString('Invoked by Timeout'), eventData['timedOut']); - // Fall-through intended. + contentHelper.appendTextRow(ls`Allotted Time`, Number.millisToString(eventData['allottedMilliseconds'])); + contentHelper.appendTextRow(ls`Invoked by Timeout`, eventData['timedOut']); + // Fall-through intended. case recordTypes.RequestIdleCallback: case recordTypes.CancelIdleCallback: - contentHelper.appendTextRow(Common.UIString('Callback ID'), eventData['id']); + contentHelper.appendTextRow(ls`Callback ID`, eventData['id']); break; case recordTypes.EventDispatch: - contentHelper.appendTextRow(Common.UIString('Type'), eventData['type']); + contentHelper.appendTextRow(ls`Type`, eventData['type']); + break; + + case recordTypes.MarkFCP: + case recordTypes.MarkFMP: + case recordTypes.MarkLoad: + case recordTypes.MarkDOMContent: + contentHelper.appendTextRow( + ls`Timestamp`, Number.preciseMillisToString(event.startTime - model.minimumRecordTime(), 1)); + const learnMoreLink = UI.XLink.create( + 'https://developers.google.com/web/fundamentals/performance/user-centric-performance-metrics#user-centric_performance_metrics', + ls`Learn more`); + const linkDiv = UI.html`<div>${learnMoreLink} about page performance metrics.</div>`; + contentHelper.appendElementRow(ls`Details`, linkDiv); break; default: { const detailsNode = Timeline.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.targetByEvent(event), linkifier); if (detailsNode) - contentHelper.appendElementRow(Common.UIString('Details'), detailsNode); + contentHelper.appendElementRow(ls`Details`, detailsNode); break; } } @@ -1006,18 +1003,17 @@ Timeline.TimelineUIUtils = class { if (timelineData.timeWaitingForMainThread) { contentHelper.appendTextRow( - Common.UIString('Time Waiting for Main Thread'), - Number.millisToString(timelineData.timeWaitingForMainThread, true)); + ls`Time Waiting for Main Thread`, Number.millisToString(timelineData.timeWaitingForMainThread, true)); } const relatedNode = relatedNodesMap && relatedNodesMap.get(timelineData.backendNodeId); if (relatedNode) { const nodeSpan = await Common.Linkifier.linkify(relatedNode); - contentHelper.appendElementRow(relatedNodeLabel || Common.UIString('Related Node'), nodeSpan); + contentHelper.appendElementRow(relatedNodeLabel || ls`Related Node`, nodeSpan); } if (event[Timeline.TimelineUIUtils._previewElementSymbol]) { - contentHelper.addSection(Common.UIString('Preview')); + contentHelper.addSection(ls`Preview`); contentHelper.appendElementRow('', event[Timeline.TimelineUIUtils._previewElementSymbol]); } @@ -1028,7 +1024,7 @@ Timeline.TimelineUIUtils = class { const stats = {}; const showPieChart = detailed && Timeline.TimelineUIUtils._aggregatedStatsForTraceEvent(stats, model, event); if (showPieChart) { - contentHelper.addSection(Common.UIString('Aggregated Time')); + contentHelper.addSection(ls`Aggregated Time`); const pieChart = Timeline.TimelineUIUtils.generatePieChart( stats, Timeline.TimelineUIUtils.eventStyle(event).category, event.selfTime); contentHelper.appendElementRow('', pieChart); @@ -1529,17 +1525,6 @@ Timeline.TimelineUIUtils = class { } /** - * @return {!TimelineModel.TimelineModelFilter} - */ - static paintEventsFilter() { - const recordTypes = TimelineModel.TimelineModel.RecordType; - return new TimelineModel.TimelineInvisibleEventsFilter( - !Runtime.experiments.isEnabled('timelinePaintTimingMarkers') ? - [recordTypes.MarkFCP, recordTypes.MarkFMP, recordTypes.MarkFMPCandidate] : - []); - } - - /** * @return {!Object.<string, !Timeline.TimelineCategory>} */ static categories() { @@ -1746,10 +1731,31 @@ Timeline.TimelineUIUtils = class { /** * @param {!SDK.TracingModel.Event} event + * @return {?string} + */ + static markerShortTitle(event) { + const recordTypes = TimelineModel.TimelineModel.RecordType; + switch (event.name) { + case recordTypes.MarkDOMContent: + return ls`DCL`; + case recordTypes.MarkLoad: + return ls`L`; + case recordTypes.MarkFirstPaint: + return ls`FP`; + case recordTypes.MarkFCP: + return ls`FCP`; + case recordTypes.MarkFMP: + return ls`FMP`; + } + return null; + } + + /** + * @param {!SDK.TracingModel.Event} event * @return {!Timeline.TimelineMarkerStyle} */ static markerStyleForEvent(event) { - const tallMarkerDashStyle = [10, 5]; + const tallMarkerDashStyle = [6, 4]; const title = Timeline.TimelineUIUtils.eventTitle(event); if (event.hasCategory(TimelineModel.TimelineModel.Category.Console) || @@ -1772,11 +1778,11 @@ Timeline.TimelineUIUtils = class { tall = true; break; case recordTypes.MarkDOMContent: - color = 'blue'; + color = '#0867CB'; tall = true; break; case recordTypes.MarkLoad: - color = 'red'; + color = '#B31412'; tall = true; break; case recordTypes.MarkFirstPaint: @@ -1784,15 +1790,11 @@ Timeline.TimelineUIUtils = class { tall = true; break; case recordTypes.MarkFCP: - color = 'hsl(160, 43%, 58%)'; - tall = true; - break; - case recordTypes.MarkFMPCandidate: - color = 'hsl(146, 57%, 40%)'; + color = '#208043'; tall = true; break; case recordTypes.MarkFMP: - color = 'hsl(144, 100%, 21%)'; + color = '#14522B'; tall = true; break; case recordTypes.TimeStamp: @@ -2359,9 +2361,9 @@ Timeline.TimelineDetailsContentHelper = class { parentElement.classList.add('timeline-details-stack-values'); const stackTraceElement = parentElement.createChild('div', 'timeline-details-view-row-value timeline-details-view-row-stack-trace'); - const callFrameElem = + const callFrameContents = Components.JSPresentationUtils.buildStackTracePreviewContents(this._target, this._linkifier, stackTrace); - stackTraceElement.appendChild(callFrameElem); + stackTraceElement.appendChild(callFrameContents.element); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js index 332ace621d7..1b0efac5fbb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js @@ -88,19 +88,19 @@ TimelineModel.TimelineModel = class { * @param {!SDK.TracingModel.Event} event * @return {boolean} */ - static isMarkerEvent(event) { + isMarkerEvent(event) { const recordTypes = TimelineModel.TimelineModel.RecordType; switch (event.name) { - case recordTypes.FrameStartedLoading: case recordTypes.TimeStamp: + return true; case recordTypes.MarkFirstPaint: case recordTypes.MarkFCP: case recordTypes.MarkFMP: - case recordTypes.MarkFMPCandidate: - return true; + // TODO(alph): There are duplicate FMP events coming from the backend. Keep the one having 'data' property. + return this._mainFrame && event.args.frame === this._mainFrame.frameId && !!event.args.data; case recordTypes.MarkDOMContent: case recordTypes.MarkLoad: - return event.args['data']['isMainFrame']; + return !!event.args['data']['isMainFrame']; default: return false; } @@ -541,7 +541,7 @@ TimelineModel.TimelineModel = class { track.tasks.push(event); eventStack.push(event); } - if (TimelineModel.TimelineModel.isMarkerEvent(event)) + if (this.isMarkerEvent(event)) this._timeMarkerEvents.push(event); track.events.push(event); @@ -599,7 +599,7 @@ TimelineModel.TimelineModel = class { } if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.UserTiming)) { - group(TimelineModel.TimelineModel.TrackType.UserTiming).push(asyncEvent); + group(TimelineModel.TimelineModel.TrackType.Timings).push(asyncEvent); continue; } @@ -685,6 +685,10 @@ TimelineModel.TimelineModel = class { pageFrameId = TimelineModel.TimelineData.forEvent(eventStack.peekLast()).frameId; timelineData.frameId = pageFrameId || (this._mainFrame && this._mainFrame.frameId) || ''; this._asyncEventTracker.processEvent(event); + + if (this.isMarkerEvent(event)) + this._ensureNamedTrack(TimelineModel.TimelineModel.TrackType.Timings); + switch (event.name) { case recordTypes.ResourceSendRequest: case recordTypes.WebSocketCreate: @@ -1215,7 +1219,6 @@ TimelineModel.TimelineModel.RecordType = { MarkFirstPaint: 'MarkFirstPaint', MarkFCP: 'firstContentfulPaint', MarkFMP: 'firstMeaningfulPaint', - MarkFMPCandidate: 'firstMeaningfulPaintCandidate', TimeStamp: 'TimeStamp', ConsoleTime: 'ConsoleTime', @@ -1396,7 +1399,7 @@ TimelineModel.TimelineModel.TrackType = { Worker: Symbol('Worker'), Input: Symbol('Input'), Animation: Symbol('Animation'), - UserTiming: Symbol('UserTiming'), + Timings: Symbol('Timings'), Console: Symbol('Console'), Raster: Symbol('Raster'), GPU: Symbol('GPU'), diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js index 0178835dbff..648ca00c381 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js @@ -118,36 +118,18 @@ UI.ShortcutRegistry = class { * @param {string} domKey * @param {!KeyboardEvent=} event */ - handleKey(key, domKey, event) { + async handleKey(key, domKey, event) { const keyModifiers = key >> 8; const actions = this._applicableActions(key); - if (!actions.length) + if (!actions.length || isPossiblyInputKey()) return; - if (UI.Dialog.hasInstance()) { - if (event && !isPossiblyInputKey()) - event.consume(true); + if (event) + event.consume(true); + if (UI.Dialog.hasInstance()) return; - } - - if (!isPossiblyInputKey()) { - if (event) - event.consume(true); - processNextAction.call(this, false); - } else { - this._pendingActionTimer = setTimeout(processNextAction.bind(this, false), 0); - } - - /** - * @param {boolean} handled - * @this {UI.ShortcutRegistry} - */ - function processNextAction(handled) { - delete this._pendingActionTimer; - const action = actions.shift(); - if (!action || handled) + for (const action of actions) { + if (await action.execute()) return; - - action.execute().then(processNextAction.bind(this)); } /** @@ -203,18 +185,10 @@ UI.ShortcutRegistry = class { this._defaultKeyToActions.set(String(descriptor.key), actionId); } - dismissPendingShortcutAction() { - if (this._pendingActionTimer) { - clearTimeout(this._pendingActionTimer); - delete this._pendingActionTimer; - } - } - /** * @param {!Document} document */ _registerBindings(document) { - document.addEventListener('input', this.dismissPendingShortcutAction.bind(this), true); const extensions = self.runtime.extensions('action'); extensions.forEach(registerExtension, this); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/UIUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/UIUtils.js index 9c2761c2ef7..7531b84bb83 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/UIUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/UIUtils.js @@ -2045,3 +2045,32 @@ UI.createExpandableText = function(text, maxLength) { }); return fragment; }; + +/** + * @interface + */ +UI.Renderer = function() {}; + +UI.Renderer.prototype = { + /** + * @param {!Object} object + * @param {!UI.Renderer.Options=} options + * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>} + */ + render(object, options) {} +}; + +/** + * @param {?Object} object + * @param {!UI.Renderer.Options=} options + * @return {!Promise<?{node: !Node, tree: ?UI.TreeOutline}>} + */ +UI.Renderer.render = async function(object, options) { + if (!object) + throw new Error('Can\'t render ' + object); + const renderer = await self.runtime.extension(UI.Renderer, object).instance(); + return renderer ? renderer.render(object, options || {}) : null; +}; + +/** @typedef {!{title: (string|!Element|undefined), editable: (boolean|undefined) }} */ +UI.Renderer.Options; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/textPrompt.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/textPrompt.css index 7194f1cc897..5fb0dd61738 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/textPrompt.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/textPrompt.css @@ -61,3 +61,7 @@ .text-prompt-editing ::content br { display: none; } + +:host-context(:not(:focus-within)) ::content ::selection { + background: transparent; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css index b83ae08c0b7..d8610f5cc42 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css @@ -5,7 +5,7 @@ */ :host { - flex: 1 1; + flex: 1 1 auto; padding: 2px 0 0 0; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js index 3f5c34745ac..cb4ed7cdd78 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js @@ -43,6 +43,7 @@ UI.TreeOutline = class extends Common.Object { this.contentElement = this._rootElement._childrenListNode; this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this), false); + this._preventTabOrder = false; this._showSelectionOnKeyboardFocus = false; this._focusable = true; this.setFocusable(this._focusable); @@ -54,9 +55,11 @@ UI.TreeOutline = class extends Common.Object { /** * @param {boolean} show + * @param {boolean=} preventTabOrder */ - setShowSelectionOnKeyboardFocus(show) { + setShowSelectionOnKeyboardFocus(show, preventTabOrder) { this.contentElement.classList.toggle('hide-selection-when-blurred', show); + this._preventTabOrder = !!preventTabOrder; this._showSelectionOnKeyboardFocus = show; } @@ -225,7 +228,7 @@ UI.TreeOutline = class extends Common.Object { /** * @return {boolean} */ - _selectFirst() { + selectFirst() { let first = this.firstChild(); while (first && !first.selectable) first = first.traverseNextTreeElement(true); @@ -276,7 +279,7 @@ UI.TreeOutline = class extends Common.Object { } else if (event.keyCode === UI.KeyboardShortcut.Keys.Space.code) { handled = this.selectedTreeElement.onspace(); } else if (event.key === 'Home') { - handled = this._selectFirst(); + handled = this.selectFirst(); } else if (event.key === 'End') { handled = this._selectLast(); } @@ -936,7 +939,7 @@ UI.TreeElement = class { * @return {boolean} */ collapseOrAscend(altKey) { - if (this.expanded) { + if (this.expanded && this._collapsible) { if (altKey) this.collapseRecursively(); else @@ -1035,8 +1038,11 @@ UI.TreeElement = class { * @return {boolean} */ select(omitFocus, selectedByUser) { - if (!this.treeOutline || !this.selectable || this.selected) + if (!this.treeOutline || !this.selectable || this.selected) { + if (!omitFocus) + this.listItemElement.focus(); return false; + } // Wait to deselect this element so that focus only changes once const lastSelected = this.treeOutline.selectedTreeElement; this.treeOutline.selectedTreeElement = null; @@ -1044,6 +1050,8 @@ UI.TreeElement = class { if (this.treeOutline._rootElement === this) { if (lastSelected) lastSelected.deselect(); + if (!omitFocus) + this.listItemElement.focus(); return false; } @@ -1067,7 +1075,7 @@ UI.TreeElement = class { */ _setFocusable(focusable) { if (focusable) { - this._listItemNode.setAttribute('tabIndex', 0); + this._listItemNode.setAttribute('tabIndex', this.treeOutline && this.treeOutline._preventTabOrder ? -1 : 0); this._listItemNode.addEventListener('focus', this._boundOnFocus, false); this._listItemNode.addEventListener('blur', this._boundOnBlur, false); } else { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json index bb5c7d438ff..5975d54503f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json @@ -3,7 +3,6 @@ { "name": "mobile_throttling", "type": "autostart" }, { "name": "worker_main", "type": "autostart" }, - { "name": "browser_console" }, { "name": "browser_debugger" }, { "name": "cookie_table" }, { "name": "elements" }, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/worker_main/WorkerMain.js b/chromium/third_party/blink/renderer/devtools/front_end/worker_main/WorkerMain.js index 71cf0ca5c0f..c9971425a15 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/worker_main/WorkerMain.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/worker_main/WorkerMain.js @@ -10,29 +10,21 @@ WorkerMain.WorkerMain = class extends Common.Object { * @override */ run() { - const capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.Log | SDK.Target.Capability.Network | - SDK.Target.Capability.Target | SDK.Target.Capability.Inspector; - SDK.targetManager.createTarget( - 'main', Common.UIString('Main'), capabilities, this._createMainConnection.bind(this), null, false /* isNodeJS */); - InspectorFrontendHost.connectionReady(); + SDK.initMainConnection(() => { + SDK.targetManager.createTarget('main', ls`Main`, SDK.Target.Type.ServiceWorker, null); + }, Components.TargetDetachedDialog.webSocketConnectionLost); new MobileThrottling.NetworkPanelIndicator(); } - - /** - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createMainConnection(params) { - return SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost()); - } }; -SDK.ChildTargetManager.install(({target, waitingForDebugger}) => { - const parentTarget = target.parentTarget(); +SDK.ChildTargetManager.install(async ({target, waitingForDebugger}) => { // Only pause the new worker if debugging SW - we are going through the pause on start checkbox. - if (!parentTarget.parentTarget() && waitingForDebugger) { - const debuggerModel = target.model(SDK.DebuggerModel); - if (debuggerModel) - debuggerModel.pause(); - } + if (target.parentTarget().type() !== SDK.Target.Type.ServiceWorker || !waitingForDebugger) + return; + const debuggerModel = target.model(SDK.DebuggerModel); + if (!debuggerModel) + return; + if (!debuggerModel.isReadyToPause()) + await debuggerModel.once(SDK.DebuggerModel.Events.DebuggerIsReadyToPause); + debuggerModel.pause(); }); |