diff --git a/BUILD.gn b/BUILD.gn index 0018559c32..36f41cff83 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -469,7 +469,6 @@ all_devtools_files = [ "front_end/sdk/ServiceWorkerCacheModel.js", "front_end/sdk/ServiceWorkerManager.js", "front_end/sdk/SourceMap.js", - "front_end/sdk/SubTargetsManager.js", "front_end/sdk/Target.js", "front_end/sdk/TargetManager.js", "front_end/sdk/TracingManager.js", @@ -658,7 +657,6 @@ all_devtools_files = [ "front_end/ui/SoftContextMenu.js", "front_end/ui/splitWidget.css", "front_end/ui/SplitWidget.js", - "front_end/ui/StackView.js", "front_end/ui/suggestBox.css", "front_end/ui/SuggestBox.js", "front_end/ui/tabbedPane.css", diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 8078939604..162369251e 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -31,11 +31,8 @@ for more details about the presubmit API built into gcl. """ -from collections import namedtuple import sys -CheckOutput = namedtuple('CheckOutput', ['results', 'has_errors']) - def _CheckNodeAndNPMModules(input_api, output_api): node_script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "install_node_deps.py") @@ -43,14 +40,18 @@ def _CheckNodeAndNPMModules(input_api, output_api): [input_api.python_executable, node_script_path], stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT) out, _ = process.communicate() if process.returncode != 0: - return CheckOutput([output_api.PresubmitError(out)], has_errors=True) - return CheckOutput([output_api.PresubmitNotifyResult(out)], has_errors=False) + return [output_api.PresubmitError(out)] + return [output_api.PresubmitNotifyResult(out)] + + +def _CheckFormat(input_api, output_api): + def popen(args): + return input_api.subprocess.Popen(args=args, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT) -def _FormatDevtools(input_api, output_api): affected_files = _getAffectedJSFiles(input_api) if len(affected_files) == 0: - return CheckOutput([], has_errors=False) + return [] original_sys_path = sys.path try: sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")] @@ -59,39 +60,34 @@ def _FormatDevtools(input_api, output_api): sys.path = original_sys_path node_path, _ = install_node_deps.resolve_node_paths() - format_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "format.js") - glob_arg = "--glob=" + ",".join(affected_files) - check_formatting_process = _inputPopen(input_api, args=[node_path, format_path] + [glob_arg, "--output-replacements-xml"]) - check_formatting_out, _ = check_formatting_process.communicate() - if check_formatting_process.returncode != 0: - return CheckOutput([output_api.PresubmitError(check_formatting_out)], has_errors=True) - if "" not in check_formatting_out: - return CheckOutput([output_api.PresubmitNotifyResult("CL is properly formatted")], has_errors=False) - - format_args = [node_path, format_path] + [glob_arg] - format_process = _inputPopen(input_api, format_args) - format_process_out, _ = format_process.communicate() + + check_formatting_process = popen(['git', 'cl', 'format', '--js', '--dry-run', input_api.PresubmitLocalPath()]) + check_formatting_process.communicate() + if check_formatting_process.returncode == 0: + return [] + + format_args = ['git', 'cl', 'format', '--js', input_api.PresubmitLocalPath()] + format_process = popen(format_args) + format_out, _ = format_process.communicate() + if format_process.returncode != 0: + return [output_api.PresubmitError(format_out)] # Use eslint to autofix the braces eslint_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "node_modules", ".bin", "eslint") - eslint_process = _inputPopen( - input_api, - [node_path, eslint_path, '--no-eslintrc', '--fix', '--env=es6', '--rule={"curly": [2, "multi-or-nest", "consistent"]}'] + - affected_files) + eslint_process = popen([ + node_path, eslint_path, '--no-eslintrc', '--fix', '--env=es6', '--rule={"curly": [2, "multi-or-nest", "consistent"]}' + ] + affected_files) eslint_process.communicate() # Need to run clang-format again to align the braces - reformat_process = _inputPopen(input_api, format_args) - reformat_process.communicate() + popen(format_args).communicate() - return CheckOutput( - [ - output_api.PresubmitError("ERROR: Found formatting violations.\n" - "Ran clang-format on files changed in CL\n" - "Use git status to check the formatting changes"), - output_api.PresubmitError(format_process_out) - ], - has_errors=True) + return [ + output_api.PresubmitError("ERROR: Found formatting violations in third_party/WebKit/Source/devtools.\n" + "Ran clang-format on diff\n" + "Use git status to check the formatting changes"), + output_api.PresubmitError(format_out), + ] def _CheckDevtoolsStyle(input_api, output_api): @@ -188,19 +184,8 @@ def _CheckCSSViolations(input_api, output_api): def CheckChangeOnUpload(input_api, output_api): results = [] - - (node_results, has_errors) = _CheckNodeAndNPMModules(input_api, output_api) - results.extend(node_results) - if has_errors: - results.append(output_api.PresubmitError("ERROR: Bailed out early because error using node.js/npm")) - return results - - (format_results, has_errors) = _FormatDevtools(input_api, output_api) - results.extend(format_results) - if has_errors: - results.append(output_api.PresubmitError("ERROR: Bailed out early because formatting errors were found")) - return results - + results.extend(_CheckNodeAndNPMModules(input_api, output_api)) + results.extend(_CheckFormat(input_api, output_api)) results.extend(_CheckDevtoolsStyle(input_api, output_api)) results.extend(_CompileDevtoolsFrontend(input_api, output_api)) results.extend(_CheckConvertSVGToPNGHashes(input_api, output_api)) @@ -233,7 +218,3 @@ def _getAffectedJSFiles(input_api): if (devtools_front_end in file_name or devtools_scripts in file_name) and file_name.endswith(".js") ] return [input_api.os_path.relpath(file_name, devtools_root) for file_name in affected_js_files] - - -def _inputPopen(input_api, args): - return input_api.subprocess.Popen(args, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT) diff --git a/front_end/Images/smallIcons.png b/front_end/Images/smallIcons.png index d4040dab46..0e9e67c569 100644 Binary files a/front_end/Images/smallIcons.png and b/front_end/Images/smallIcons.png differ diff --git a/front_end/Images/smallIcons_2x.png b/front_end/Images/smallIcons_2x.png index f7be16491a..7102809ff1 100644 Binary files a/front_end/Images/smallIcons_2x.png and b/front_end/Images/smallIcons_2x.png differ diff --git a/front_end/Images/src/optimize_png.hashes b/front_end/Images/src/optimize_png.hashes index 1965213cf1..a635ead8a6 100644 --- a/front_end/Images/src/optimize_png.hashes +++ b/front_end/Images/src/optimize_png.hashes @@ -4,7 +4,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "044ba42204fd8ae030835e2ca78433bf", + "smallIcons.svg": "b8336251749394a04c66de7e4a29e51e", "toolbarButtonGlyphs.svg": "fa5911823785a90273dfea76fe4ce512", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", diff --git a/front_end/Images/src/smallIcons.svg b/front_end/Images/src/smallIcons.svg index a30ed84f5a..3a140ca98c 100644 --- a/front_end/Images/src/smallIcons.svg +++ b/front_end/Images/src/smallIcons.svg @@ -14,7 +14,7 @@ height="30" id="svg3250" version="1.1" - inkscape:version="0.92.0 r" + inkscape:version="0.48.4 r9939" sodipodi:docname="smallIcons.svg"> @@ -351,16 +351,16 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="3.8890873" - inkscape:cx="92.377869" - inkscape:cy="-2.2195908" + inkscape:zoom="22" + inkscape:cx="129.30954" + inkscape:cy="14.946709" inkscape:document-units="px" inkscape:current-layer="svg3250" showgrid="true" inkscape:window-width="1278" - inkscape:window-height="746" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:window-height="995" + inkscape:window-x="75" + inkscape:window-y="34" inkscape:window-maximized="0"> - - - + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccc" /> + + + + + + diff --git a/front_end/Images/src/svg2png.hashes b/front_end/Images/src/svg2png.hashes index 1965213cf1..a635ead8a6 100644 --- a/front_end/Images/src/svg2png.hashes +++ b/front_end/Images/src/svg2png.hashes @@ -4,7 +4,7 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "044ba42204fd8ae030835e2ca78433bf", + "smallIcons.svg": "b8336251749394a04c66de7e4a29e51e", "toolbarButtonGlyphs.svg": "fa5911823785a90273dfea76fe4ce512", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", diff --git a/front_end/Tests.js b/front_end/Tests.js index 11a6be78ff..8a2af93c77 100644 --- a/front_end/Tests.js +++ b/front_end/Tests.js @@ -912,7 +912,7 @@ var test = this; this.showPanel('timeline').then(function() { var timeline = UI.panels.timeline; - test._overrideMethod(timeline, 'recordingStarted', callback); + test._overrideMethod(timeline, '_recordingStarted', callback); timeline._toggleRecording(); }); }; diff --git a/front_end/bindings/NetworkProject.js b/front_end/bindings/NetworkProject.js index 719487ad04..6cea05b680 100644 --- a/front_end/bindings/NetworkProject.js +++ b/front_end/bindings/NetworkProject.js @@ -31,13 +31,12 @@ * @implements {SDK.TargetManager.Observer} * @unrestricted */ -Bindings.NetworkProjectManager = class extends Common.Object { +Bindings.NetworkProjectManager = class { /** * @param {!SDK.TargetManager} targetManager * @param {!Workspace.Workspace} workspace */ constructor(targetManager, workspace) { - super(); this._workspace = workspace; targetManager.observeTargets(this); } @@ -59,17 +58,6 @@ Bindings.NetworkProjectManager = class extends Common.Object { } }; -/** @implements {Common.Emittable} */ -Bindings.NetworkProjectManager.FrameAttributionChangedEvent = class { - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - constructor(uiSourceCode) { - this.uiSourceCode = uiSourceCode; - } -}; - - /** * @unrestricted */ @@ -82,9 +70,10 @@ Bindings.NetworkProject = class extends SDK.SDKObject { constructor(target, workspace, resourceTreeModel) { super(target); this._workspace = workspace; + /** @type {!Map} */ + this._workspaceProjects = new Map(); this._resourceTreeModel = resourceTreeModel; target[Bindings.NetworkProject._networkProjectSymbol] = this; - this._createProjects(); this._eventListeners = []; @@ -116,11 +105,12 @@ Bindings.NetworkProject = class extends SDK.SDKObject { /** * @param {!SDK.Target} target + * @param {?SDK.ResourceTreeFrame} frame * @param {boolean} isContentScripts * @return {string} */ - static projectId(target, isContentScripts) { - return (isContentScripts ? 'contentscripts' : 'networkproject') + ':' + target.id(); + static projectId(target, frame, isContentScripts) { + return target.id() + ':' + (frame ? frame.id : '') + ':' + (isContentScripts ? 'contentscripts' : ''); } /** @@ -132,11 +122,19 @@ Bindings.NetworkProject = class extends SDK.SDKObject { } /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {?Set} + * @param {!Workspace.Project} project + * @return {?SDK.Target} target + */ + static targetForProject(project) { + return project[Bindings.NetworkProject._targetSymbol] || null; + } + + /** + * @param {!Workspace.Project} project + * @return {?SDK.ResourceTreeFrame} */ - static framesForUISourceCode(uiSourceCode) { - return uiSourceCode[Bindings.NetworkProject._frameSymbol] || null; + static frameForProject(project) { + return project[Bindings.NetworkProject._frameSymbol] || null; } /** @@ -144,7 +142,7 @@ Bindings.NetworkProject = class extends SDK.SDKObject { * @return {?SDK.Target} target */ static targetForUISourceCode(uiSourceCode) { - return uiSourceCode.project()[Bindings.NetworkProject._targetSymbol] || null; + return uiSourceCode[Bindings.NetworkProject._targetSymbol] || null; } /** @@ -152,7 +150,7 @@ Bindings.NetworkProject = class extends SDK.SDKObject { * @return {string} */ static uiSourceCodeMimeType(uiSourceCode) { - if (uiSourceCode[Bindings.NetworkProject._useCanonicalMimeType]) + if (uiSourceCode[Bindings.NetworkProject._scriptSymbol] || uiSourceCode[Bindings.NetworkProject._styleSheetSymbol]) return uiSourceCode.contentType().canonicalMimeType(); var resource = uiSourceCode[Bindings.NetworkProject._resourceSymbol]; @@ -163,36 +161,24 @@ Bindings.NetworkProject = class extends SDK.SDKObject { } /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {!SDK.ResourceTreeFrame} frame + * @param {?SDK.ResourceTreeFrame} frame + * @param {boolean} isContentScripts + * @return {!Bindings.ContentProviderBasedProject} */ - _addFrameToUISourceCode(uiSourceCode, frame) { - var frames = uiSourceCode[Bindings.NetworkProject._frameSymbol]; - if (!frames) { - frames = /** @type {!Set} */ (new Set()); - uiSourceCode[Bindings.NetworkProject._frameSymbol] = frames; - } - frames.add(frame); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {!SDK.ResourceTreeFrame} frame - */ - _removeFrameFromUISourceCode(uiSourceCode, frame) { - var frames = uiSourceCode[Bindings.NetworkProject._frameSymbol]; - frames.delete(frame); - } - - _createProjects() { - this._regularProject = new Bindings.ContentProviderBasedProject( - this._workspace, Bindings.NetworkProject.projectId(this.target(), false), Workspace.projectTypes.Network, '', - false /* isServiceProject */); - this._regularProject[Bindings.NetworkProject._targetSymbol] = this.target(); - this._contentScriptsProject = new Bindings.ContentProviderBasedProject( - this._workspace, Bindings.NetworkProject.projectId(this.target(), true), Workspace.projectTypes.ContentScripts, - '', false /* isServiceProject */); - this._contentScriptsProject[Bindings.NetworkProject._targetSymbol] = this.target(); + _workspaceProject(frame, isContentScripts) { + var projectId = Bindings.NetworkProject.projectId(this.target(), frame, isContentScripts); + var projectType = isContentScripts ? Workspace.projectTypes.ContentScripts : Workspace.projectTypes.Network; + + var project = this._workspaceProjects.get(projectId); + if (project) + return project; + + project = new Bindings.ContentProviderBasedProject( + this._workspace, projectId, projectType, '', false /* isServiceProject */); + project[Bindings.NetworkProject._targetSymbol] = this.target(); + project[Bindings.NetworkProject._frameSymbol] = frame; + this._workspaceProjects.set(projectId, project); + return project; } /** @@ -209,6 +195,17 @@ Bindings.NetworkProject = class extends SDK.SDKObject { return uiSourceCode; } + /** + * @param {?SDK.ResourceTreeFrame} frame + * @param {string} url + */ + _removeFileForURL(frame, url) { + var project = this._workspaceProjects.get(Bindings.NetworkProject.projectId(this.target(), frame, false)); + if (!project) + return; + project.removeFile(url); + } + _populate() { /** * @param {!SDK.ResourceTreeFrame} frame @@ -252,19 +249,12 @@ Bindings.NetworkProject = class extends SDK.SDKObject { if (!parsedURL.isValid) return; } - var frame = SDK.ResourceTreeFrame.fromScript(script); - var url = script.sourceURL; - var project = script.isContentScript() ? this._contentScriptsProject : this._regularProject; - var oldSourceCode = project.uiSourceCodeForURL(url); - var oldFrames = oldSourceCode ? Bindings.NetworkProject.framesForUISourceCode(oldSourceCode) : null; - var newSourceCode = this._createFile(script, frame, script.isContentScript()); - newSourceCode[Bindings.NetworkProject._useCanonicalMimeType] = true; - if (oldFrames) { - for (var oldFrame of oldFrames) - this._addFrameToUISourceCode(newSourceCode, oldFrame); - } - var metadata = frame ? Bindings.resourceMetadata(frame.resourceForURL(newSourceCode.url())) : null; - this._addUISourceCodeWithProvider(newSourceCode, script, metadata); + var originalContentProvider = script.originalContentProvider(); + var uiSourceCode = + this._createFile(originalContentProvider, SDK.ResourceTreeFrame.fromScript(script), script.isContentScript()); + uiSourceCode[Bindings.NetworkProject._scriptSymbol] = script; + var resource = SDK.ResourceTreeModel.resourceForURL(uiSourceCode.url()); + this._addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, this._resourceMetadata(resource)); } /** @@ -274,23 +264,14 @@ Bindings.NetworkProject = class extends SDK.SDKObject { var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector') return; - var url = header.resourceURL(); - if (!url) + if (!header.resourceURL()) return; - var frame = SDK.ResourceTreeFrame.fromStyleSheet(header); - var uiSourceCode = this._regularProject.uiSourceCodeForURL(url); - if (uiSourceCode) { - this._addFrameToUISourceCode(uiSourceCode, frame); - Bindings.networkProjectManager.emit( - new Bindings.NetworkProjectManager.FrameAttributionChangedEvent(uiSourceCode)); - return; - } var originalContentProvider = header.originalContentProvider(); - uiSourceCode = this._createFile(originalContentProvider, frame, false); - uiSourceCode[Bindings.NetworkProject._useCanonicalMimeType] = true; - var metadata = frame ? Bindings.resourceMetadata(frame.resourceForURL(uiSourceCode.url())) : null; - this._addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, metadata); + var uiSourceCode = this._createFile(originalContentProvider, SDK.ResourceTreeFrame.fromStyleSheet(header), false); + uiSourceCode[Bindings.NetworkProject._styleSheetSymbol] = header; + var resource = SDK.ResourceTreeModel.resourceForURL(uiSourceCode.url()); + this._addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, this._resourceMetadata(resource)); } /** @@ -301,16 +282,7 @@ Bindings.NetworkProject = class extends SDK.SDKObject { if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector') return; - var url = header.resourceURL(); - var uiSourceCode = this._regularProject.uiSourceCodeForURL(url); - if (!uiSourceCode) - return; - var frame = SDK.ResourceTreeFrame.fromStyleSheet(header); - this._removeFrameFromUISourceCode(uiSourceCode, frame); - var frames = - /** @type {!Set} */ (Bindings.NetworkProject.framesForUISourceCode(uiSourceCode)); - if (!frames.size) - this._regularProject.removeFile(url); + this._removeFileForURL(SDK.ResourceTreeFrame.fromStyleSheet(header), header.resourceURL()); } /** @@ -347,7 +319,7 @@ Bindings.NetworkProject = class extends SDK.SDKObject { var uiSourceCode = this._createFile(resource, SDK.ResourceTreeFrame.fromResource(resource), false); uiSourceCode[Bindings.NetworkProject._resourceSymbol] = resource; - this._addUISourceCodeWithProvider(uiSourceCode, resource, Bindings.resourceMetadata(resource)); + this._addUISourceCodeWithProvider(uiSourceCode, resource, this._resourceMetadata(resource)); } /** @@ -355,10 +327,12 @@ Bindings.NetworkProject = class extends SDK.SDKObject { */ _frameWillNavigate(event) { var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data); - for (var resource of frame.resources()) { - this._regularProject.removeUISourceCode(resource.url); - this._contentScriptsProject.removeUISourceCode(resource.url); - } + var project = this._workspaceProject(frame, false); + for (var resource of frame.resources()) + project.removeUISourceCode(resource.url); + project = this._workspaceProject(frame, true); + for (var resource of frame.resources()) + project.removeUISourceCode(resource.url); } /** @@ -384,24 +358,32 @@ Bindings.NetworkProject = class extends SDK.SDKObject { */ _createFile(contentProvider, frame, isContentScript) { var url = contentProvider.contentURL(); - var project = isContentScript ? this._contentScriptsProject : this._regularProject; + var project = this._workspaceProject(frame, isContentScript); var uiSourceCode = project.createUISourceCode(url, contentProvider.contentType()); - if (frame) - this._addFrameToUISourceCode(uiSourceCode, frame); + uiSourceCode[Bindings.NetworkProject._targetSymbol] = this.target(); return uiSourceCode; } + /** + * @param {?SDK.Resource} resource + * @return {?Workspace.UISourceCodeMetadata} + */ + _resourceMetadata(resource) { + if (!resource || (typeof resource.contentSize() !== 'number' && !resource.lastModified())) + return null; + return new Workspace.UISourceCodeMetadata(resource.lastModified(), resource.contentSize()); + } + _dispose() { - this._regularProject.removeProject(); - this._contentScriptsProject.removeProject(); + this._reset(); Common.EventTarget.removeEventListeners(this._eventListeners); delete this.target()[Bindings.NetworkProject._networkProjectSymbol]; } _reset() { - this._regularProject.removeProject(); - this._contentScriptsProject.removeProject(); - this._createProjects(); + for (var project of this._workspaceProjects.values()) + project.removeProject(); + this._workspaceProjects.clear(); } /** @@ -412,8 +394,9 @@ Bindings.NetworkProject = class extends SDK.SDKObject { */ static uiSourceCodeForScriptURL(workspace, url, script) { var target = script.debuggerModel.target(); - return workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, false), url) || - workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, true), url); + var frame = SDK.ResourceTreeFrame.fromScript(script); + return workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, frame, false), url) || + workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, frame, true), url); } /** @@ -423,12 +406,14 @@ Bindings.NetworkProject = class extends SDK.SDKObject { * @return {?Workspace.UISourceCode} */ static uiSourceCodeForStyleURL(workspace, url, header) { - return workspace.uiSourceCode(Bindings.NetworkProject.projectId(header.target(), false), url); + var frame = SDK.ResourceTreeFrame.fromStyleSheet(header); + return workspace.uiSourceCode(Bindings.NetworkProject.projectId(header.target(), frame, false), url); } }; Bindings.NetworkProject._networkProjectSymbol = Symbol('networkProject'); Bindings.NetworkProject._resourceSymbol = Symbol('resource'); -Bindings.NetworkProject._useCanonicalMimeType = Symbol('useCanonicalMimeType'); +Bindings.NetworkProject._scriptSymbol = Symbol('script'); +Bindings.NetworkProject._styleSheetSymbol = Symbol('styleSheet'); Bindings.NetworkProject._targetSymbol = Symbol('target'); Bindings.NetworkProject._frameSymbol = Symbol('frame'); diff --git a/front_end/bindings/ResourceUtils.js b/front_end/bindings/ResourceUtils.js index 8ddd2c9e82..d586241f48 100644 --- a/front_end/bindings/ResourceUtils.js +++ b/front_end/bindings/ResourceUtils.js @@ -86,13 +86,3 @@ Bindings.displayNameForURL = function(url) { var displayName = url.trimURL(parsedURL.host); return displayName === '/' ? parsedURL.host + '/' : displayName; }; - -/** - * @param {?SDK.Resource} resource - * @return {?Workspace.UISourceCodeMetadata} - */ -Bindings.resourceMetadata = function(resource) { - if (!resource || (typeof resource.contentSize() !== 'number' && !resource.lastModified())) - return null; - return new Workspace.UISourceCodeMetadata(resource.lastModified(), resource.contentSize()); -}; diff --git a/front_end/common/Object.js b/front_end/common/Object.js index a696fcb298..76643912ef 100644 --- a/front_end/common/Object.js +++ b/front_end/common/Object.js @@ -98,7 +98,7 @@ Common.Object = class { /** * @override - * @param {function(new:Common.Emittable, ...)} eventType + * @param {function(new:T, ...)} eventType * @param {function(!T)} listener * @param {!Object=} thisObject * @return {!Common.EventTarget.TypedEventDescriptor} @@ -115,9 +115,10 @@ Common.Object = class { /** * @override - * @param {function(new:Common.Emittable, ...)} eventType - * @param {function(!Common.Emittable)} listener + * @param {function(new:T, ...)} eventType + * @param {function(!T)} listener * @param {!Object=} thisObject + * @template T */ off(eventType, listener, thisObject) { if (!this._listeners || !this._listeners.has(eventType)) @@ -274,7 +275,7 @@ Common.EventTarget.prototype = { dispatchEventToListeners(eventType, eventData) {}, /** - * @param {function(new:Common.Emittable, ...)} eventType + * @param {function(new:T, ...)} eventType * @param {function(!T)} listener * @param {!Object=} thisObject * @return {!Common.EventTarget.TypedEventDescriptor} @@ -283,9 +284,10 @@ Common.EventTarget.prototype = { on(eventType, listener, thisObject) {}, /** - * @param {function(new:Common.Emittable, ...)} eventType - * @param {function(!Common.Emittable)} listener + * @param {function(new:T, ...)} eventType + * @param {function(!T)} listener * @param {!Object=} thisObject + * @template T */ off(eventType, listener, thisObject) {}, diff --git a/front_end/common/StaticContentProvider.js b/front_end/common/StaticContentProvider.js index 07bfc7eb68..6111e3b56b 100644 --- a/front_end/common/StaticContentProvider.js +++ b/front_end/common/StaticContentProvider.js @@ -49,7 +49,7 @@ Common.StaticContentProvider = class { * @return {!Promise} */ requestContent() { - return /** @type {!Promise} */ (this._lazyContent()); + return this._lazyContent(); } /** diff --git a/front_end/console/ConsoleView.js b/front_end/console/ConsoleView.js index e435228680..084a5c4f22 100644 --- a/front_end/console/ConsoleView.js +++ b/front_end/console/ConsoleView.js @@ -168,8 +168,6 @@ Console.ConsoleView = class extends UI.VBox { this._registerWithMessageSink(); SDK.targetManager.observeTargets(this); - this._initConsoleMessages(); - UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this); this._messagesElement.addEventListener('mousedown', this._updateStickToBottomOnMouseDown.bind(this), false); @@ -210,14 +208,14 @@ Console.ConsoleView = class extends UI.VBox { this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSetting.get()); } - _initConsoleMessages() { - var mainTarget = SDK.targetManager.mainTarget(); - var resourceTreeModel = mainTarget && SDK.ResourceTreeModel.fromTarget(mainTarget); - var resourcesLoaded = !resourceTreeModel || resourceTreeModel.cachedResourcesLoaded(); - if (!mainTarget || !resourcesLoaded) { - SDK.targetManager.addModelListener( - SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, - this); + /** + * @param {!SDK.Target} target + */ + _initConsoleMessages(target) { + var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); + if (resourceTreeModel && !resourceTreeModel.cachedResourcesLoaded()) { + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this); return; } this._fetchMultitargetMessages(); @@ -228,11 +226,8 @@ Console.ConsoleView = class extends UI.VBox { */ _onResourceTreeModelLoaded(event) { var resourceTreeModel = /** @type {!SDK.ResourceTreeModel} */ (event.data); - if (resourceTreeModel.target() !== SDK.targetManager.mainTarget()) - return; - SDK.targetManager.removeModelListener( - SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, - this); + resourceTreeModel.removeEventListener( + SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this); this._fetchMultitargetMessages(); } @@ -287,6 +282,8 @@ Console.ConsoleView = class extends UI.VBox { * @param {!SDK.Target} target */ targetAdded(target) { + if (target === SDK.targetManager.mainTarget()) + this._initConsoleMessages(target); this._viewport.invalidate(); } diff --git a/front_end/cookie_table/CookiesTable.js b/front_end/cookie_table/CookiesTable.js index 0bea9c03cd..5076c466d9 100644 --- a/front_end/cookie_table/CookiesTable.js +++ b/front_end/cookie_table/CookiesTable.js @@ -36,13 +36,15 @@ CookieTable.CookiesTable = class extends UI.VBox { * @param {function(!SDK.Cookie, ?SDK.Cookie, function(?string))=} saveCallback * @param {function()=} refreshCallback * @param {function()=} selectedCallback + * @param {function(!SDK.Cookie, function())=} deleteCallback * @param {string=} cookieDomain */ - constructor(saveCallback, refreshCallback, selectedCallback, cookieDomain) { + constructor(saveCallback, refreshCallback, selectedCallback, deleteCallback, cookieDomain) { super(); this._saveCallback = saveCallback; this._refreshCallback = refreshCallback; + this._deleteCallback = deleteCallback; this._cookieDomain = cookieDomain; var editable = !!saveCallback; @@ -98,7 +100,6 @@ CookieTable.CookiesTable = class extends UI.VBox { if (selectedCallback) this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, selectedCallback, this); - this._nextSelectedCookie = /** @type {?SDK.Cookie} */ (null); /** @type {?string} */ this._lastEditedColumnId = null; @@ -129,6 +130,16 @@ CookieTable.CookiesTable = class extends UI.VBox { return node ? node.cookie : null; } + /** + * @return {{current: ?SDK.Cookie, neighbor: ?SDK.Cookie}} + */ + _getSelectionCookies() { + var node = this._dataGrid.selectedNode; + var neighbor = node && (node.traverseNextNode(true) || node.traversePreviousNode(true)); + + return {current: node && node.cookie, neighbor: neighbor && neighbor.cookie}; + } + /** * @override */ @@ -136,14 +147,43 @@ CookieTable.CookiesTable = class extends UI.VBox { this._lastEditedColumnId = null; } + /** + * @param {{current: ?SDK.Cookie, neighbor: ?SDK.Cookie}} selectionCookies + * @param {!Array} cookies + * @return {?SDK.Cookie} + */ + _findSelectedCookie(selectionCookies, cookies) { + var current = selectionCookies.current; + var foundCurrent = cookies.find(cookie => this._isSameCookie(cookie, current)); + if (foundCurrent) + return foundCurrent; + + var neighbor = selectionCookies.neighbor; + var foundNeighbor = cookies.find(cookie => this._isSameCookie(cookie, neighbor)); + if (foundNeighbor) + return foundNeighbor; + + return null; + } + + /** + * @param {!SDK.Cookie} cookieA + * @param {?SDK.Cookie} cookieB + * @return {boolean} + */ + _isSameCookie(cookieA, cookieB) { + return !!cookieB && cookieB.name() === cookieA.name() && cookieB.domain() === cookieA.domain() && + cookieB.path() === cookieA.path(); + } + _rebuildTable() { - var selectedCookie = this._nextSelectedCookie || this.selectedCookie(); + var selectionCookies = this._getSelectionCookies(); var lastEditedColumnId = this._lastEditedColumnId; - this._nextSelectedCookie = null; this._lastEditedColumnId = null; this._dataGrid.rootNode().removeChildren(); for (var i = 0; i < this._data.length; ++i) { var item = this._data[i]; + var selectedCookie = this._findSelectedCookie(selectionCookies, item.cookies); if (item.folderName) { var groupData = { name: item.folderName, @@ -188,8 +228,7 @@ CookieTable.CookiesTable = class extends UI.VBox { var cookie = cookies[i]; var cookieNode = this._createGridNode(cookie); parentNode.appendChild(cookieNode); - if (selectedCookie && selectedCookie.name() === cookie.name() && selectedCookie.domain() === cookie.domain() && - selectedCookie.path() === cookie.path()) { + if (this._isSameCookie(cookie, selectedCookie)) { cookieNode.select(); if (lastEditedColumnId !== null) this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode, lastEditedColumnId); @@ -313,13 +352,12 @@ CookieTable.CookiesTable = class extends UI.VBox { return node; } + /** + * @param {!DataGrid.DataGridNode} node + */ _onDeleteCookie(node) { - var cookie = node.cookie; - var neighbour = node.traverseNextNode() || node.traversePreviousNode(); - if (neighbour) - this._nextSelectedCookie = neighbour.cookie; - cookie.remove(); - this._refresh(); + if (node.cookie && this._deleteCallback) + this._deleteCallback(node.cookie, () => this._refresh()); } /** @@ -366,7 +404,6 @@ CookieTable.CookiesTable = class extends UI.VBox { else node.setDirty(true); }); - this._nextSelectedCookie = newCookie; } /** diff --git a/front_end/coverage/CoverageListView.js b/front_end/coverage/CoverageListView.js index 330fa2d70a..abc86f261e 100644 --- a/front_end/coverage/CoverageListView.js +++ b/front_end/coverage/CoverageListView.js @@ -15,7 +15,7 @@ Coverage.CoverageListView = class extends UI.VBox { sortable: true, align: DataGrid.DataGrid.Align.Right }, - { + {id: 'type', title: Common.UIString('Type'), width: '30px', fixedWidth: true, sortable: true}, { id: 'unusedSize', title: Common.UIString('Unused Bytes'), width: '60px', @@ -91,6 +91,9 @@ Coverage.CoverageListView = class extends UI.VBox { case 'url': sortFunction = compareURL; break; + case 'type': + sortFunction = compareNumericField.bind(null, 'type'); + break; case 'size': sortFunction = compareNumericField.bind(null, 'size'); break; @@ -129,6 +132,18 @@ Coverage.CoverageListView = class extends UI.VBox { return nodeA._coverageInfo[fieldName] - nodeB._coverageInfo[fieldName]; } } + + /** + * @param {!Coverage.CoverageType} type + */ + static _typeToString(type) { + var types = []; + if (type & Coverage.CoverageType.CSS) + types.push(Common.UIString('CSS')); + if (type & Coverage.CoverageType.JavaScript) + types.push(Common.UIString('JS')); + return types.join('+'); + } }; Coverage.CoverageListView.GridNode = class extends DataGrid.SortableDataGridNode { @@ -152,6 +167,10 @@ Coverage.CoverageListView.GridNode = class extends DataGrid.SortableDataGridNode switch (columnId) { case 'url': cell.textContent = this._coverageInfo.url; + cell.title = this._coverageInfo.url; + break; + case 'type': + cell.textContent = Coverage.CoverageListView._typeToString(this._coverageInfo.type); break; case 'size': cell.classList.add('numeric-column'); diff --git a/front_end/coverage/CoverageView.js b/front_end/coverage/CoverageView.js index 5c40b1e10e..fe27fdd867 100644 --- a/front_end/coverage/CoverageView.js +++ b/front_end/coverage/CoverageView.js @@ -8,10 +8,25 @@ Coverage.RangeUsage; /** @typedef {{styleSheetHeader: !SDK.CSSStyleSheetHeader, ranges: !Array}} */ Coverage.StyleSheetUsage; -/** @typedef {{url: string, size: (number|undefined), unusedSize: (number|undefined), usedSize: (number|undefined), - * ranges: !Array}} */ +/** @typedef {{ + * url: string, + * size: (number|undefined), + * unusedSize: (number|undefined), + * usedSize: (number|undefined), + * type: !Coverage.CoverageType, + * ranges: !Array + * }} + */ Coverage.CoverageInfo; +/** + * @enum {number} + */ +Coverage.CoverageType = { + CSS: (1 << 0), + JavaScript: (1 << 1), +}; + Coverage.CoverageView = class extends UI.VBox { constructor() { super(true); @@ -64,11 +79,14 @@ Coverage.CoverageView = class extends UI.VBox { if (!mainTarget) return; var cssModel = mainTarget.model(SDK.CSSModel); - if (!cssModel) + var cpuProfilerModel = mainTarget.model(SDK.CPUProfilerModel); + if (!cssModel && !cpuProfilerModel) return; this._toggleRecordAction.setToggled(true); - cssModel.startRuleUsageTracking(); - mainTarget.profilerAgent().startPreciseCoverage(); + if (cssModel) + cssModel.startRuleUsageTracking(); + if (cpuProfilerModel) + cpuProfilerModel.startPreciseCoverage(); this._progressElement.textContent = Common.UIString('Recording...'); } @@ -112,6 +130,7 @@ Coverage.CoverageView = class extends UI.VBox { lastEntry.size += entry.size; lastEntry.usedSize += entry.usedSize; lastEntry.unusedSize += entry.unusedSize; + lastEntry.type |= entry.type; } else { result.push(entry); } @@ -124,11 +143,11 @@ Coverage.CoverageView = class extends UI.VBox { */ async _stopJSCoverage() { var mainTarget = SDK.targetManager.mainTarget(); - var profilerAgent = mainTarget && mainTarget.profilerAgent(); - if (!profilerAgent) + var cpuProfilerModel = mainTarget ? mainTarget.model(SDK.CPUProfilerModel) : null; + if (!cpuProfilerModel) return []; - var coveragePromise = profilerAgent.takePreciseCoverage((error, result) => error ? [] : result); - profilerAgent.stopPreciseCoverage(); + var coveragePromise = cpuProfilerModel.takePreciseCoverage(); + cpuProfilerModel.stopPreciseCoverage(); var rawCoverageData = await coveragePromise; return Coverage.CoverageView._processJSCoverage( /** @type !SDK.DebuggerModel */ (SDK.DebuggerModel.fromTarget(mainTarget)), rawCoverageData); @@ -153,20 +172,9 @@ Coverage.CoverageView = class extends UI.VBox { ranges.push({range: textRange, wasUsed: !!range.count}); } } - promises.push(convertToCoverageInfo(script, ranges)); + promises.push(Coverage.CoverageView._coverageInfoForText(script, script.lineOffset, script.columnOffset, ranges)); } return Promise.all(promises); - - /** - * @param {!SDK.Script} script - * @param {!Array} ranges - * @return {!Promise} - */ - function convertToCoverageInfo(script, ranges) { - return script.requestContent().then( - content => Coverage.CoverageView._coverageInfoForText( - script.contentURL(), script.lineOffset, script.columnOffset, content, ranges)); - } } /** @@ -205,33 +213,30 @@ Coverage.CoverageView = class extends UI.VBox { rule.range.endColumn + (rule.range.endLine ? 0 : styleSheetHeader.startColumn)); ranges.push({range: textRange, wasUsed: rule.wasUsed}); } - return Promise.all(Array.from(rulesByStyleSheet.entries(), entry => convertToCoverageInfo(entry[0], entry[1]))); - - /** - * @param {!SDK.CSSStyleSheetHeader} styleSheetHeader - * @param {!Array} ranges - * @return {!Promise} - */ - function convertToCoverageInfo(styleSheetHeader, ranges) { - return styleSheetHeader.requestContent().then( - content => Coverage.CoverageView._coverageInfoForText( - styleSheetHeader.sourceURL, styleSheetHeader.startLine, styleSheetHeader.startColumn, content, ranges)); - } + return Promise.all(Array.from( + rulesByStyleSheet.entries(), entry => Coverage.CoverageView._coverageInfoForText( + entry[0], entry[0].startLine, entry[0].startColumn, entry[1]))); } /** - * @param {string} url + * @param {!Common.ContentProvider} contentProvider * @param {number} startLine * @param {number} startColumn - * @param {?string} content * @param {!Array} ranges - * @return {!Coverage.CoverageInfo} + * @return {!Promise} */ - static _coverageInfoForText(url, startLine, startColumn, content, ranges) { - var coverageInfo = { - url: url, - ranges: ranges, - }; + static async _coverageInfoForText(contentProvider, startLine, startColumn, ranges) { + var url = contentProvider.contentURL(); + var coverageType; + if (contentProvider.contentType().isScript()) + coverageType = Coverage.CoverageType.JavaScript; + else if (contentProvider.contentType().isStyleSheet()) + coverageType = Coverage.CoverageType.CSS; + else + console.assert(false, `Unexpected resource type ${contentProvider.contentType().name} for ${url}`); + + var coverageInfo = {url: url, ranges: ranges, type: coverageType}; + var content = await contentProvider.requestContent(); if (!content) return coverageInfo; @@ -362,4 +367,4 @@ Coverage.CoverageView.RecordActionDelegate = class { return true; } -}; \ No newline at end of file +}; diff --git a/front_end/elements/StylesSidebarPane.js b/front_end/elements/StylesSidebarPane.js index b4ffe1dc32..0eb0d410bf 100644 --- a/front_end/elements/StylesSidebarPane.js +++ b/front_end/elements/StylesSidebarPane.js @@ -27,9 +27,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - * @unrestricted - */ Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane { constructor() { super(); @@ -41,6 +38,17 @@ Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane { this._sectionsContainer = this.element.createChild('div'); this._swatchPopoverHelper = new InlineEditor.SwatchPopoverHelper(); this._linkifier = new Components.Linkifier(Elements.StylesSidebarPane._maxLinkLength, /* useLinkDecorator */ true); + /** @type {?Elements.StylePropertyHighlighter} */ + this._decorator = null; + this._userOperation = false; + this._isEditingStyle = false; + /** @type {?RegExp} */ + this._filterRegex = null; + + /** @type {?Elements.StylePropertyTreeElement} */ + this._mouseDownTreeElement = null; + this._mouseDownTreeElementIsName = false; + this._mouseDownTreeElementIsValue = false; this.element.classList.add('styles-pane'); @@ -349,7 +357,7 @@ Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane { this._nodeStylesUpdatedForTest(node, true); if (this._decorator) { this._decorator.perform(); - delete this._decorator; + this._decorator = null; } } @@ -395,7 +403,7 @@ Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane { * @this {Elements.StylesSidebarPane} */ function onViaInspectorStyleSheet(styleSheetHeader) { - delete this._userOperation; + this._userOperation = false; this._createNewRuleInStyleSheet(styleSheetHeader); } } @@ -489,9 +497,6 @@ Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane { Elements.StylesSidebarPane._maxLinkLength = 30; -/** - * @unrestricted - */ Elements.SectionBlock = class { /** * @param {?Element} titleElement @@ -552,10 +557,6 @@ Elements.SectionBlock = class { } }; - -/** - * @unrestricted - */ Elements.StylePropertiesSection = class { /** * @param {!Elements.StylesSidebarPane} parentPane @@ -567,6 +568,11 @@ Elements.StylePropertiesSection = class { this._style = style; this._matchedStyles = matchedStyles; this.editable = !!(style.styleSheetId && style.range); + /** @type {?number} */ + this._hoverTimer = null; + /** @type {?function(!Elements.StylePropertiesSection)} */ + this._afterUpdate = null; + this._willCauseCancelEditing = false; var rule = style.parentRule; this.element = createElementWithClass('div', 'styles-section matched-styles monospace'); @@ -1057,7 +1063,7 @@ Elements.StylePropertiesSection = class { afterUpdate() { if (this._afterUpdate) { this._afterUpdate(this); - delete this._afterUpdate; + this._afterUpdate = null; this._afterUpdateFinishedForTest(); } } @@ -1190,7 +1196,7 @@ Elements.StylePropertiesSection = class { */ _checkWillCancelEditing() { var willCauseCancelEditing = this._willCauseCancelEditing; - delete this._willCauseCancelEditing; + this._willCauseCancelEditing = false; return willCauseCancelEditing; } @@ -1347,7 +1353,7 @@ Elements.StylePropertiesSection = class { this._matchedStyles.resetActiveProperties(); this._parentPane._refreshUpdate(this); } - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; this._editingMediaTextCommittedForTest(); } @@ -1474,7 +1480,7 @@ Elements.StylePropertiesSection = class { * @this {Elements.StylePropertiesSection} */ function headerTextCommitted() { - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; this._moveEditorFromSelector(moveDirection); this._editingSelectorCommittedForTest(); } @@ -1543,10 +1549,6 @@ Elements.StylePropertiesSection = class { } }; - -/** - * @unrestricted - */ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSection { /** * @param {!Elements.StylesSidebarPane} stylesPane @@ -1560,6 +1562,7 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec var cssModel = /** @type {!SDK.CSSModel} */ (stylesPane.cssModel()); var rule = SDK.CSSStyleRule.createDummyRule(cssModel, defaultSelectorText); super(stylesPane, matchedStyles, rule.style); + this._normal = false; this._ruleLocation = ruleLocation; this._styleSheetId = styleSheetId; this._selectorRefElement.removeChildren(); @@ -1611,7 +1614,7 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec /** * @param {?SDK.CSSStyleRule} newRule * @return {!Promise} - * @this {Elements.StylePropertiesSection} + * @this {Elements.BlankStylePropertiesSection} */ function onRuleAdded(newRule) { if (!newRule) { @@ -1625,7 +1628,7 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec /** * @param {!SDK.CSSStyleRule} newRule - * @this {Elements.StylePropertiesSection} + * @this {Elements.BlankStylePropertiesSection} */ function onAddedToCascade(newRule) { var doesSelectorAffectSelectedNode = this._matchedStyles.matchingSelectors(newRule).length > 0; @@ -1638,7 +1641,7 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec if (this.element.parentElement) // Might have been detached already. this._moveEditorFromSelector(moveDirection); - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; this._editingSelectorEnded(); this._markSelectorMatches(); @@ -1658,7 +1661,7 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec * @override */ editingSelectorCancelled() { - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; if (!this.isBlank) { super.editingSelectorCancelled(); return; @@ -1679,9 +1682,6 @@ Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSec } }; -/** - * @unrestricted - */ Elements.KeyframePropertiesSection = class extends Elements.StylePropertiesSection { /** * @param {!Elements.StylesSidebarPane} stylesPane @@ -1763,9 +1763,6 @@ Elements.KeyframePropertiesSection = class extends Elements.StylePropertiesSecti } }; -/** - * @unrestricted - */ Elements.StylePropertyTreeElement = class extends UI.TreeElement { /** * @param {!Elements.StylesSidebarPane} stylesPane @@ -1787,6 +1784,14 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { this._parentPane = stylesPane; this.isShorthand = isShorthand; this._applyStyleThrottler = new Common.Throttler(0); + this._newProperty = false; + this._expandedDueToFilter = false; + this.valueElement = null; + this.nameElement = null; + this._expandElement = null; + this._originalPropertyText = ''; + this._prompt = null; + this._propertyHasBeenEditedIncrementally = false; } /** @@ -2038,7 +2043,7 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { * @this {Elements.StylePropertyTreeElement} */ function callback(success) { - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; if (!success) return; @@ -2105,9 +2110,9 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { _resetMouseDownElement() { if (this._parentPane) { - delete this._parentPane._mouseDownTreeElement; - delete this._parentPane._mouseDownTreeElementIsName; - delete this._parentPane._mouseDownTreeElementIsValue; + this._parentPane._mouseDownTreeElement = null; + this._parentPane._mouseDownTreeElementIsName = false; + this._parentPane._mouseDownTreeElementIsValue = false; } } @@ -2495,7 +2500,7 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { _revertStyleUponEditingCanceled() { if (this._propertyHasBeenEditedIncrementally) { this.applyStyleText(this._originalPropertyText, false); - delete this._originalPropertyText; + this._originalPropertyText = ''; } else if (this._newProperty) { this.treeOutline.removeChild(this); } else { @@ -2648,7 +2653,7 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { // BUG 53242. This cannot go into editingEnded(), as it should always happen first for any editing outcome. if (this._prompt) { this._prompt.detach(); - delete this._prompt; + this._prompt = null; } } @@ -2693,7 +2698,7 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { * @this {Elements.StylePropertyTreeElement} */ function callback(success) { - delete this._parentPane._userOperation; + this._parentPane._userOperation = false; if (!success) { if (majorChange) { @@ -2744,9 +2749,6 @@ Elements.StylePropertyTreeElement = class extends UI.TreeElement { /** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */ Elements.StylePropertyTreeElement.Context; -/** - * @unrestricted - */ Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt { /** * @param {!Array} cssCompletions @@ -2862,7 +2864,7 @@ Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt { } // Handle numeric value increment/decrement only at this point. - if (!this._isEditingName && + if (!this._isEditingName && this._treeElement.valueElement && UI.handleElementValueModifications( event, this._treeElement.valueElement, finishHandler.bind(this), this._isValueSuggestion.bind(this), customNumberHandler.bind(this))) @@ -2931,9 +2933,6 @@ Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt { } }; -/** - * @unrestricted - */ Elements.StylesSidebarPropertyRenderer = class { /** * @param {?SDK.CSSRule} rule @@ -2946,6 +2945,12 @@ Elements.StylesSidebarPropertyRenderer = class { this._node = node; this._propertyName = name; this._propertyValue = value; + /** @type {?function(string):!Node} */ + this._colorHandler = null; + /** @type {?function(string):!Node} */ + this._bezierHandler = null; + /** @type {?function(string, string):!Node} */ + this._shadowHandler = null; } /** @@ -3042,7 +3047,6 @@ Elements.StylesSidebarPropertyRenderer = class { /** * @implements {UI.ToolbarItem.Provider} - * @unrestricted */ Elements.StylesSidebarPane.ButtonProvider = class { constructor() { diff --git a/front_end/help/Help.js b/front_end/help/Help.js index 35838b6fa7..7d3b6cb598 100644 --- a/front_end/help/Help.js +++ b/front_end/help/Help.js @@ -81,7 +81,10 @@ Help._releaseNoteViewId = 'release-note'; /** @typedef {!{src: string}} */ Help.ReleaseNoteImage; -/** @typedef {!{text: string, link: string, featured: (boolean | undefined)}} */ +/** @typedef {!{text: string, link: (string | undefined)}} */ +Help.ReleaseNoteHighlightContent; + +/** @typedef {!{contents: !Array, featured: (boolean | undefined)}} */ Help.ReleaseNoteHighlight; /** diff --git a/front_end/help/ReleaseNote.js b/front_end/help/ReleaseNote.js index 3af1db26c8..5402ec3601 100644 --- a/front_end/help/ReleaseNote.js +++ b/front_end/help/ReleaseNote.js @@ -16,30 +16,39 @@ Help.ReleaseNoteView = class extends UI.VBox { */ _createReleaseNoteElement(releaseNote) { var container = createElementWithClass('div', 'release-note-container'); - var textContainer = container.createChild('div', 'release-note-text-container'); - textContainer.createChild('div', 'release-note-header').textContent = - Common.UIString('New in DevTools %d', releaseNote.version); + var contentContainer = container.createChild('div', 'release-note-content-container'); + var textContainer = contentContainer.createChild('div', 'release-note-text-container'); + textContainer.createChild('div', 'release-note-update-text') + .createTextChild(Common.UIString('Chrome has been updated to version %d. ', releaseNote.version)); + textContainer.createChild('div').createTextChild(Common.UIString(`Here's what's new in DevTools:`)); var highlightContainer = textContainer.createChild('ul', 'release-note-highlight-container'); for (var highlight of releaseNote.highlights) { - var className = highlight.featured ? 'release-note-featured-link' : 'release-note-link'; - var highlightLink = UI.createExternalLink(highlight.link, highlight.text, className); - highlightContainer.createChild('li').appendChild(highlightLink); + var listItem = highlightContainer.createChild('li'); + for (var content of highlight.contents) { + if (content.link) { + var className = highlight.featured ? 'release-note-featured-link' : 'release-note-link'; + listItem.appendChild(UI.createExternalLink(content.link, content.text + ' ', className)); + } else { + listItem.createTextChild(content.text + ' '); + } + } } - var viewMoreButton = UI.createTextButton(Common.UIString('And more...'), event => { + var actionContainer = container.createChild('div', 'release-note-action-container'); + var viewMoreButton = UI.createTextButton(Common.UIString('Learn more'), event => { event.consume(true); InspectorFrontendHost.openInNewTab(releaseNote.link); }); - textContainer.appendChild(viewMoreButton); + actionContainer.appendChild(viewMoreButton); - var closeButton = UI.createTextButton(Common.UIString('Dismiss'), event => { + var closeButton = UI.createTextButton(Common.UIString('Close'), event => { event.consume(true); UI.inspectorView.closeDrawerTab(Help._releaseNoteViewId, true); }, 'close-release-note'); - textContainer.appendChild(closeButton); + actionContainer.appendChild(closeButton); - var imageLink = UI.createExternalLink(releaseNote.link, ' ', 'release-note-image-container'); - container.appendChild(imageLink); + var imageLink = UI.createExternalLink(releaseNote.link, ' '); + contentContainer.appendChild(imageLink); var image = imageLink.createChild('img', 'release-note-image'); image.src = releaseNote.image.src; image.addEventListener('mouseover', e => container.classList.add('image-hover')); diff --git a/front_end/help/ReleaseNoteText.js b/front_end/help/ReleaseNoteText.js index da5ce490df..28bc9d1e9f 100644 --- a/front_end/help/ReleaseNoteText.js +++ b/front_end/help/ReleaseNoteText.js @@ -12,22 +12,57 @@ Help.releaseNoteText = [ version: 58, highlights: [ { - text: 'Review CSS changes in the new Changes drawer', - link: 'https://developers.google.com/web/updates/2016/06/devtools-digest', + contents: [ + { + text: 'Improved', + }, + { + text: 'Performance and Memory panels', + link: 'https://developers.google.com/web/tools/chrome-devtools/', + } + ], featured: true, }, { - text: 'Contextual icons in Console', - link: 'https://developers.google.com/web/updates/2016/06/devtools-digest', + contents: [ + { + text: 'Edit cookies directly', + link: 'https://developers.google.com/web/tools/chrome-devtools/', + }, + { + text: 'from the Application panel', + }, + ], }, { - text: 'Release notes for DevTools', - link: 'https://developers.google.com/web/updates/2016/06/devtools-digest', + contents: [ + { + text: 'Better', + }, + { + text: 'filtering & settings for Console', + link: 'https://developers.google.com/web/tools/chrome-devtools/', + }, + ], + }, + { + contents: [ + { + text: 'Debugger', + }, + { + text: 'catches out-of-memory', + link: 'https://developers.google.com/web/tools/chrome-devtools/', + }, + { + text: 'errors', + }, + ], }, ], - link: 'https://developers.google.com/web/updates/2016/06/devtools-digest', + link: 'https://developers.google.com/web/tools/chrome-devtools/', image: { - src: 'https://developers.google.com/web/updates/images/2016/08/colorpicker.jpg', + src: 'https://developers.google.com/web/tools/chrome-devtools/images/panels/performance.png', }, }, ]; diff --git a/front_end/help/releaseNote.css b/front_end/help/releaseNote.css index 06b1a7ed42..7dbb2309fb 100644 --- a/front_end/help/releaseNote.css +++ b/front_end/help/releaseNote.css @@ -4,22 +4,37 @@ * found in the LICENSE file. */ -.release-note-header { - font-size: 15px; +.release-note-container { + display: flex; + flex-direction: column; + overflow: hidden; } -.release-note-container { - margin: 12px; +.release-note-update-text { + font-weight: bold; +} + +.release-note-content-container { display: flex; flex-direction: row; - flex-wrap: wrap-reverse; - align-content: flex-start; + overflow-x: hidden; + overflow-y: auto; + padding: 12px 12px 0 12px; +} + +.release-note-text-container { + min-width: 220px; + max-width: 300px; +} + +.release-note-action-container { + padding: 12px; + min-height: 48px; } .release-note-highlight-container { - margin: 12px 0 12px -25px; line-height: 1.5; - width: 100%; + -webkit-padding-start: 16px; } .release-note-link, .release-note-featured-link { @@ -33,19 +48,10 @@ text-decoration: underline; } -.release-note-image-container { - /* Bottom padding is used when DevTools width is small and the image wraps */ - padding: 0 0 12px 0; -} - .release-note-image { width: 200px; } -.release-note-text-container { - max-width: 300px; -} - .close-release-note { margin-left: 4px; } diff --git a/front_end/main/Main.js b/front_end/main/Main.js index 574e6df322..f638ac8bd5 100644 --- a/front_end/main/Main.js +++ b/front_end/main/Main.js @@ -115,7 +115,7 @@ Main.Main = class { Runtime.experiments.register('sourceDiff', 'Source diff'); Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true); Runtime.experiments.register('timelineInvalidationTracking', 'Timeline invalidation tracking', true); - Runtime.experiments.register('timelineMultipleMainViews', 'Timeline with multiple main views'); + Runtime.experiments.register('timelineMultipleMainViews', 'Tabbed views on Performance panel'); Runtime.experiments.register('timelineTracingJSProfile', 'Timeline tracing based JS profiler', true); Runtime.experiments.register('timelineV8RuntimeCallStats', 'V8 Runtime Call Stats on Timeline', true); Runtime.experiments.register('timelinePerFrameTrack', 'Show track per frame on Timeline', true); @@ -135,7 +135,7 @@ Main.Main = class { Runtime.experiments.enableForTest('releaseNote'); } - Runtime.experiments.setDefaultExperiments(['persistenceValidation', 'timelineMultipleMainViews']); + Runtime.experiments.setDefaultExperiments(['persistenceValidation']); } /** @@ -181,7 +181,7 @@ Main.Main = class { Common.formatterWorkerPool = new Common.FormatterWorkerPool(); Workspace.fileSystemMapping = new Workspace.FileSystemMapping(Workspace.isolatedFileSystemManager); - Bindings.networkProjectManager = new Bindings.NetworkProjectManager(SDK.targetManager, Workspace.workspace); + Main.networkProjectManager = new Bindings.NetworkProjectManager(SDK.targetManager, Workspace.workspace); Bindings.presentationConsoleMessageHelper = new Bindings.PresentationConsoleMessageHelper(Workspace.workspace); Bindings.cssWorkspaceBinding = new Bindings.CSSWorkspaceBinding(SDK.targetManager, Workspace.workspace); Bindings.debuggerWorkspaceBinding = new Bindings.DebuggerWorkspaceBinding(SDK.targetManager, Workspace.workspace); @@ -746,6 +746,10 @@ Main.Main.MainMenuItem = class { moreTools.appendItem(extension.title(), UI.viewManager.showView.bind(UI.viewManager, descriptor['id'])); } + var helpSubMenu = contextMenu.namedSubMenu('mainMenuHelp'); + helpSubMenu.appendAction('settings.documentation'); + if (Runtime.experiments.isEnabled('releaseNote')) + helpSubMenu.appendItem('Release Notes', () => InspectorFrontendHost.openInNewTab(Help.latestReleaseNote().link)); contextMenu.show(); } }; diff --git a/front_end/main/module.json b/front_end/main/module.json index 55d8931d57..1df75095e4 100644 --- a/front_end/main/module.json +++ b/front_end/main/module.json @@ -372,6 +372,13 @@ "subMenuId": "mainMenuMoreTools", "order": 80 }, + { + "type": "context-menu-item", + "location": "mainMenu/footer", + "title": "Help", + "subMenuId": "mainMenuHelp", + "order": 30 + }, { "type": "view", "location": "drawer-view", diff --git a/front_end/network/NetworkPanel.js b/front_end/network/NetworkPanel.js index f09dbedf04..5244640ffb 100644 --- a/front_end/network/NetworkPanel.js +++ b/front_end/network/NetworkPanel.js @@ -671,18 +671,14 @@ Network.NetworkPanel.FilmStripRecorder = class { * @param {!PerfUI.FilmStripView} filmStripView */ constructor(timeCalculator, filmStripView) { - /** @type {?SDK.Target} */ - this._target = null; + /** @type {?SDK.TracingManager} */ + this._tracingManager = null; + /** @type {?SDK.ResourceTreeModel} */ + this._resourceTreeModel = null; this._timeCalculator = timeCalculator; this._filmStripView = filmStripView; } - /** - * @override - */ - tracingStarted() { - } - /** * @override * @param {!Array.} events @@ -696,13 +692,15 @@ Network.NetworkPanel.FilmStripRecorder = class { * @override */ tracingComplete() { - if (!this._tracingModel || !this._target) + if (!this._tracingModel || !this._tracingManager) return; this._tracingModel.tracingComplete(); - SDK.targetManager.resumeReload(this._target); - this._target = null; + this._tracingManager = null; this._callback(new SDK.FilmStripModel(this._tracingModel, this._timeCalculator.minimumBoundary() * 1000)); delete this._callback; + if (this._resourceTreeModel) + this._resourceTreeModel.resumeReload(); + this._resourceTreeModel = null; } /** @@ -721,33 +719,36 @@ Network.NetworkPanel.FilmStripRecorder = class { startRecording() { this._filmStripView.reset(); this._filmStripView.setStatusText(Common.UIString('Recording frames...')); - if (this._target) + var tracingManagers = SDK.targetManager.models(SDK.TracingManager); + if (this._tracingManager || !tracingManagers.length) return; - this._target = SDK.targetManager.mainTarget(); + this._tracingManager = tracingManagers[0]; + this._resourceTreeModel = this._tracingManager.target().model(SDK.ResourceTreeModel); if (this._tracingModel) this._tracingModel.reset(); else this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage('tracing')); - this._target.tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', ''); + this._tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', ''); } /** * @return {boolean} */ isRecording() { - return !!this._target; + return !!this._tracingManager; } /** * @param {function(?SDK.FilmStripModel)} callback */ stopRecording(callback) { - if (!this._target) + if (!this._tracingManager) return; - this._target.tracingManager.stop(); - SDK.targetManager.suspendReload(this._target); + this._tracingManager.stop(); + if (this._resourceTreeModel) + this._resourceTreeModel.suspendReload(); this._callback = callback; this._filmStripView.setStatusText(Common.UIString('Fetching frames...')); } diff --git a/front_end/object_ui/RemoteObjectPreviewFormatter.js b/front_end/object_ui/RemoteObjectPreviewFormatter.js index cc2234f9a8..31a94d7e43 100644 --- a/front_end/object_ui/RemoteObjectPreviewFormatter.js +++ b/front_end/object_ui/RemoteObjectPreviewFormatter.js @@ -32,20 +32,18 @@ ObjectUI.RemoteObjectPreviewFormatter = class { } const isArrayOrTypedArray = preview.subtype === 'array' || preview.subtype === 'typedarray'; if (description) { - if (previewExperimentEnabled) { - // Hide the description for plain objects and plain arrays. - const plainObjectDescription = 'Object'; - const size = SDK.RemoteObject.arrayLength(preview) || SDK.RemoteObject.mapOrSetEntriesCount(preview); - var text = preview.subtype === 'typedarray' ? SDK.RemoteObject.arrayNameFromDescription(description) : ''; - if (isArrayOrTypedArray) - text += size > 1 ? ('(' + size + ')') : ''; - else - text = description === plainObjectDescription ? '' : description; - if (text.length > 0) - parentElement.createChild('span', 'object-description').textContent = text + ' '; - } else if (preview.subtype !== 'array') { - parentElement.createTextChildren(description, ' '); + var text; + if (isArrayOrTypedArray) { + var arrayLength = SDK.RemoteObject.arrayLength(preview); + var arrayLengthText = arrayLength > 1 ? ('(' + arrayLength + ')') : ''; + var arrayName = preview.subtype === 'typedarray' ? SDK.RemoteObject.arrayNameFromDescription(description) : ''; + text = arrayName + arrayLengthText; + } else { + var hideDescription = previewExperimentEnabled && description === 'Object'; + text = hideDescription ? '' : description; } + if (text.length > 0) + parentElement.createChild('span', 'object-description').textContent = text + ' '; } parentElement.createTextChild(isArrayOrTypedArray ? '[' : '{'); diff --git a/front_end/object_ui/objectValue.css b/front_end/object_ui/objectValue.css index cfd403e469..f1c6b53f7d 100644 --- a/front_end/object_ui/objectValue.css +++ b/front_end/object_ui/objectValue.css @@ -99,6 +99,6 @@ color: hsl(252, 100%, 75%); } -.object-description { +.object-properties-section .object-description { color: gray; } diff --git a/front_end/profiler/CPUProfileView.js b/front_end/profiler/CPUProfileView.js index 41c7f04aaa..2114d0a901 100644 --- a/front_end/profiler/CPUProfileView.js +++ b/front_end/profiler/CPUProfileView.js @@ -189,16 +189,16 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { } startRecordingProfile() { - var target = UI.context.flavor(SDK.Target); - if (this.profileBeingRecorded() || !target) + var cpuProfilerModel = UI.context.flavor(SDK.CPUProfilerModel); + if (this.profileBeingRecorded() || !cpuProfilerModel) return; - var profile = new Profiler.CPUProfileHeader(target, this); + var profile = new Profiler.CPUProfileHeader(cpuProfilerModel.target(), this); this.setProfileBeingRecorded(profile); SDK.targetManager.suspendAllTargets(); this.addProfile(profile); profile.updateStatus(Common.UIString('Recording\u2026')); this._recording = true; - target.cpuProfilerModel.startRecording(); + cpuProfilerModel.startRecording(); } stopRecordingProfile() { @@ -231,7 +231,8 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType { this.profileBeingRecorded() .target() - .cpuProfilerModel.stopRecording() + .model(SDK.CPUProfilerModel) + .stopRecording() .then(didStopProfiling.bind(this)) .then(SDK.targetManager.resumeAllTargets.bind(SDK.targetManager)) .then(fireEvent.bind(this)); diff --git a/front_end/quick_open/CommandMenu.js b/front_end/quick_open/CommandMenu.js index 7867bf0265..9f11fdd529 100644 --- a/front_end/quick_open/CommandMenu.js +++ b/front_end/quick_open/CommandMenu.js @@ -62,22 +62,11 @@ QuickOpen.CommandMenu = class { * @return {!QuickOpen.CommandMenu.Command} */ static createRevealPanelCommand(extension) { - var panelName = extension.descriptor()['name']; + var panelId = extension.descriptor()['id']; + var executeHandler = UI.viewManager.showView.bind(UI.viewManager, panelId); var tags = extension.descriptor()['tags'] || ''; return QuickOpen.CommandMenu.createCommand( - Common.UIString('Panel'), tags, Common.UIString('Show %s', extension.title()), '', executeHandler, - availableHandler); - - /** - * @return {boolean} - */ - function availableHandler() { - return true; - } - - function executeHandler() { - UI.viewManager.showView(panelName); - } + Common.UIString('Panel'), tags, Common.UIString('Show %s', extension.title()), '', executeHandler); } /** @@ -93,17 +82,12 @@ QuickOpen.CommandMenu = class { } _loadCommands() { - // Populate panels. - var panelExtensions = self.runtime.extensions(UI.Panel); - for (var extension of panelExtensions) - this._commands.push(QuickOpen.CommandMenu.createRevealPanelCommand(extension)); - - // Populate drawers. - var drawerExtensions = self.runtime.extensions('view'); - for (var extension of drawerExtensions) { - if (extension.descriptor()['location'] !== 'drawer-view') - continue; - this._commands.push(QuickOpen.CommandMenu.createRevealDrawerCommand(extension)); + var viewExtensions = self.runtime.extensions('view'); + for (var extension of viewExtensions) { + if (extension.descriptor()['location'] === 'panel') + this._commands.push(QuickOpen.CommandMenu.createRevealPanelCommand(extension)); + else if (extension.descriptor()['location'] === 'drawer-view') + this._commands.push(QuickOpen.CommandMenu.createRevealDrawerCommand(extension)); } // Populate whitelisted settings. diff --git a/front_end/resources/CookieItemsView.js b/front_end/resources/CookieItemsView.js index d9ea297024..1fc2505c14 100644 --- a/front_end/resources/CookieItemsView.js +++ b/front_end/resources/CookieItemsView.js @@ -73,6 +73,14 @@ Resources.CookieItemsView = class extends Resources.StorageItemsView { this._model.saveCookie(newCookie, callback); } + /** + * @param {!SDK.Cookie} cookie + * @param {function()} callback + */ + _deleteCookie(cookie, callback) { + this._model.deleteCookie(cookie, callback); + } + /** * @param {!Array.} allCookies */ @@ -83,7 +91,8 @@ Resources.CookieItemsView = class extends Resources.StorageItemsView { const parsedURL = this._cookieDomain.asParsedURL(); const domain = parsedURL ? parsedURL.host : ''; this._cookiesTable = new CookieTable.CookiesTable( - this._saveCookie.bind(this), this.refreshItems.bind(this), () => this.setCanDeleteSelected(true), domain); + this._saveCookie.bind(this), this.refreshItems.bind(this), () => this.setCanDeleteSelected(true), + this._deleteCookie.bind(this), domain); } var shownCookies = this.filter(allCookies, cookie => `${cookie.name()} ${cookie.value()} ${cookie.domain()}`); diff --git a/front_end/resources/DOMStorageItemsView.js b/front_end/resources/DOMStorageItemsView.js index 0675cb28ca..95f109e73a 100644 --- a/front_end/resources/DOMStorageItemsView.js +++ b/front_end/resources/DOMStorageItemsView.js @@ -66,10 +66,7 @@ Resources.DOMStorageItemsView = class extends Resources.StorageItemsView { this.refreshItems(); } - /** - * @param {!Common.Event} event - */ - _domStorageItemsCleared(event) { + _domStorageItemsCleared() { if (!this.isShowing() || !this._dataGrid) return; @@ -207,6 +204,8 @@ Resources.DOMStorageItemsView = class extends Resources.StorageItemsView { */ deleteAllItems() { this._domStorage.clear(); + // explicitly clear the view because the event won't be fired when it has no items + this._domStorageItemsCleared(); } _editingCallback(editingNode, columnIdentifier, oldText, newText) { diff --git a/front_end/resources/ServiceWorkersView.js b/front_end/resources/ServiceWorkersView.js index e6e989f514..cb02ad4d45 100644 --- a/front_end/resources/ServiceWorkersView.js +++ b/front_end/resources/ServiceWorkersView.js @@ -48,7 +48,6 @@ Resources.ServiceWorkersView = class extends UI.VBox { if (this._manager) return; this._manager = serviceWorkerManager; - this._subTargetsManager = serviceWorkerManager.target().subTargetsManager; this._securityOriginManager = SDK.SecurityOriginManager.fromTarget(serviceWorkerManager.target()); for (var registration of this._manager.registrations().values()) @@ -79,7 +78,6 @@ Resources.ServiceWorkersView = class extends UI.VBox { Common.EventTarget.removeEventListeners(this._eventListeners.get(serviceWorkerManager)); this._eventListeners.delete(serviceWorkerManager); this._manager = null; - this._subTargetsManager = null; this._securityOriginManager = null; } @@ -141,8 +139,8 @@ Resources.ServiceWorkersView = class extends UI.VBox { _updateRegistration(registration) { var section = this._sections.get(registration); if (!section) { - section = new Resources.ServiceWorkersView.Section( - this._manager, this._subTargetsManager, this._reportView.appendSection(''), registration); + section = + new Resources.ServiceWorkersView.Section(this._manager, this._reportView.appendSection(''), registration); this._sections.set(registration, section); } this._updateSectionVisibility(); @@ -174,13 +172,11 @@ Resources.ServiceWorkersView = class extends UI.VBox { Resources.ServiceWorkersView.Section = class { /** * @param {!SDK.ServiceWorkerManager} manager - * @param {!SDK.SubTargetsManager} subTargetsManager * @param {!UI.ReportView.Section} section * @param {!SDK.ServiceWorkerRegistration} registration */ - constructor(manager, subTargetsManager, section, registration) { + constructor(manager, section, registration) { this._manager = manager; - this._subTargetsManager = subTargetsManager; this._section = section; this._registration = registration; @@ -210,7 +206,7 @@ Resources.ServiceWorkersView.Section = class { this._errorsList.classList.add('service-worker-error-stack', 'monospace', 'hidden'); this._linkifier = new Components.Linkifier(); - /** @type {!Map} */ + /** @type {!Map} */ this._clientInfoCache = new Map(); for (var error of registration.errors) this._addError(error); @@ -287,9 +283,11 @@ Resources.ServiceWorkersView.Section = class { this._section.setFieldVisible(Common.UIString('Clients'), active.controlledClients.length); for (var client of active.controlledClients) { var clientLabelText = clientsList.createChild('div', 'service-worker-client'); - if (this._clientInfoCache.has(client)) - this._updateClientInfo(clientLabelText, /** @type {!SDK.TargetInfo} */ (this._clientInfoCache.get(client))); - this._subTargetsManager.getTargetInfo(client, this._onClientInfo.bind(this, clientLabelText)); + if (this._clientInfoCache.has(client)) { + this._updateClientInfo( + clientLabelText, /** @type {!Protocol.Target.TargetInfo} */ (this._clientInfoCache.get(client))); + } + this._manager.target().targetAgent().getTargetInfo(client, this._onClientInfo.bind(this, clientLabelText)); } } @@ -384,36 +382,37 @@ Resources.ServiceWorkersView.Section = class { /** * @param {!Element} element - * @param {?SDK.TargetInfo} targetInfo + * @param {?Protocol.Error} error + * @param {?Protocol.Target.TargetInfo} targetInfo */ - _onClientInfo(element, targetInfo) { - if (!targetInfo) + _onClientInfo(element, error, targetInfo) { + if (error || !targetInfo) return; - this._clientInfoCache.set(targetInfo.id, targetInfo); + this._clientInfoCache.set(targetInfo.targetId, targetInfo); this._updateClientInfo(element, targetInfo); } /** * @param {!Element} element - * @param {!SDK.TargetInfo} targetInfo + * @param {!Protocol.Target.TargetInfo} targetInfo */ _updateClientInfo(element, targetInfo) { - if (!targetInfo.canActivate) { - element.createTextChild(targetInfo.title); + if (targetInfo.type !== 'page' && targetInfo.type === 'iframe') { + element.createTextChild(Common.UIString('Worker: %s', targetInfo.url)); return; } element.removeChildren(); element.createTextChild(targetInfo.url); var focusLabel = element.createChild('label', 'link'); focusLabel.createTextChild('focus'); - focusLabel.addEventListener('click', this._activateTarget.bind(this, targetInfo.id), true); + focusLabel.addEventListener('click', this._activateTarget.bind(this, targetInfo.targetId), true); } /** * @param {string} targetId */ _activateTarget(targetId) { - this._subTargetsManager.activateTarget(targetId); + this._manager.target().targetAgent().activateTarget(targetId); } _startButtonClicked() { diff --git a/front_end/sdk/CPUProfilerModel.js b/front_end/sdk/CPUProfilerModel.js index 500369d22a..5f7554f37b 100644 --- a/front_end/sdk/CPUProfilerModel.js +++ b/front_end/sdk/CPUProfilerModel.js @@ -25,9 +25,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /** * @implements {Protocol.ProfilerDispatcher} - * @unrestricted */ SDK.CPUProfilerModel = class extends SDK.SDKModel { /** @@ -36,17 +36,10 @@ SDK.CPUProfilerModel = class extends SDK.SDKModel { constructor(target) { super(target); this._isRecording = false; + this._profilerAgent = target.profilerAgent(); target.registerProfilerDispatcher(this); - target.profilerAgent().enable(); - - this._configureCpuProfilerSamplingInterval(); - Common.moduleSetting('highResolutionCpuProfiling') - .addChangeListener(this._configureCpuProfilerSamplingInterval, this); - } - - _configureCpuProfilerSamplingInterval() { - var intervalUs = Common.moduleSetting('highResolutionCpuProfiling').get() ? 100 : 1000; - this.target().profilerAgent().setSamplingInterval(intervalUs); + this._profilerAgent.enable(); + this._debuggerModel = /** @type {!SDK.DebuggerModel} */ (target.model(SDK.DebuggerModel)); } /** @@ -80,10 +73,8 @@ SDK.CPUProfilerModel = class extends SDK.SDKModel { */ _dispatchProfileEvent(eventName, id, scriptLocation, title, cpuProfile) { // Make sure ProfilesPanel is initialized and CPUProfileType is created. - self.runtime.loadModulePromise('profiler').then(_ => { - var debuggerModel = - /** @type {!SDK.DebuggerModel} */ (SDK.DebuggerModel.fromTarget(this.target())); - var debuggerLocation = SDK.DebuggerModel.Location.fromPayload(debuggerModel, scriptLocation); + self.runtime.loadModulePromise('profiler').then(() => { + var debuggerLocation = SDK.DebuggerModel.Location.fromPayload(this._debuggerModel, scriptLocation); var globalId = this.target().id() + '.' + id; var data = /** @type {!SDK.CPUProfilerModel.EventData} */ ( {id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title}); @@ -100,8 +91,10 @@ SDK.CPUProfilerModel = class extends SDK.SDKModel { startRecording() { this._isRecording = true; - this.target().profilerAgent().start(); Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesCPUProfileTaken); + var intervalUs = Common.moduleSetting('highResolutionCpuProfiling').get() ? 100 : 1000; + this._profilerAgent.setSamplingInterval(intervalUs); + this._profilerAgent.start(); } /** @@ -117,20 +110,32 @@ SDK.CPUProfilerModel = class extends SDK.SDKModel { return !error && profile ? profile : null; } this._isRecording = false; - return this.target().profilerAgent().stop(extractProfile); + return this._profilerAgent.stop(extractProfile); } /** - * @override + * @return {!Promise} + */ + startPreciseCoverage() { + return this._profilerAgent.startPreciseCoverage(); + } + + /** + * @return {!Promise>} + */ + takePreciseCoverage() { + return this._profilerAgent.takePreciseCoverage((error, coverage) => error ? [] : coverage); + } + + /** + * @return {!Promise} */ - dispose() { - Common.moduleSetting('highResolutionCpuProfiling') - .removeChangeListener(this._configureCpuProfilerSamplingInterval, this); + stopPreciseCoverage() { + return this._profilerAgent.stopPreciseCoverage(); } }; -// TODO(dgozman): should be JS. -SDK.SDKModel.register(SDK.CPUProfilerModel, SDK.Target.Capability.None); +SDK.SDKModel.register(SDK.CPUProfilerModel, SDK.Target.Capability.JS); /** @enum {symbol} */ SDK.CPUProfilerModel.Events = { diff --git a/front_end/sdk/CSSStyleSheetHeader.js b/front_end/sdk/CSSStyleSheetHeader.js index 591c0678e2..b17c162181 100644 --- a/front_end/sdk/CSSStyleSheetHeader.js +++ b/front_end/sdk/CSSStyleSheetHeader.js @@ -33,8 +33,8 @@ SDK.CSSStyleSheetHeader = class { originalContentProvider() { if (!this._originalContentProvider) { var lazyContent = this._cssModel.originalStyleSheetText.bind(this._cssModel, this); - this._originalContentProvider = - new Common.StaticContentProvider(this.contentURL(), this.contentType(), lazyContent); + this._originalContentProvider = new Common.StaticContentProvider( + this.contentURL(), this.contentType(), /** @type {function():!Promise} */ (lazyContent)); } return this._originalContentProvider; } @@ -155,60 +155,3 @@ SDK.CSSStyleSheetHeader = class { return this.origin === 'inspector'; } }; - -/** - * @implements {Common.ContentProvider} - * @unrestricted - */ -SDK.CSSStyleSheetHeader.OriginalContentProvider = class { - /** - * @param {!SDK.CSSStyleSheetHeader} header - */ - constructor(header) { - this._header = header; - } - - /** - * @override - * @return {string} - */ - contentURL() { - return this._header.contentURL(); - } - - /** - * @override - * @return {!Common.ResourceType} - */ - contentType() { - return this._header.contentType(); - } - - /** - * @override - * @return {!Promise} - */ - requestContent() { - return /** @type {!Promise} */ (this._header.cssModel().originalStyleSheetText(this._header)); - } - - /** - * @override - * @param {string} query - * @param {boolean} caseSensitive - * @param {boolean} isRegex - * @param {function(!Array.)} callback - */ - searchInContent(query, caseSensitive, isRegex, callback) { - /** - * @param {?string} content - */ - function performSearch(content) { - var searchResults = - content ? Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex) : []; - callback(searchResults); - } - - this.requestContent().then(performSearch); - } -}; diff --git a/front_end/sdk/ResourceTreeModel.js b/front_end/sdk/ResourceTreeModel.js index b2b33846a7..a86b299d37 100644 --- a/front_end/sdk/ResourceTreeModel.js +++ b/front_end/sdk/ResourceTreeModel.js @@ -356,7 +356,7 @@ SDK.ResourceTreeModel = class extends SDK.SDKModel { reloadPage(bypassCache, scriptToEvaluateOnLoad) { // Only dispatch PageReloadRequested upon first reload request to simplify client logic. if (!this._pendingReloadOptions) - this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.PageReloadRequested); + this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.PageReloadRequested, this); if (this._reloadSuspensionCount) { this._pendingReloadOptions = [bypassCache, scriptToEvaluateOnLoad]; return; @@ -532,12 +532,10 @@ SDK.ResourceTreeFrame = class { /** * @param {!SDK.CSSStyleSheetHeader} header - * @return {!SDK.ResourceTreeFrame} + * @return {?SDK.ResourceTreeFrame} */ static fromStyleSheet(header) { - var frame = SDK.ResourceTreeFrame._fromObject(header); - console.assert(frame, 'Failed to find frame for header ', header.id); - return /** @type {!SDK.ResourceTreeFrame} */ (frame); + return SDK.ResourceTreeFrame._fromObject(header); } /** diff --git a/front_end/sdk/Script.js b/front_end/sdk/Script.js index c02c26fc0e..10413cfa00 100644 --- a/front_end/sdk/Script.js +++ b/front_end/sdk/Script.js @@ -71,6 +71,8 @@ SDK.Script = class { this._isLiveEdit = isLiveEdit; this.sourceMapURL = sourceMapURL; this.hasSourceURL = hasSourceURL; + this._originalContentProvider = null; + this._originalSource = null; } /** @@ -186,10 +188,24 @@ SDK.Script = class { } else { this._source = ''; } + if (this._originalSource === null) + this._originalSource = this._source; callback(this._source); } } + /** + * @return {!Common.ContentProvider} + */ + originalContentProvider() { + if (!this._originalContentProvider) { + var lazyContent = () => this.requestContent().then(() => this._originalSource); + this._originalContentProvider = + new Common.StaticContentProvider(this.contentURL(), this.contentType(), lazyContent); + } + return this._originalContentProvider; + } + /** * @override * @param {string} query @@ -261,8 +277,9 @@ SDK.Script = class { newSource = this._appendSourceURLCommentIfNeeded(newSource); if (this.scriptId) { - this.debuggerModel.target().debuggerAgent().setScriptSource( - this.scriptId, newSource, undefined, didEditScriptSource.bind(this)); + this.requestContent().then( + () => this.debuggerModel.target().debuggerAgent().setScriptSource( + this.scriptId, newSource, undefined, didEditScriptSource.bind(this))); } else { callback('Script failed to parse'); } diff --git a/front_end/sdk/ServiceWorkerManager.js b/front_end/sdk/ServiceWorkerManager.js index 120b85a2fe..81ea9a4ef7 100644 --- a/front_end/sdk/ServiceWorkerManager.js +++ b/front_end/sdk/ServiceWorkerManager.js @@ -47,8 +47,7 @@ SDK.ServiceWorkerManager = class extends SDK.SDKModel { if (this._forceUpdateSetting.get()) this._forceUpdateSettingChanged(); this._forceUpdateSetting.addChangeListener(this._forceUpdateSettingChanged, this); - new SDK.ServiceWorkerContextNamer( - target, this, /** @type {!SDK.SubTargetsManager} */ (SDK.SubTargetsManager.fromTarget(target))); + new SDK.ServiceWorkerContextNamer(target, this); } enable() { @@ -532,12 +531,10 @@ SDK.ServiceWorkerContextNamer = class { /** * @param {!SDK.Target} target * @param {!SDK.ServiceWorkerManager} serviceWorkerManager - * @param {!SDK.SubTargetsManager} subTargetsManager */ - constructor(target, serviceWorkerManager, subTargetsManager) { + constructor(target, serviceWorkerManager) { this._target = target; this._serviceWorkerManager = serviceWorkerManager; - this._subTargetsManager = subTargetsManager; /** @type {!Map} */ this._versionByTargetId = new Map(); serviceWorkerManager.addEventListener( diff --git a/front_end/sdk/SubTargetsManager.js b/front_end/sdk/SubTargetsManager.js deleted file mode 100644 index ef20196486..0000000000 --- a/front_end/sdk/SubTargetsManager.js +++ /dev/null @@ -1,345 +0,0 @@ -// 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. -/** - * @unrestricted - */ -SDK.SubTargetsManager = class extends SDK.SDKModel { - /** - * @param {!SDK.Target} target - */ - constructor(target) { - super(target); - target.registerTargetDispatcher(new SDK.SubTargetsDispatcher(this)); - this._lastAnonymousTargetId = 0; - this._agent = target.targetAgent(); - - /** @type {!Map} */ - this._attachedTargets = new Map(); - /** @type {!Map} */ - this._connections = new Map(); - - /** @type {!Set} */ - this._nodeTargetIds = new Set(); - - this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnStart */); - if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) - this._agent.setAttachToFrames(true); - - if (!target.parentTarget()) { - var defaultLocations = [{host: 'localhost', port: 9229}]; - this._agent.setRemoteLocations(defaultLocations); - this._agent.setDiscoverTargets(true); - } - SDK.targetManager.addEventListener(SDK.TargetManager.Events.MainFrameNavigated, this._mainFrameNavigated, this); - } - - /** - * @param {!SDK.Target} target - * @return {?SDK.SubTargetsManager} - */ - static fromTarget(target) { - return target.model(SDK.SubTargetsManager); - } - - /** - * @return {number} - */ - availableNodeTargetsCount() { - return this._nodeTargetIds.size; - } - - /** - * @override - * @return {!Promise} - */ - suspendModel() { - var fulfill; - var promise = new Promise(f => fulfill = f); - this._agent.setAutoAttach(true /* autoAttach */, false /* waitForDebuggerOnStart */, fulfill); - return promise; - } - - /** - * @override - * @return {!Promise} - */ - resumeModel() { - var fulfill; - var promise = new Promise(f => fulfill = f); - this._agent.setAutoAttach(true /* autoAttach */, true /* waitForDebuggerOnStart */, fulfill); - return promise; - } - - /** - * @override - */ - dispose() { - for (var attachedTargetId of this._attachedTargets.keys()) - this._detachedFromTarget(attachedTargetId); - } - - /** - * @param {!Protocol.Target.TargetID} targetId - */ - activateTarget(targetId) { - this._agent.activateTarget(targetId); - } - - /** - * @param {!Protocol.Target.TargetID} targetId - * @param {function(?SDK.TargetInfo)=} callback - */ - getTargetInfo(targetId, callback) { - /** - * @param {?Protocol.Error} error - * @param {?Protocol.Target.TargetInfo} targetInfo - */ - function innerCallback(error, targetInfo) { - if (error) { - console.error(error); - callback(null); - return; - } - if (targetInfo) - callback(new SDK.TargetInfo(targetInfo)); - else - callback(null); - } - this._agent.getTargetInfo(targetId, innerCallback); - } - - /** - * @param {string} type - * @return {number} - */ - _capabilitiesForType(type) { - if (type === 'worker') - return SDK.Target.Capability.JS | SDK.Target.Capability.Log; - 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; - } - if (type === 'node') - return SDK.Target.Capability.JS; - return 0; - } - - /** - * @param {!SDK.TargetInfo} targetInfo - * @param {boolean} waitingForDebugger - */ - _attachedToTarget(targetInfo, waitingForDebugger) { - var targetName = ''; - if (targetInfo.type === 'node') { - targetName = targetInfo.title; - } else if (targetInfo.type !== 'iframe') { - var parsedURL = targetInfo.url.asParsedURL(); - targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + (++this._lastAnonymousTargetId); - } - var target = SDK.targetManager.createTarget( - targetInfo.id, targetName, this._capabilitiesForType(targetInfo.type), - this._createConnection.bind(this, targetInfo.id), this.target()); - target[SDK.SubTargetsManager._InfoSymbol] = targetInfo; - this._attachedTargets.set(targetInfo.id, target); - - // Only pause new worker if debugging SW - we are going through the pause on start checkbox. - var mainIsServiceWorker = - !this.target().parentTarget() && this.target().hasTargetCapability() && !this.target().hasBrowserCapability(); - if (mainIsServiceWorker && waitingForDebugger) - target.debuggerAgent().pause(); - target.runtimeAgent().runIfWaitingForDebugger(); - } - - /** - * @param {string} targetId - * @param {!Protocol.InspectorBackend.Connection.Params} params - * @return {!Protocol.InspectorBackend.Connection} - */ - _createConnection(targetId, params) { - var connection = new SDK.SubTargetConnection(this._agent, targetId, params); - this._connections.set(targetId, connection); - return connection; - } - - /** - * @param {string} targetId - */ - _detachedFromTarget(targetId) { - this._attachedTargets.delete(targetId); - var connection = this._connections.get(targetId); - connection._onDisconnect.call(null, 'target terminated'); - this._connections.delete(targetId); - } - - /** - * @param {string} targetId - * @param {string} message - */ - _receivedMessageFromTarget(targetId, message) { - var connection = this._connections.get(targetId); - if (connection) - connection._onMessage.call(null, message); - } - - /** - * @param {!SDK.TargetInfo} targetInfo - */ - _targetCreated(targetInfo) { - if (targetInfo.type !== 'node') - return; - if (Runtime.queryParam('nodeFrontend')) { - this._agent.attachToTarget(targetInfo.id); - } else { - this._nodeTargetIds.add(targetInfo.id); - this.dispatchEventToListeners(SDK.SubTargetsManager.Events.AvailableNodeTargetsChanged); - } - } - - /** - * @param {string} targetId - */ - _targetDestroyed(targetId) { - if (Runtime.queryParam('nodeFrontend') || !this._nodeTargetIds.has(targetId)) - return; - this._nodeTargetIds.delete(targetId); - this.dispatchEventToListeners(SDK.SubTargetsManager.Events.AvailableNodeTargetsChanged); - } - - /** - * @param {!Common.Event} event - */ - _mainFrameNavigated(event) { - if (event.data.target() !== this.target()) - return; - - var idsToDetach = []; - for (var targetId of this._attachedTargets.keys()) { - var target = this._attachedTargets.get(targetId); - if (target[SDK.SubTargetsManager._InfoSymbol].type === 'worker') - idsToDetach.push(targetId); - } - idsToDetach.forEach(id => this._detachedFromTarget(id)); - } -}; - -SDK.SDKModel.register(SDK.SubTargetsManager, SDK.Target.Capability.Target); - -/** @enum {symbol} */ -SDK.SubTargetsManager.Events = { - AvailableNodeTargetsChanged: Symbol('AvailableNodeTargetsChanged'), -}; - -SDK.SubTargetsManager._InfoSymbol = Symbol('SubTargetInfo'); - -/** - * @implements {Protocol.TargetDispatcher} - * @unrestricted - */ -SDK.SubTargetsDispatcher = class { - /** - * @param {!SDK.SubTargetsManager} manager - */ - constructor(manager) { - this._manager = manager; - } - - /** - * @override - * @param {!Protocol.Target.TargetInfo} targetInfo - */ - targetCreated(targetInfo) { - this._manager._targetCreated(new SDK.TargetInfo(targetInfo)); - } - - /** - * @override - * @param {string} targetId - */ - targetDestroyed(targetId) { - this._manager._targetDestroyed(targetId); - } - - /** - * @override - * @param {!Protocol.Target.TargetInfo} targetInfo - * @param {boolean} waitingForDebugger - */ - attachedToTarget(targetInfo, waitingForDebugger) { - this._manager._attachedToTarget(new SDK.TargetInfo(targetInfo), waitingForDebugger); - } - - /** - * @override - * @param {string} targetId - */ - detachedFromTarget(targetId) { - this._manager._detachedFromTarget(targetId); - } - - /** - * @override - * @param {string} targetId - * @param {string} message - */ - receivedMessageFromTarget(targetId, message) { - this._manager._receivedMessageFromTarget(targetId, message); - } -}; - -/** - * @implements {Protocol.InspectorBackend.Connection} - * @unrestricted - */ -SDK.SubTargetConnection = class { - /** - * @param {!Protocol.TargetAgent} agent - * @param {string} targetId - * @param {!Protocol.InspectorBackend.Connection.Params} params - */ - constructor(agent, targetId, params) { - this._agent = agent; - this._targetId = targetId; - this._onMessage = params.onMessage; - this._onDisconnect = params.onDisconnect; - } - - /** - * @override - * @param {string} message - */ - sendMessage(message) { - this._agent.sendMessageToTarget(this._targetId, message); - } - - /** - * @override - * @return {!Promise} - */ - disconnect() { - throw new Error('Not implemented'); - } -}; - -/** - * @unrestricted - */ -SDK.TargetInfo = class { - /** - * @param {!Protocol.Target.TargetInfo} payload - */ - constructor(payload) { - this.id = payload.targetId; - this.url = payload.url; - this.type = payload.type; - this.canActivate = this.type === 'page' || this.type === 'iframe'; - if (this.type === 'node') - this.title = Common.UIString('Node: %s', this.url); - else if (this.type === 'page' || this.type === 'iframe') - this.title = payload.title; - else - this.title = Common.UIString('Worker: %s', this.url); - } -}; diff --git a/front_end/sdk/Target.js b/front_end/sdk/Target.js index 222c5b6aee..daf25f7a3d 100644 --- a/front_end/sdk/Target.js +++ b/front_end/sdk/Target.js @@ -186,17 +186,18 @@ SDK.Target = class extends Protocol.TargetBase { * @enum {number} */ SDK.Target.Capability = { - Browser: 1, - DOM: 2, - JS: 4, - Log: 8, - Network: 16, - Target: 32, - ScreenCapture: 64, + Browser: 1 << 0, + DOM: 1 << 1, + JS: 1 << 2, + Log: 1 << 3, + Network: 1 << 4, + Target: 1 << 5, + ScreenCapture: 1 << 6, + Tracing: 1 << 7, None: 0, - AllForTests: 127 + AllForTests: (1 << 8) - 1 }; /** diff --git a/front_end/sdk/TargetManager.js b/front_end/sdk/TargetManager.js index d894ed023a..52f19551b7 100644 --- a/front_end/sdk/TargetManager.js +++ b/front_end/sdk/TargetManager.js @@ -4,9 +4,6 @@ * found in the LICENSE file. */ -/** - * @unrestricted - */ SDK.TargetManager = class extends Common.Object { constructor() { super(); @@ -22,6 +19,15 @@ SDK.TargetManager = class extends Common.Object { /** @type {!Set} */ this._pendingTargets = new Set(); this._isSuspended = false; + this._lastAnonymousTargetId = 0; + /** @type {!Map} */ + this._childTargetManagers = new Map(); + /** @type {!Set} */ + this._nodeTargetIds = new Set(); + /** @type {!Protocol.InspectorBackend.Connection} */ + this._mainConnection; + /** @type {function()} */ + this._webSocketConnectionLostCallback; } suspendAllTargets() { @@ -30,8 +36,11 @@ SDK.TargetManager = class extends Common.Object { this._isSuspended = true; this.dispatchEventToListeners(SDK.TargetManager.Events.SuspendStateChanged); - for (var i = 0; i < this._targets.length; ++i) { - for (var model of this._targets[i].models().values()) + for (var target of this._targets) { + var childTargetManager = this._childTargetManagers.get(target); + if (childTargetManager) + childTargetManager.suspend(); + for (var model of target.models().values()) model.suspendModel(); } } @@ -46,8 +55,11 @@ SDK.TargetManager = class extends Common.Object { this.dispatchEventToListeners(SDK.TargetManager.Events.SuspendStateChanged); var promises = []; - for (var i = 0; i < this._targets.length; ++i) { - for (var model of this._targets[i].models().values()) + for (var target of this._targets) { + var childTargetManager = this._childTargetManagers.get(target); + if (childTargetManager) + promises.push(childTargetManager.resume()); + for (var model of target.models().values()) promises.push(model.resumeModel()); } return Promise.all(promises); @@ -87,14 +99,6 @@ SDK.TargetManager = class extends Common.Object { return this._targets[0] ? this._targets[0].inspectedURL() : ''; } - /** - * @param {!SDK.TargetManager.Events} eventName - * @param {!Common.Event} event - */ - _redispatchEvent(eventName, event) { - this.dispatchEventToListeners(eventName, event.data); - } - /** * @param {boolean=} bypassCache * @param {string=} injectedScript @@ -253,16 +257,12 @@ SDK.TargetManager = class extends Common.Object { target.model(SDK.DebuggerModel); target.model(SDK.DOMModel); target.model(SDK.CSSModel); - - /** @type {?SDK.SubTargetsManager} */ - target.subTargetsManager = target.model(SDK.SubTargetsManager); - /** @type {!SDK.CPUProfilerModel} */ - target.cpuProfilerModel = /** @type {!SDK.CPUProfilerModel} */ (target.model(SDK.CPUProfilerModel)); - - target.tracingManager = new SDK.TracingManager(target); - + target.model(SDK.CPUProfilerModel); target.model(SDK.ServiceWorkerManager); + if (target.hasTargetCapability()) + this._childTargetManagers.set(target, new SDK.ChildTargetManager(this, target, resourceTreeModel)); + // Force creation of models which have observers. for (var modelClass of this._modelObservers.keys()) target.model(modelClass); @@ -270,26 +270,23 @@ SDK.TargetManager = class extends Common.Object { this._targets.push(target); - /** - * @param {!SDK.ResourceTreeModel.Events} sourceEvent - * @param {!SDK.TargetManager.Events} targetEvent - * @return {!Common.EventTarget.EventDescriptor} - * @this {SDK.TargetManager} - */ - function setupRedispatch(sourceEvent, targetEvent) { - return resourceTreeModel.addEventListener(sourceEvent, this._redispatchEvent.bind(this, targetEvent)); - } - - if (this._targets.length === 1 && resourceTreeModel) { + if (resourceTreeModel && !target.parentTarget()) { resourceTreeModel[SDK.TargetManager._listenersSymbol] = [ - setupRedispatch.call( - this, SDK.ResourceTreeModel.Events.MainFrameNavigated, SDK.TargetManager.Events.MainFrameNavigated), - setupRedispatch.call(this, SDK.ResourceTreeModel.Events.Load, SDK.TargetManager.Events.Load), - setupRedispatch.call( - this, SDK.ResourceTreeModel.Events.PageReloadRequested, SDK.TargetManager.Events.PageReloadRequested), - setupRedispatch.call(this, SDK.ResourceTreeModel.Events.WillReloadPage, SDK.TargetManager.Events.WillReloadPage) + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.MainFrameNavigated, + event => this.dispatchEventToListeners(SDK.TargetManager.Events.MainFrameNavigated, event.data)), + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.Load, + event => this.dispatchEventToListeners(SDK.TargetManager.Events.Load, event.data)), + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.PageReloadRequested, + event => this.dispatchEventToListeners(SDK.TargetManager.Events.PageReloadRequested, event.data)), + resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.WillReloadPage, + event => this.dispatchEventToListeners(SDK.TargetManager.Events.WillReloadPage, event.data)), ]; } + var copy = this._observersForTarget(target); for (var i = 0; i < copy.length; ++i) copy[i].targetAdded(target); @@ -324,6 +321,12 @@ SDK.TargetManager = class extends Common.Object { removeTarget(target) { if (!this._targets.includes(target)) return; + + var childTargetManager = this._childTargetManagers.get(target); + this._childTargetManagers.delete(target); + if (childTargetManager) + childTargetManager.dispose(); + this._targets.remove(target); var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); var treeModelListeners = resourceTreeModel && resourceTreeModel[SDK.TargetManager._listenersSymbol]; @@ -364,6 +367,7 @@ SDK.TargetManager = class extends Common.Object { * @return {?SDK.Target} */ targetById(id) { + // TODO(dgozman): add a map id -> target. for (var i = 0; i < this._targets.length; ++i) { if (this._targets[i].id() === id) return this._targets[i]; @@ -378,24 +382,6 @@ SDK.TargetManager = class extends Common.Object { return this._targets[0] || null; } - /** - * @param {!SDK.Target} target - */ - suspendReload(target) { - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); - if (resourceTreeModel) - resourceTreeModel.suspendReload(); - } - - /** - * @param {!SDK.Target} target - */ - resumeReload(target) { - var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); - if (resourceTreeModel) - setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel)); - } - /** * @param {function()} webSocketConnectionLostCallback */ @@ -409,15 +395,15 @@ SDK.TargetManager = class extends Common.Object { var target = new SDK.Target( this, 'main', Common.UIString('Node'), SDK.Target.Capability.Target, this._createMainConnection.bind(this), null); - target.subTargetsManager = new SDK.SubTargetsManager(target); target.setInspectedURL('Node'); + this._childTargetManagers.set(target, new SDK.ChildTargetManager(this, target, null)); Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSFromFrontend); return; } var capabilities = 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.ScreenCapture; + SDK.Target.Capability.ScreenCapture | SDK.Target.Capability.Tracing; if (Runtime.queryParam('isSharedWorker')) { capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target; @@ -447,6 +433,13 @@ SDK.TargetManager = class extends Common.Object { return this._mainConnection; } + /** + * @return {number} + */ + availableNodeTargetsCount() { + return this._nodeTargetIds.size; + } + /** * @param {function(string)} onMessage * @return {!Promise} @@ -457,6 +450,208 @@ SDK.TargetManager = class extends Common.Object { } }; +/** + * @implements {Protocol.TargetDispatcher} + */ +SDK.ChildTargetManager = class { + /** + * @param {!SDK.TargetManager} targetManager + * @param {!SDK.Target} parentTarget + * @param {?SDK.ResourceTreeModel} resourceTreeModel + */ + constructor(targetManager, parentTarget, resourceTreeModel) { + this._targetManager = targetManager; + this._parentTarget = parentTarget; + this._targetAgent = parentTarget.targetAgent(); + + /** @type {!Map} */ + this._childConnections = new Map(); + + parentTarget.registerTargetDispatcher(this); + this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}); + if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes')) + this._targetAgent.setAttachToFrames(true); + + if (!parentTarget.parentTarget()) { + this._targetAgent.setRemoteLocations([{host: 'localhost', port: 9229}]); + this._targetAgent.setDiscoverTargets(true); + } + + this._eventListeners = []; + if (resourceTreeModel) { + this._eventListeners.push(resourceTreeModel.addEventListener( + SDK.ResourceTreeModel.Events.MainFrameNavigated, this._detachWorkersOnMainFrameNavigated, this)); + } + } + + suspend() { + this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false}); + } + + /** + * @return {!Promise} + */ + resume() { + var fulfill; + var promise = new Promise(callback => fulfill = callback); + this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true}, fulfill); + return promise; + } + + dispose() { + Common.EventTarget.removeEventListeners(this._eventListeners); + // TODO(dgozman): this is O(n^2) when removing main target. + var childTargets = this._targetManager._targets.filter(child => child.parentTarget() === this._parentTarget); + for (var child of childTargets) + this.detachedFromTarget(child.id()); + } + + /** + * @param {string} type + * @return {number} + */ + _capabilitiesForType(type) { + if (type === 'worker') + return SDK.Target.Capability.JS | SDK.Target.Capability.Log; + 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; + } + if (type === 'node') + return SDK.Target.Capability.JS; + return 0; + } + + _detachWorkersOnMainFrameNavigated() { + // TODO(dgozman): send these from backend. + var idsToDetach = []; + for (var target of this._targetManager._targets) { + if (target.parentTarget() === this._parentTarget && target[SDK.TargetManager._isWorkerSymbol]) + idsToDetach.push(target.id()); + } + idsToDetach.forEach(id => this.detachedFromTarget(id)); + } + + /** + * @override + * @param {!Protocol.Target.TargetInfo} targetInfo + */ + targetCreated(targetInfo) { + if (targetInfo.type !== 'node') + return; + if (Runtime.queryParam('nodeFrontend')) { + this._targetAgent.attachToTarget(targetInfo.targetId); + } else { + this._targetManager._nodeTargetIds.add(targetInfo.targetId); + this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.AvailableNodeTargetsChanged); + } + } + + /** + * @override + * @param {string} targetId + */ + targetDestroyed(targetId) { + if (Runtime.queryParam('nodeFrontend') || !this._targetManager._nodeTargetIds.has(targetId)) + return; + this._targetManager._nodeTargetIds.delete(targetId); + this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.AvailableNodeTargetsChanged); + } + + /** + * @override + * @param {!Protocol.Target.TargetInfo} targetInfo + * @param {boolean} waitingForDebugger + */ + attachedToTarget(targetInfo, waitingForDebugger) { + var targetName = ''; + if (targetInfo.type === 'node') { + targetName = Common.UIString('Node: %s', targetInfo.url); + } else if (targetInfo.type !== 'iframe') { + var parsedURL = targetInfo.url.asParsedURL(); + targetName = + parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + (++this._targetManager._lastAnonymousTargetId); + } + var target = this._targetManager.createTarget( + targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type), + this._createChildConnection.bind(this, this._targetAgent, targetInfo.targetId), this._parentTarget); + target[SDK.TargetManager._isWorkerSymbol] = targetInfo.type === 'worker'; + + // Only pause the new worker if debugging SW - we are going through the pause on start checkbox. + if (!this._parentTarget.parentTarget() && Runtime.queryParam('isSharedWorker') && waitingForDebugger) + target.debuggerAgent().pause(); + target.runtimeAgent().runIfWaitingForDebugger(); + } + + /** + * @override + * @param {string} childTargetId + */ + detachedFromTarget(childTargetId) { + this._childConnections.get(childTargetId)._onDisconnect.call(null, 'target terminated'); + this._childConnections.delete(childTargetId); + } + + /** + * @override + * @param {string} childTargetId + * @param {string} message + */ + receivedMessageFromTarget(childTargetId, message) { + var connection = this._childConnections.get(childTargetId); + if (connection) + connection._onMessage.call(null, message); + } + + /** + * @param {!Protocol.TargetAgent} agent + * @param {string} childTargetId + * @param {!Protocol.InspectorBackend.Connection.Params} params + * @return {!Protocol.InspectorBackend.Connection} + */ + _createChildConnection(agent, childTargetId, params) { + var connection = new SDK.ChildConnection(agent, childTargetId, params); + this._childConnections.set(childTargetId, connection); + return connection; + } +}; + +/** + * @implements {Protocol.InspectorBackend.Connection} + */ +SDK.ChildConnection = class { + /** + * @param {!Protocol.TargetAgent} agent + * @param {string} targetId + * @param {!Protocol.InspectorBackend.Connection.Params} params + */ + constructor(agent, targetId, params) { + this._agent = agent; + this._targetId = targetId; + this._onMessage = params.onMessage; + this._onDisconnect = params.onDisconnect; + } + + /** + * @override + * @param {string} message + */ + sendMessage(message) { + this._agent.sendMessageToTarget(this._targetId, message); + } + + /** + * @override + * @return {!Promise} + */ + disconnect() { + throw 'Not implemented'; + } +}; + /** @enum {symbol} */ SDK.TargetManager.Events = { InspectedURLChanged: Symbol('InspectedURLChanged'), @@ -466,10 +661,12 @@ SDK.TargetManager.Events = { PageReloadRequested: Symbol('PageReloadRequested'), WillReloadPage: Symbol('WillReloadPage'), TargetDisposed: Symbol('TargetDisposed'), - SuspendStateChanged: Symbol('SuspendStateChanged') + SuspendStateChanged: Symbol('SuspendStateChanged'), + AvailableNodeTargetsChanged: Symbol('AvailableNodeTargetsChanged') }; SDK.TargetManager._listenersSymbol = Symbol('SDK.TargetManager.Listeners'); +SDK.TargetManager._isWorkerSymbol = Symbol('SDK.TargetManager.IsWorker'); /** * @interface diff --git a/front_end/sdk/TracingManager.js b/front_end/sdk/TracingManager.js index f60455d5f9..9e7af8e804 100644 --- a/front_end/sdk/TracingManager.js +++ b/front_end/sdk/TracingManager.js @@ -9,7 +9,6 @@ SDK.TracingManagerClient = function() {}; SDK.TracingManagerClient.prototype = { - tracingStarted() {}, /** * @param {!Array.} events */ @@ -28,12 +27,13 @@ SDK.TracingManagerClient.prototype = { /** * @unrestricted */ -SDK.TracingManager = class { +SDK.TracingManager = class extends SDK.SDKModel { /** * @param {!SDK.Target} target */ constructor(target) { - this._target = target; + super(target); + this._tracingAgent = target.tracingAgent(); target.registerTracingDispatcher(new SDK.TracingDispatcher(this)); /** @type {?SDK.TracingManagerClient} */ @@ -42,13 +42,6 @@ SDK.TracingManager = class { this._eventsRetrieved = 0; } - /** - * @return {?SDK.Target} - */ - target() { - return this._target; - } - /** * @param {number=} usage * @param {number=} eventCount @@ -84,17 +77,15 @@ SDK.TracingManager = class { * @param {!SDK.TracingManagerClient} client * @param {string} categoryFilter * @param {string} options - * @param {function(?string)=} callback + * @return {!Promise} */ - start(client, categoryFilter, options, callback) { + start(client, categoryFilter, options) { if (this._activeClient) throw new Error('Tracing is already started'); var bufferUsageReportingIntervalMs = 500; this._activeClient = client; - this._target.tracingAgent().start( - categoryFilter, options, bufferUsageReportingIntervalMs, SDK.TracingManager.TransferMode.ReportEvents, - callback); - this._activeClient.tracingStarted(); + return this._tracingAgent.start( + categoryFilter, options, bufferUsageReportingIntervalMs, SDK.TracingManager.TransferMode.ReportEvents); } stop() { @@ -103,10 +94,12 @@ SDK.TracingManager = class { if (this._finishing) throw new Error('Tracing is already being stopped'); this._finishing = true; - this._target.tracingAgent().end(); + this._tracingAgent.end(); } }; +SDK.SDKModel.register(SDK.TracingManager, SDK.Target.Capability.Tracing); + /** @typedef {!{ cat: string, pid: number, diff --git a/front_end/sdk/module.json b/front_end/sdk/module.json index a86a1ef27f..72143bb646 100644 --- a/front_end/sdk/module.json +++ b/front_end/sdk/module.json @@ -123,7 +123,6 @@ "LayerTreeBase.js", "NetworkLog.js", "ServiceWorkerManager.js", - "SubTargetsManager.js", "TracingManager.js", "TracingModel.js", "RuntimeModel.js", diff --git a/front_end/settings/SettingsScreen.js b/front_end/settings/SettingsScreen.js index c934379967..a860463590 100644 --- a/front_end/settings/SettingsScreen.js +++ b/front_end/settings/SettingsScreen.js @@ -479,7 +479,7 @@ Settings.SettingsScreen.ActionDelegate = class { case 'settings.show': Settings.SettingsScreen._showSettingsScreen(); return true; - case 'settings.help': + case 'settings.documentation': InspectorFrontendHost.openInNewTab('https://developers.google.com/web/tools/chrome-devtools/'); return true; case 'settings.shortcuts': diff --git a/front_end/settings/module.json b/front_end/settings/module.json index e4b274c5d4..50d02334a0 100644 --- a/front_end/settings/module.json +++ b/front_end/settings/module.json @@ -15,8 +15,8 @@ { "type": "@UI.ActionDelegate", "category": "Settings", - "actionId": "settings.help", - "title": "Help", + "actionId": "settings.documentation", + "title": "Documentation", "className": "Settings.SettingsScreen.ActionDelegate" }, { @@ -43,12 +43,6 @@ "order": 20, "actionId": "settings.show" }, - { - "type": "context-menu-item", - "location": "mainMenu/footer", - "order": 30, - "actionId": "settings.help" - }, { "type": "view", "location": "settings-view", diff --git a/front_end/sources/InplaceFormatterEditorAction.js b/front_end/sources/InplaceFormatterEditorAction.js index 036a6fc8e6..24defa6e2f 100644 --- a/front_end/sources/InplaceFormatterEditorAction.js +++ b/front_end/sources/InplaceFormatterEditorAction.js @@ -124,7 +124,7 @@ Sources.InplaceFormatterEditorAction = class { var endLocation = sourceMapping.originalToFormatted(range.endLine, range.endColumn); uiSourceCode.addDecoration( - new Common.TextRange(...startLocation, ...endLocation), + new Common.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]), /** @type {string} */ (decoration.type()), decoration.data()); } } diff --git a/front_end/sources/JavaScriptSourceFrame.js b/front_end/sources/JavaScriptSourceFrame.js index 9410c7bd2f..2dfa997d88 100644 --- a/front_end/sources/JavaScriptSourceFrame.js +++ b/front_end/sources/JavaScriptSourceFrame.js @@ -615,7 +615,7 @@ Sources.JavaScriptSourceFrame = class extends SourceFrame.UISourceCodeFrame { bookmarks.map(bookmark => bookmark.clear()); for (var location of locations) { - var icon = UI.Icon.create('smallicon-green-ball'); + var icon = UI.Icon.create('smallicon-green-arrow'); icon.classList.add('cm-continue-to-location'); icon.addEventListener('click', location.continueToLocation.bind(location)); icon.addEventListener('mousemove', hidePopoverAndConsumeEvent.bind(this)); diff --git a/front_end/sources/NavigatorView.js b/front_end/sources/NavigatorView.js index 8948d30037..fc433ab3c6 100644 --- a/front_end/sources/NavigatorView.js +++ b/front_end/sources/NavigatorView.js @@ -78,9 +78,6 @@ Sources.NavigatorView = class extends UI.VBox { SDK.targetManager.observeTargets(this); this._resetWorkspace(Workspace.workspace); this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this)); - - Bindings.networkProjectManager.on( - Bindings.NetworkProjectManager.FrameAttributionChangedEvent, this._frameAttributionChanged, this); } /** @@ -179,8 +176,7 @@ Sources.NavigatorView = class extends UI.VBox { */ _onBindingRemoved(event) { var binding = /** @type {!Persistence.PersistenceBinding} */ (event.data); - if (this._addUISourceCode(binding.network)) - this.uiSourceCodeAdded(binding.network); + this._addUISourceCode(binding.network); } /** @@ -251,27 +247,16 @@ Sources.NavigatorView = class extends UI.VBox { /** * @param {!Workspace.UISourceCode} uiSourceCode - * @return {?Set} + * @return {?SDK.ResourceTreeFrame} */ - _uiSourceCodeFrames(uiSourceCode) { - var frames = Bindings.NetworkProject.framesForUISourceCode(uiSourceCode); - if (!frames || !frames.size) { - // This is to overcome compilation cache which doesn't get reset. - var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode); + _uiSourceCodeFrame(uiSourceCode) { + var frame = Bindings.NetworkProject.frameForProject(uiSourceCode.project()); + if (!frame) { + var target = Bindings.NetworkProject.targetForProject(uiSourceCode.project()); var resourceTreeModel = target && SDK.ResourceTreeModel.fromTarget(target); - var frame = resourceTreeModel ? resourceTreeModel.mainFrame : null; - if (frame) - frames = new Set([frame]); + frame = resourceTreeModel && resourceTreeModel.mainFrame; } - return frames; - } - - /** - * @param {!Bindings.NetworkProjectManager.FrameAttributionChangedEvent} event - */ - _frameAttributionChanged(event) { - this._removeUISourceCode(event.uiSourceCode); - this._addUISourceCode(event.uiSourceCode); + return frame; } /** @@ -279,11 +264,11 @@ Sources.NavigatorView = class extends UI.VBox { */ _addUISourceCode(uiSourceCode) { if (!this.accept(uiSourceCode)) - return false; + return; var binding = Persistence.persistence.binding(uiSourceCode); if (!Runtime.experiments.isEnabled('persistence2') && binding && binding.network === uiSourceCode) - return false; + return; var isFromSourceMap = uiSourceCode.contentType().isFromSourceMap(); var path; @@ -294,26 +279,14 @@ Sources.NavigatorView = class extends UI.VBox { var project = uiSourceCode.project(); var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode); - var frames = this._uiSourceCodeFrames(uiSourceCode); - var uiSourceCodeNodes = []; - if (frames && frames.size) { - for (var frame of frames) { - var folderNode = - this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap); - var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode, frame); - folderNode.appendChild(uiSourceCodeNode); - uiSourceCodeNodes.push(uiSourceCodeNode); - } - } else { - var folderNode = - this._folderNode(uiSourceCode, project, target, null, uiSourceCode.origin(), path, isFromSourceMap); - var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode, null); - folderNode.appendChild(uiSourceCodeNode); - uiSourceCodeNodes.push(uiSourceCodeNode); - } + var frame = this._uiSourceCodeFrame(uiSourceCode); - this._uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNodes); - return true; + var folderNode = + this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap); + var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode); + this._uiSourceCodeNodes.set(uiSourceCode, [uiSourceCodeNode]); + folderNode.appendChild(uiSourceCodeNode); + this.uiSourceCodeAdded(uiSourceCode); } /** @@ -327,8 +300,7 @@ Sources.NavigatorView = class extends UI.VBox { */ _uiSourceCodeAdded(event) { var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); - if (this._addUISourceCode(uiSourceCode)) - this.uiSourceCodeAdded(uiSourceCode); + this._addUISourceCode(uiSourceCode); } /** @@ -560,7 +532,7 @@ Sources.NavigatorView = class extends UI.VBox { var project = uiSourceCode.project(); var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode); - var frame = node.frame(); + var frame = this._uiSourceCodeFrame(uiSourceCode); var parentNode = node.parent; parentNode.removeChild(node); @@ -1266,22 +1238,13 @@ Sources.NavigatorUISourceCodeTreeNode = class extends Sources.NavigatorTreeNode /** * @param {!Sources.NavigatorView} navigatorView * @param {!Workspace.UISourceCode} uiSourceCode - * @param {?SDK.ResourceTreeFrame} frame */ - constructor(navigatorView, uiSourceCode, frame) { + constructor(navigatorView, uiSourceCode) { super(uiSourceCode.project().id() + ':' + uiSourceCode.url(), Sources.NavigatorView.Types.File); this._navigatorView = navigatorView; this._uiSourceCode = uiSourceCode; this._treeElement = null; this._eventListeners = []; - this._frame = frame; - } - - /** - * @return {?SDK.ResourceTreeFrame} - */ - frame() { - return this._frame; } /** diff --git a/front_end/sources/ScriptFormatterEditorAction.js b/front_end/sources/ScriptFormatterEditorAction.js index 543c4777a5..d4d16e9c2e 100644 --- a/front_end/sources/ScriptFormatterEditorAction.js +++ b/front_end/sources/ScriptFormatterEditorAction.js @@ -379,6 +379,17 @@ Sources.ScriptFormatterEditorAction = class { /** @type {!Sources.FormatterScriptMapping} */ (this._scriptMappingByDebuggerModel.get(debuggerModels[i])); Bindings.debuggerWorkspaceBinding.setSourceMapping(debuggerModels[i], formattedUISourceCode, scriptMapping); } + + for (var decoration of uiSourceCode.allDecorations()) { + var range = decoration.range(); + var startLocation = formatterMapping.originalToFormatted(range.startLine, range.startColumn); + var endLocation = formatterMapping.originalToFormatted(range.endLine, range.endColumn); + + formattedUISourceCode.addDecoration( + new Common.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]), + /** @type {string} */ (decoration.type()), decoration.data()); + } + this._showIfNeeded(uiSourceCode, formattedUISourceCode, formatterMapping); } } diff --git a/front_end/sources/SourcesPanel.js b/front_end/sources/SourcesPanel.js index 69f172c4cd..735c0da494 100644 --- a/front_end/sources/SourcesPanel.js +++ b/front_end/sources/SourcesPanel.js @@ -116,9 +116,8 @@ Sources.SourcesPanel = class extends UI.Panel { SDK.targetManager.addModelListener( SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, event => this._debuggerResumed(/** @type {!SDK.DebuggerModel} */ (event.data))); - SDK.targetManager.addModelListener( - SDK.SubTargetsManager, SDK.SubTargetsManager.Events.AvailableNodeTargetsChanged, - this._availableNodeTargetsChanged, this); + SDK.targetManager.addEventListener( + SDK.TargetManager.Events.AvailableNodeTargetsChanged, this._availableNodeTargetsChanged, this); new Sources.WorkspaceMappingTip(this, this._workspace); Extensions.extensionServer.addEventListener( Extensions.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this); diff --git a/front_end/sources/SourcesView.js b/front_end/sources/SourcesView.js index 8f39d886e0..11a957142e 100644 --- a/front_end/sources/SourcesView.js +++ b/front_end/sources/SourcesView.js @@ -28,6 +28,8 @@ Sources.SourcesView = class extends UI.VBox { var tabbedEditorPlaceholderText = Host.isMac() ? Common.UIString('Hit \u2318+P to open a file') : Common.UIString('Hit Ctrl+P to open a file'); + if (Runtime.experiments.isEnabled('persistence2')) + tabbedEditorPlaceholderText += '\n\n' + Common.UIString('Drop in a folder to add to workspace'); this._editorContainer = new Sources.TabbedEditorContainer( this, Common.settings.createLocalSetting('previouslyViewedFiles', []), tabbedEditorPlaceholderText); this._editorContainer.show(this._searchableView.element); diff --git a/front_end/sources/ThreadsSidebarPane.js b/front_end/sources/ThreadsSidebarPane.js index 897bbbfe24..35f6e6ab92 100644 --- a/front_end/sources/ThreadsSidebarPane.js +++ b/front_end/sources/ThreadsSidebarPane.js @@ -18,9 +18,8 @@ Sources.ThreadsSidebarPane = class extends UI.VBox { UI.context.addFlavorChangeListener(SDK.Target, this._targetFlavorChanged, this); - SDK.targetManager.addModelListener( - SDK.SubTargetsManager, SDK.SubTargetsManager.Events.AvailableNodeTargetsChanged, - this._availableNodeTargetsChanged, this); + SDK.targetManager.addEventListener( + SDK.TargetManager.Events.AvailableNodeTargetsChanged, this._availableNodeTargetsChanged, this); this._availableNodeTargetsChanged(); SDK.targetManager.observeModels(SDK.DebuggerModel, this); @@ -33,23 +32,11 @@ Sources.ThreadsSidebarPane = class extends UI.VBox { var minJSTargets = Runtime.queryParam('nodeFrontend') ? 1 : 2; if (SDK.targetManager.models(SDK.DebuggerModel).length >= minJSTargets) return true; - if (Sources.ThreadsSidebarPane.availableNodeTargetsCount()) - return true; - return false; - } - - /** - * @return {number} - */ - static availableNodeTargetsCount() { - var count = 0; - for (var target of SDK.targetManager.targets(SDK.Target.Capability.Target)) - count += SDK.SubTargetsManager.fromTarget(target).availableNodeTargetsCount(); - return count; + return !!SDK.targetManager.availableNodeTargetsCount(); } _availableNodeTargetsChanged() { - var count = Sources.ThreadsSidebarPane.availableNodeTargetsCount(); + var count = SDK.targetManager.availableNodeTargetsCount(); if (!count) { this._availableNodeTargetsElement.classList.add('hidden'); return; diff --git a/front_end/text_editor/cmdevtools.css b/front_end/text_editor/cmdevtools.css index 48e272a4f6..869ecc96ba 100644 --- a/front_end/text_editor/cmdevtools.css +++ b/front_end/text_editor/cmdevtools.css @@ -162,7 +162,13 @@ .cm-continue-to-location { cursor: pointer; - transform: scale(0.7); + opacity: 0.5; + position: relative; + top: 2px; +} + +.cm-continue-to-location:hover { + opacity: 1; } div.CodeMirror span.CodeMirror-matchingbracket { diff --git a/front_end/timeline/TimelineController.js b/front_end/timeline/TimelineController.js index 00272073b3..dbfd06d3ac 100644 --- a/front_end/timeline/TimelineController.js +++ b/front_end/timeline/TimelineController.js @@ -3,36 +3,35 @@ // found in the LICENSE file. /** - * @implements {SDK.TargetManager.Observer} + * @implements {SDK.SDKModelObserver} * @implements {SDK.TracingManagerClient} * @unrestricted */ Timeline.TimelineController = class { /** - * @param {!SDK.Target} target + * @param {!SDK.TracingManager} tracingManager * @param {!Timeline.PerformanceModel} performanceModel * @param {!Timeline.TimelineController.Client} client */ - constructor(target, performanceModel, client) { - this._target = target; + constructor(tracingManager, performanceModel, client) { + this._tracingManager = tracingManager; this._performanceModel = performanceModel; this._client = client; this._tracingModelBackingStorage = new Bindings.TempFileBackingStorage('tracing'); this._tracingModel = new SDK.TracingModel(this._tracingModelBackingStorage); - this._performanceModel.setMainTarget(target); + this._performanceModel.setMainTarget(tracingManager.target()); - /** @type {!Array} */ - this._targets = []; /** @type {!Array} */ this._extensionSessions = []; - SDK.targetManager.observeTargets(this); + SDK.targetManager.observeModels(SDK.CPUProfilerModel, this); } /** * @param {!Timeline.TimelineController.RecordingOptions} options * @param {!Array} providers + * @return {!Promise} */ startRecording(options, providers) { this._extensionTraceProviders = Extensions.extensionServer.traceProviders().slice(); @@ -72,15 +71,16 @@ Timeline.TimelineController = class { this._extensionSessions = providers.map(provider => new Timeline.ExtensionTracingSession(provider, this._performanceModel)); this._extensionSessions.forEach(session => session.start()); - this._startRecordingWithCategories(categoriesArray.join(','), options.enableJSSampling); + var startPromise = this._startRecordingWithCategories(categoriesArray.join(','), options.enableJSSampling); this._performanceModel.setRecordStartTime(Date.now()); + return startPromise; } stopRecording() { var tracingStoppedPromises = []; tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve)); - tracingStoppedPromises.push(this._stopProfilingOnAllTargets()); - this._target.tracingManager.stop(); + tracingStoppedPromises.push(this._stopProfilingOnAllModels()); + this._tracingManager.stop(); tracingStoppedPromises.push(SDK.targetManager.resumeAllTargets()); this._client.loadingStarted(); @@ -97,59 +97,38 @@ Timeline.TimelineController = class { /** * @override - * @param {!SDK.Target} target + * @param {!SDK.CPUProfilerModel} cpuProfilerModel */ - targetAdded(target) { - this._targets.push(target); + modelAdded(cpuProfilerModel) { if (this._profiling) - this._startProfilingOnTarget(target); + cpuProfilerModel.startRecording(); } /** * @override - * @param {!SDK.Target} target + * @param {!SDK.CPUProfilerModel} cpuProfilerModel */ - targetRemoved(target) { - this._targets.remove(target, true); + modelRemoved(cpuProfilerModel) { // FIXME: We'd like to stop profiling on the target and retrieve a profile // but it's too late. Backend connection is closed. } - /** - * @param {!SDK.Target} target - * @return {!Promise} - */ - _startProfilingOnTarget(target) { - return target.hasJSCapability() ? target.profilerAgent().start() : Promise.resolve(); - } - /** * @return {!Promise} */ - _startProfilingOnAllTargets() { - var intervalUs = Common.moduleSetting('highResolutionCpuProfiling').get() ? 100 : 1000; - this._target.profilerAgent().setSamplingInterval(intervalUs); + _startProfilingOnAllModels() { this._profiling = true; - return Promise.all(this._targets.map(this._startProfilingOnTarget)); - } - - /** - * @param {!SDK.Target} target - * @return {!Promise} - */ - _stopProfilingOnTarget(target) { - return target.hasJSCapability() ? target.profilerAgent().stop(this._addCpuProfile.bind(this, target.id())) : - Promise.resolve(); + var models = SDK.targetManager.models(SDK.CPUProfilerModel); + return Promise.all(models.map(model => model.startRecording())); } /** * @param {string} targetId - * @param {?Protocol.Error} error * @param {?Protocol.Profiler.Profile} cpuProfile */ - _addCpuProfile(targetId, error, cpuProfile) { + _addCpuProfile(targetId, cpuProfile) { if (!cpuProfile) { - Common.console.warn(Common.UIString('CPU profile for a target is not available. %s', error || '')); + Common.console.warn(Common.UIString('CPU profile for a target is not available.')); return; } if (!this._cpuProfiles) @@ -160,43 +139,31 @@ Timeline.TimelineController = class { /** * @return {!Promise} */ - _stopProfilingOnAllTargets() { - var targets = this._profiling ? this._targets : []; + _stopProfilingOnAllModels() { + var models = this._profiling ? SDK.targetManager.models(SDK.CPUProfilerModel) : []; this._profiling = false; - return Promise.all(targets.map(this._stopProfilingOnTarget, this)); + var promises = []; + for (var model of models) { + var targetId = model.target().id(); + var modelPromise = model.stopRecording().then(this._addCpuProfile.bind(this, targetId)); + promises.push(modelPromise); + } + return Promise.all(promises); } /** * @param {string} categories * @param {boolean=} enableJSSampling - * @param {function(?string)=} callback + * @return {!Promise} */ - _startRecordingWithCategories(categories, enableJSSampling, callback) { + _startRecordingWithCategories(categories, enableJSSampling) { SDK.targetManager.suspendAllTargets(); var profilingStartedPromise = enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile') ? - this._startProfilingOnAllTargets() : + this._startProfilingOnAllModels() : Promise.resolve(); var samplingFrequencyHz = Common.moduleSetting('highResolutionCpuProfiling').get() ? 10000 : 1000; var options = 'sampling-frequency=' + samplingFrequencyHz; - var target = this._target; - var tracingManager = target.tracingManager; - SDK.targetManager.suspendReload(target); - profilingStartedPromise.then(tracingManager.start.bind(tracingManager, this, categories, options, onTraceStarted)); - /** - * @param {?string} error - */ - function onTraceStarted(error) { - SDK.targetManager.resumeReload(target); - if (callback) - callback(error); - } - } - - /** - * @override - */ - tracingStarted() { - this._client.recordingStarted(); + return profilingStartedPromise.then(() => this._tracingManager.start(this, categories, options)); } /** @@ -258,16 +225,13 @@ Timeline.TimelineController = class { return; var pid = mainMetaEvent.thread.process().id(); - var mainCpuProfile = this._cpuProfiles.get(this._target.id()); + var mainCpuProfile = this._cpuProfiles.get(this._tracingManager.target().id()); this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile); var workerMetaEvents = metadataEvents.filter(event => event.name === metadataEventTypes.TracingSessionIdForWorker); for (var metaEvent of workerMetaEvents) { var workerId = metaEvent.args['data']['workerId']; - var workerTarget = SDK.targetManager.targetById(workerId); - if (!workerTarget) - continue; - var cpuProfile = this._cpuProfiles.get(workerTarget.id()); + var cpuProfile = this._cpuProfiles.get(workerId); this._injectCpuProfileEvent( metaEvent.thread.process().id(), metaEvent.args['data']['workerThreadId'], cpuProfile); } @@ -298,8 +262,6 @@ Timeline.TimelineController = class { Timeline.TimelineController.Client = function() {}; Timeline.TimelineController.Client.prototype = { - recordingStarted() {}, - /** * @param {number} usage */ diff --git a/front_end/timeline/TimelineDetailsView.js b/front_end/timeline/TimelineDetailsView.js index 615df98296..bb3dc5e5d1 100644 --- a/front_end/timeline/TimelineDetailsView.js +++ b/front_end/timeline/TimelineDetailsView.js @@ -42,8 +42,8 @@ Timeline.TimelineDetailsView = class extends UI.VBox { this._rangeDetailViews.set(tabIds.CallTree, callTreeView); const eventsView = new Timeline.EventsTimelineTreeView(filters, delegate); - this._appendTab(tabIds.Events, Common.UIString('Event Log'), eventsView); - this._rangeDetailViews.set(tabIds.Events, eventsView); + this._appendTab(tabIds.EventLog, Common.UIString('Event Log'), eventsView); + this._rangeDetailViews.set(tabIds.EventLog, eventsView); } this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this); @@ -237,7 +237,7 @@ Timeline.TimelineDetailsView = class extends UI.VBox { */ Timeline.TimelineDetailsView.Tab = { Details: 'Details', - Events: 'Events', + EventLog: 'EventLog', CallTree: 'CallTree', BottomUp: 'BottomUp', PaintProfiler: 'PaintProfiler', diff --git a/front_end/timeline/TimelineFlameChartView.js b/front_end/timeline/TimelineFlameChartView.js index 82fa8a691b..01a9b47a7a 100644 --- a/front_end/timeline/TimelineFlameChartView.js +++ b/front_end/timeline/TimelineFlameChartView.js @@ -2,98 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Timeline.FlameChartStyle = { - textColor: '#333' -}; - -/** - * @enum {symbol} - */ -Timeline.TimelineFlameChartEntryType = { - Frame: Symbol('Frame'), - Event: Symbol('Event'), - InteractionRecord: Symbol('InteractionRecord'), - ExtensionEvent: Symbol('ExtensionEvent') -}; - -/** - * @implements {PerfUI.FlameChartMarker} - * @unrestricted - */ -Timeline.TimelineFlameChartMarker = class { - /** - * @param {number} startTime - * @param {number} startOffset - * @param {!Timeline.TimelineMarkerStyle} style - */ - constructor(startTime, startOffset, style) { - this._startTime = startTime; - this._startOffset = startOffset; - this._style = style; - } - - /** - * @override - * @return {number} - */ - startTime() { - return this._startTime; - } - - /** - * @override - * @return {string} - */ - color() { - return this._style.color; - } - - /** - * @override - * @return {string} - */ - title() { - var startTime = Number.millisToString(this._startOffset); - return Common.UIString('%s at %s', this._style.title, startTime); - } - - /** - * @override - * @param {!CanvasRenderingContext2D} context - * @param {number} x - * @param {number} height - * @param {number} pixelsPerMillisecond - */ - draw(context, x, height, pixelsPerMillisecond) { - var lowPriorityVisibilityThresholdInPixelsPerMs = 4; - - 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(); - } - - 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.setLineDash(this._style.dashStyle); - context.lineTo(x, context.canvas.height); - context.stroke(); - } - context.restore(); - } -}; - /** * @implements {Timeline.TimelineModeView} * @implements {PerfUI.FlameChartDelegate} @@ -115,47 +23,56 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { this._searchResults; this._filters = filters; - this._splitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150); + this._showMemoryGraphSetting = Common.settings.createSetting('timelineShowMemory', false); + + // Create main and network flamecharts. + this._networkSplitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150); - this._dataProvider = new Timeline.TimelineFlameChartDataProvider(filters); var mainViewGroupExpansionSetting = Common.settings.createSetting('timelineFlamechartMainViewGroupExpansion', {}); - this._mainView = new PerfUI.FlameChart(this._dataProvider, this, mainViewGroupExpansionSetting); - this._mainView.alwaysShowVerticalScroll(); - this._mainView.enableRuler(false); + this._mainDataProvider = new Timeline.TimelineFlameChartDataProvider(filters); + this._mainFlameChart = new PerfUI.FlameChart(this._mainDataProvider, this, mainViewGroupExpansionSetting); + this._mainFlameChart.alwaysShowVerticalScroll(); + this._mainFlameChart.enableRuler(false); - this._networkViewGroupExpansionSetting = + this._networkFlameChartGroupExpansionSetting = Common.settings.createSetting('timelineFlamechartNetworkViewGroupExpansion', {}); this._networkDataProvider = new Timeline.TimelineFlameChartNetworkDataProvider(); - this._networkView = new PerfUI.FlameChart(this._networkDataProvider, this, this._networkViewGroupExpansionSetting); - this._networkView.alwaysShowVerticalScroll(); + this._networkFlameChart = new PerfUI.FlameChart( + this._networkDataProvider, this, this._networkFlameChartGroupExpansionSetting); + this._networkFlameChart.alwaysShowVerticalScroll(); this._networkPane = new UI.VBox(); this._networkPane.setMinimumSize(23, 23); - this._networkView.show(this._networkPane.element); + this._networkFlameChart.show(this._networkPane.element); this._splitResizer = this._networkPane.element.createChild('div', 'timeline-flamechart-resizer'); - this._splitWidget.hideDefaultResizer(true); - this._splitWidget.installResizer(this._splitResizer); - - this._splitWidget.setMainWidget(this._mainView); - this._splitWidget.setSidebarWidget(this._networkPane); - - if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) { - // Create top level properties splitter. - this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState'); - this._detailsSplitWidget.element.classList.add('timeline-details-split'); - this._detailsView = new Timeline.TimelineDetailsView(filters, delegate); - this._detailsSplitWidget.installResizer(this._detailsView.headerElement()); - this._detailsSplitWidget.setMainWidget(this._splitWidget); - this._detailsSplitWidget.setSidebarWidget(this._detailsView); - this._detailsSplitWidget.show(this.element); - } else { - this._splitWidget.show(this.element); - } - - this._onMainEntrySelected = this._onEntrySelected.bind(this, this._dataProvider); + this._networkSplitWidget.hideDefaultResizer(true); + this._networkSplitWidget.installResizer(this._splitResizer); + + this._networkSplitWidget.setMainWidget(this._mainFlameChart); + this._networkSplitWidget.setSidebarWidget(this._networkPane); + + // Create counters chart splitter. + this._chartSplitWidget = new UI.SplitWidget(false, true, 'timelineCountersSplitViewState'); + this._countersView = new Timeline.CountersGraph(this._delegate); + this._chartSplitWidget.setMainWidget(this._networkSplitWidget); + this._chartSplitWidget.setSidebarWidget(this._countersView); + this._chartSplitWidget.hideDefaultResizer(); + this._chartSplitWidget.installResizer(/** @type {!Element} */ (this._countersView.resizerElement())); + this._updateCountersGraphToggle(); + + // Create top level properties splitter. + this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState'); + this._detailsSplitWidget.element.classList.add('timeline-details-split'); + this._detailsView = new Timeline.TimelineDetailsView(filters, delegate); + this._detailsSplitWidget.installResizer(this._detailsView.headerElement()); + this._detailsSplitWidget.setMainWidget(this._chartSplitWidget); + this._detailsSplitWidget.setSidebarWidget(this._detailsView); + this._detailsSplitWidget.show(this.element); + + this._onMainEntrySelected = this._onEntrySelected.bind(this, this._mainDataProvider); this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider); - this._mainView.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this); - this._networkView.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this); + this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this); + this._networkFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this); this._nextExtensionIndex = 0; this._boundRefresh = this._refresh.bind(this); @@ -203,8 +120,9 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { } _refresh() { - this._dataProvider.setModel(this._model); + this._mainDataProvider.setModel(this._model); this._networkDataProvider.setModel(this._model); + this._countersView.setModel(this._model); if (this._detailsView) this._detailsView.setModel(this._model); @@ -212,15 +130,15 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { this._appendExtensionData(); if (this._networkDataProvider.isEmpty()) { - this._mainView.enableRuler(true); - this._splitWidget.hideSidebar(); + this._mainFlameChart.enableRuler(true); + this._networkSplitWidget.hideSidebar(); } else { - this._mainView.enableRuler(false); - this._splitWidget.showBoth(); + this._mainFlameChart.enableRuler(false); + this._networkSplitWidget.showBoth(); this.resizeToPreferredHeights(); } - this._mainView.reset(); - this._networkView.reset(); + this._mainFlameChart.reset(); + this._networkFlameChart.reset(); } _appendExtensionData() { @@ -228,8 +146,8 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { return; var extensions = this._model.extensionInfo(); while (this._nextExtensionIndex < extensions.length) - this._dataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]); - this._mainView.scheduleUpdate(); + this._mainDataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]); + this._mainFlameChart.scheduleUpdate(); } /** @@ -238,18 +156,19 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { */ highlightEvent(event) { var entryIndex = - event ? this._dataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1; + event ? this._mainDataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1; if (entryIndex >= 0) - this._mainView.highlightEntry(entryIndex); + this._mainFlameChart.highlightEntry(entryIndex); else - this._mainView.hideHighlight(); + this._mainFlameChart.hideHighlight(); } /** * @override */ willHide() { - this._networkViewGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this); + this._networkFlameChartGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this); + this._showMemoryGraphSetting.removeChangeListener(this._updateCountersGraphToggle, this); Bindings.blackboxManager.removeChangeListener(this._boundRefresh); } @@ -257,12 +176,20 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { * @override */ wasShown() { - this._networkViewGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this); + this._networkFlameChartGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this); + this._showMemoryGraphSetting.addChangeListener(this._updateCountersGraphToggle, this); Bindings.blackboxManager.addChangeListener(this._boundRefresh); if (this._needsResizeToPreferredHeights) this.resizeToPreferredHeights(); - this._mainView.scheduleUpdate(); - this._networkView.scheduleUpdate(); + this._mainFlameChart.scheduleUpdate(); + this._networkFlameChart.scheduleUpdate(); + } + + _updateCountersGraphToggle() { + if (this._showMemoryGraphSetting.get()) + this._chartSplitWidget.showBoth(); + else + this._chartSplitWidget.hideSidebar(); } /** @@ -279,9 +206,10 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { * @param {number} endTime */ setWindowTimes(startTime, endTime) { - this._mainView.setWindowTimes(startTime, endTime); - this._networkView.setWindowTimes(startTime, endTime); + this._mainFlameChart.setWindowTimes(startTime, endTime); + this._networkFlameChart.setWindowTimes(startTime, endTime); this._networkDataProvider.setWindowTimes(startTime, endTime); + this._countersView.setWindowTimes(startTime, endTime); this._windowStartTime = startTime; this._windowEndTime = endTime; } @@ -296,7 +224,7 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { this._delegate.select(null); return; } - var timelineSelection = this._dataProvider.selectionForEvent(event); + var timelineSelection = this._mainDataProvider.selectionForEvent(event); if (timelineSelection) this._delegate.select(timelineSelection); } @@ -306,10 +234,10 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { * @param {?Timeline.TimelineSelection} selection */ setSelection(selection) { - var index = this._dataProvider.entryIndexForSelection(selection); - this._mainView.setSelectedEntry(index); + var index = this._mainDataProvider.entryIndexForSelection(selection); + this._mainFlameChart.setSelectedEntry(index); index = this._networkDataProvider.entryIndexForSelection(selection); - this._networkView.setSelectedEntry(index); + this._networkFlameChart.setSelectedEntry(index); if (selection && this._detailsView) this._detailsView.setSelection(selection); } @@ -331,7 +259,7 @@ Timeline.TimelineFlameChartView = class extends UI.VBox { this._needsResizeToPreferredHeights = false; this._networkPane.element.classList.toggle( 'timeline-network-resizer-disabled', !this._networkDataProvider.isExpanded()); - this._splitWidget.setSidebarSize( + this._networkSplitWidget.setSidebarSize( this._networkDataProvider.preferredHeight() + this._splitResizer.clientHeight + PerfUI.FlameChart.HeaderHeight + 2); } @@ -488,3 +416,95 @@ Timeline.TimelineFlameChartView.Selection = class { this.entryIndex = entryIndex; } }; + +Timeline.FlameChartStyle = { + textColor: '#333' +}; + +/** + * @enum {symbol} + */ +Timeline.TimelineFlameChartEntryType = { + Frame: Symbol('Frame'), + Event: Symbol('Event'), + InteractionRecord: Symbol('InteractionRecord'), + ExtensionEvent: Symbol('ExtensionEvent') +}; + +/** + * @implements {PerfUI.FlameChartMarker} + * @unrestricted + */ +Timeline.TimelineFlameChartMarker = class { + /** + * @param {number} startTime + * @param {number} startOffset + * @param {!Timeline.TimelineMarkerStyle} style + */ + constructor(startTime, startOffset, style) { + this._startTime = startTime; + this._startOffset = startOffset; + this._style = style; + } + + /** + * @override + * @return {number} + */ + startTime() { + return this._startTime; + } + + /** + * @override + * @return {string} + */ + color() { + return this._style.color; + } + + /** + * @override + * @return {string} + */ + title() { + var startTime = Number.millisToString(this._startOffset); + return Common.UIString('%s at %s', this._style.title, startTime); + } + + /** + * @override + * @param {!CanvasRenderingContext2D} context + * @param {number} x + * @param {number} height + * @param {number} pixelsPerMillisecond + */ + draw(context, x, height, pixelsPerMillisecond) { + var lowPriorityVisibilityThresholdInPixelsPerMs = 4; + + 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(); + } + + 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.setLineDash(this._style.dashStyle); + context.lineTo(x, context.canvas.height); + context.stroke(); + } + context.restore(); + } +}; diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js index a9de61fd29..ee00e525df 100644 --- a/front_end/timeline/TimelinePanel.js +++ b/front_end/timeline/TimelinePanel.js @@ -66,9 +66,6 @@ Timeline.TimelinePanel = class extends UI.Panel { this._cpuThrottlingManager = new Components.CPUThrottlingManager(); - /** @type {!Array} */ - this._currentViews = []; - this._viewModeSetting = Common.settings.createSetting('timelineViewMode', Timeline.TimelinePanel.ViewMode.FlameChart); @@ -108,11 +105,8 @@ Timeline.TimelinePanel = class extends UI.Panel { SDK.targetManager.addEventListener(SDK.TargetManager.Events.PageReloadRequested, this._pageReloadRequested, this); SDK.targetManager.addEventListener(SDK.TargetManager.Events.Load, this._loadEventFired, this); - this._stackView = new UI.StackView(false); - this._stackView.element.classList.add('timeline-view-stack'); - if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) { - const viewMode = Timeline.TimelinePanel.ViewMode; + var viewMode = Timeline.TimelinePanel.ViewMode; this._tabbedPane = new UI.TabbedPane(); this._tabbedPane.appendTab(viewMode.FlameChart, Common.UIString('Flame Chart'), new UI.VBox()); this._tabbedPane.appendTab(viewMode.BottomUp, Common.UIString('Bottom-Up'), new UI.VBox()); @@ -120,16 +114,6 @@ Timeline.TimelinePanel = class extends UI.Panel { this._tabbedPane.appendTab(viewMode.EventLog, Common.UIString('Event Log'), new UI.VBox()); this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._onMainViewChanged.bind(this)); this._tabbedPane.selectTab(this._viewModeSetting.get()); - } else { - // Create top level properties splitter. - this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState', 400); - this._detailsSplitWidget.element.classList.add('timeline-details-split'); - this._detailsView = new Timeline.TimelineDetailsView(this._filters, this); - this._detailsSplitWidget.installResizer(this._detailsView.headerElement()); - this._detailsSplitWidget.setSidebarWidget(this._detailsView); - this._detailsSplitWidget.setMainWidget(this._stackView); - this._detailsSplitWidget.hideSidebar(); - this._detailsSplitWidget.show(this._timelinePane.element); } this._onModeChanged(); @@ -179,9 +163,7 @@ Timeline.TimelinePanel = class extends UI.Panel { _onWindowChanged(event) { this._windowStartTime = event.data.startTime; this._windowEndTime = event.data.endTime; - - for (var i = 0; i < this._currentViews.length; ++i) - this._currentViews[i].setWindowTimes(this._windowStartTime, this._windowEndTime); + this._currentView.setWindowTimes(this._windowStartTime, this._windowEndTime); if (!this._selection || this._selection.type() === Timeline.TimelineSelection.Type.Range) this.select(null); @@ -209,27 +191,6 @@ Timeline.TimelinePanel = class extends UI.Panel { this._overviewPane.requestWindowTimes(windowStartTime, windowEndTime); } - /** - * @param {!Timeline.TimelineModeView} modeView - */ - _addModeView(modeView) { - modeView.setModel(this._performanceModel); - modeView.setWindowTimes(this._windowStartTime, this._windowEndTime); - var splitWidget = - this._stackView.appendView(modeView.view(), 'timelinePanelTimelineStackSplitViewState', undefined, 112); - var resizer = modeView.resizerElement(); - if (splitWidget && resizer) { - splitWidget.hideDefaultResizer(); - splitWidget.installResizer(resizer); - } - this._currentViews.push(modeView); - } - - _removeAllModeViews() { - this._currentViews = []; - this._stackView.detachChildWidgets(); - } - /** * @param {!Timeline.TimelinePanel.State} state */ @@ -432,8 +393,6 @@ Timeline.TimelinePanel = class extends UI.Panel { } _onModeChanged() { - const showMemory = this._showMemorySetting.get(); - const showScreenshots = this._showScreenshotsSetting.get(); // Set up overview controls. this._overviewControls = []; this._overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness()); @@ -442,31 +401,26 @@ Timeline.TimelinePanel = class extends UI.Panel { this._overviewControls.push(new Timeline.TimelineEventOverviewFrames()); this._overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity()); this._overviewControls.push(new Timeline.TimelineEventOverviewNetwork()); - if (showScreenshots) + if (this._showScreenshotsSetting.get()) this._overviewControls.push(new Timeline.TimelineFilmStripOverview()); - if (showMemory) + if (this._showMemorySetting.get()) this._overviewControls.push(new Timeline.TimelineEventOverviewMemory()); for (var control of this._overviewControls) control.setModel(this._performanceModel); this._overviewPane.setOverviewControls(this._overviewControls); - // Set up the main view. - this._removeAllModeViews(); - - var viewMode = Timeline.TimelinePanel.ViewMode.FlameChart; + // Set up main view. + if (this._currentView) + this._currentView.detach(); + var viewMode = Runtime.experiments.isEnabled('timelineMultipleMainViews') + ? this._tabbedPane.selectedTabId + : Timeline.TimelinePanel.ViewMode.FlameChart; this._flameChart = null; - if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) { - viewMode = this._tabbedPane.selectedTabId; - this._stackView.detach(); - this._stackView.show(this._tabbedPane.visibleView.element); - } var mainView; if (viewMode === Timeline.TimelinePanel.ViewMode.FlameChart) { this._flameChart = new Timeline.TimelineFlameChartView(this, this._filters); - this._addModeView(this._flameChart); - if (showMemory) - this._addModeView(new Timeline.CountersGraph(this)); mainView = this._flameChart; + this._currentView = this._flameChart; } else { switch (viewMode) { case Timeline.TimelinePanel.ViewMode.CallTree: @@ -480,15 +434,23 @@ Timeline.TimelinePanel = class extends UI.Panel { break; } var treeView = new Timeline.TimelineTreeModeView(this, mainView); - this._addModeView(treeView); + this._currentView = treeView; } + this._currentView.setModel(this._performanceModel); + this._currentView.setWindowTimes(this._windowStartTime, this._windowEndTime); if (this._searchableView) this._searchableView.detach(); this._searchableView = new UI.SearchableView(mainView); this._searchableView.setMinimumSize(0, 100); this._searchableView.element.classList.add('searchable-view'); this._searchableView.show(this._timelinePane.element); - this._tabbedPane.show(this._searchableView.element); + + if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) { + this._tabbedPane.show(this._searchableView.element); + this._currentView.show(this._tabbedPane.visibleView.element); + } else { + this._currentView.show(this._searchableView.element); + } mainView.setSearchableView(this._searchableView); if (this._lastViewMode !== viewMode) { this._lastViewMode = viewMode; @@ -540,12 +502,13 @@ Timeline.TimelinePanel = class extends UI.Panel { /** * @param {boolean} userInitiated + * @return {!Promise} */ _startRecording(userInitiated) { console.assert(!this._statusPane, 'Status pane is already opened.'); - var mainTarget = SDK.targetManager.mainTarget(); - if (!mainTarget) - return; + var tracingManagers = SDK.targetManager.models(SDK.TracingManager); + if (!tracingManagers.length) + return Promise.resolve(); this._setState(Timeline.TimelinePanel.State.StartPending); this._showRecordingStarted(); @@ -560,13 +523,13 @@ Timeline.TimelinePanel = class extends UI.Panel { }; this._pendingPerformanceModel = new Timeline.PerformanceModel(); - this._controller = new Timeline.TimelineController(mainTarget, this._pendingPerformanceModel, this); - this._controller.startRecording(recordingOptions, enabledTraceProviders); - + this._controller = new Timeline.TimelineController(tracingManagers[0], this._pendingPerformanceModel, this); Host.userMetrics.actionTaken( userInitiated ? Host.UserMetrics.Action.TimelineStarted : Host.UserMetrics.Action.TimelinePageReloadStarted); this._setUIControlsEnabled(false); this._hideLandingPage(); + return this._controller.startRecording(recordingOptions, enabledTraceProviders) + .then(() => this._recordingStarted()); } _stopRecording() { @@ -603,8 +566,6 @@ Timeline.TimelinePanel = class extends UI.Panel { _clear() { this._showLandingPage(); - if (this._detailsSplitWidget) - this._detailsSplitWidget.hideSidebar(); this._reset(); } @@ -621,7 +582,7 @@ Timeline.TimelinePanel = class extends UI.Panel { if (this._performanceModel) this._performanceModel.dispose(); this._performanceModel = model; - this._currentViews.forEach(view => view.setModel(this._performanceModel)); + this._currentView.setModel(model); this._overviewPane.reset(); if (model) { @@ -641,18 +602,13 @@ Timeline.TimelinePanel = class extends UI.Panel { this.requestWindowTimes(0, Infinity); } this._overviewPane.scheduleUpdate(); - if (this._detailsView) - this._detailsView.setModel(model); this.select(null); if (this._flameChart) this._flameChart.resizeToPreferredHeights(); } - /** - * @override - */ - recordingStarted() { + _recordingStarted() { this._reset(); this._setState(Timeline.TimelinePanel.State.Recording); this._showRecordingStarted(); @@ -687,7 +643,8 @@ Timeline.TimelinePanel = class extends UI.Panel { } var learnMoreNode = UI.createExternalLink( - 'https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/', Common.UIString('Learn\xa0more')); + 'https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/', + Common.UIString('Learn\xa0more')); var recordKey = encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording')[0].name); var reloadKey = encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('main.reload')[0].name); @@ -702,12 +659,12 @@ Timeline.TimelinePanel = class extends UI.Panel { centered.createChild('p').appendChild(UI.formatLocalized( 'Click the record button %s or hit %s to capture a new recording.\n' + - 'Click the reload button %s or hit %s to record and evaluate the page load.', + 'Click the reload button %s or hit %s to record and evaluate the page load.', [recordButton, recordKey, reloadButton, reloadKey])); centered.createChild('p').appendChild(UI.formatLocalized( 'After recording, select an area of interest in the overview by dragging.\n' + - 'Then, zoom and pan the timeline with the mousewheel or %s keys.\n%s', + 'Then, zoom and pan the timeline with the mousewheel or %s keys.\n%s', [navigateNode, learnMoreNode])); var cpuProfilerHintSetting = Common.settings.createSetting('timelineShowProfilerHint', true); @@ -791,9 +748,6 @@ Timeline.TimelinePanel = class extends UI.Panel { performanceModel.setTracingModel(tracingModel); this._backingStorage = backingStorage; this._setModel(performanceModel); - - if (this._detailsSplitWidget) - this._detailsSplitWidget.showBoth(); } _showRecordingStarted() { @@ -830,7 +784,9 @@ Timeline.TimelinePanel = class extends UI.Panel { _pageReloadRequested(event) { if (this._state !== Timeline.TimelinePanel.State.Idle || !this.isShowing()) return; - this._startRecording(false); + var resourceTreeModel = /** @type {!SDK.ResourceTreeModel} */ (event.data); + resourceTreeModel.suspendReload(); + this._startRecording(false).then(() => resourceTreeModel.resumeReload()); } /** @@ -897,12 +853,7 @@ Timeline.TimelinePanel = class extends UI.Panel { if (!selection) selection = Timeline.TimelineSelection.fromRange(this._windowStartTime, this._windowEndTime); this._selection = selection; - if (preferredTab && this._detailsView) - this._detailsView.setPreferredTab(preferredTab); - for (var view of this._currentViews) - view.setSelection(selection); - if (this._detailsView) - this._detailsView.setSelection(selection); + this._currentView.setSelection(selection); } /** @@ -930,8 +881,7 @@ Timeline.TimelinePanel = class extends UI.Panel { * @param {?SDK.TracingModel.Event} event */ highlightEvent(event) { - for (var view of this._currentViews) - view.highlightEvent(event); + this._currentView.highlightEvent(event); } /** diff --git a/front_end/ui/Icon.js b/front_end/ui/Icon.js index 0b3c08a161..928dafc953 100644 --- a/front_end/ui/Icon.js +++ b/front_end/ui/Icon.js @@ -95,6 +95,7 @@ UI.Icon.Descriptors = { 'smallicon-red-ball': {x: -120, y: 0, width: 10, height: 10, spritesheet: 'smallicons'}, 'smallicon-green-ball': {x: -140, y: 0, width: 10, height: 10, spritesheet: 'smallicons'}, 'smallicon-orange-ball': {x: -160, y: 0, width: 10, height: 10, spritesheet: 'smallicons'}, + 'smallicon-green-arrow': {x: -120, y: -20, width: 10, height: 10, spritesheet: 'smallicons'}, 'smallicon-thick-right-arrow': {x: -180, y: 0, width: 10, height: 10, spritesheet: 'smallicons'}, 'smallicon-thick-left-arrow': {x: -180, y: -20, width: 10, height: 10, spritesheet: 'smallicons'}, 'smallicon-user-command': {x: 0, y: -19, width: 10, height: 10, spritesheet: 'smallicons'}, diff --git a/front_end/ui/StackView.js b/front_end/ui/StackView.js deleted file mode 100644 index 3230919c85..0000000000 --- a/front_end/ui/StackView.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. - * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @unrestricted - */ -UI.StackView = class extends UI.VBox { - /** - * @param {boolean} isVertical - */ - constructor(isVertical) { - super(); - this._isVertical = isVertical; - this._currentSplitWidget = null; - } - - /** - * @param {!UI.Widget} view - * @param {string=} sidebarSizeSettingName - * @param {number=} defaultSidebarWidth - * @param {number=} defaultSidebarHeight - * @return {?UI.SplitWidget} - */ - appendView(view, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight) { - var splitWidget = - new UI.SplitWidget(this._isVertical, true, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight); - splitWidget.setMainWidget(view); - splitWidget.hideSidebar(); - - if (!this._currentSplitWidget) { - splitWidget.show(this.element); - } else { - this._currentSplitWidget.setSidebarWidget(splitWidget); - this._currentSplitWidget.showBoth(); - } - - var lastSplitWidget = this._currentSplitWidget; - this._currentSplitWidget = splitWidget; - return lastSplitWidget; - } - - /** - * @override - */ - detachChildWidgets() { - super.detachChildWidgets(); - this._currentSplitWidget = null; - } -}; diff --git a/front_end/ui/module.json b/front_end/ui/module.json index 8a498d94a2..3cb21152c9 100644 --- a/front_end/ui/module.json +++ b/front_end/ui/module.json @@ -40,7 +40,6 @@ "SettingsUI.js", "SoftContextMenu.js", "SplitWidget.js", - "StackView.js", "TextPrompt.js", "ThrottledWidget.js", "Toolbar.js", diff --git a/front_end/ui/tabbedPane.css b/front_end/ui/tabbedPane.css index b0f12569b0..467cbb2a34 100644 --- a/front_end/ui/tabbedPane.css +++ b/front_end/ui/tabbedPane.css @@ -50,6 +50,7 @@ text-align: center; margin-top: 20px; text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0; + white-space: pre; } .tabbed-pane-header { diff --git a/front_end/ui/textPrompt.css b/front_end/ui/textPrompt.css index 49d08cb890..76335a533c 100644 --- a/front_end/ui/textPrompt.css +++ b/front_end/ui/textPrompt.css @@ -45,7 +45,7 @@ color: rgb(128, 128, 128); } -::content .text-prompt:empty::after { +::content .text-prompt:not([data-placeholder]):empty::after { content: '\00A0'; width: 0; display: block; diff --git a/package.json b/package.json index 1e2519f136..e55dd255ac 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "debug-test": "node scripts/npm_test.js --debug-devtools", "compat-test": "node scripts/npm_test.js --compat-protocol=1.2", "lint": "eslint front_end", - "format": "node scripts/format.js", + "format": "git cl format --js .", "closure": "python scripts/compile_frontend.py", "setup-dtrun": "cd scripts/devtools_run && npm link", "format-py": "yapf --exclude scripts/build/rjsmin.py -i --recursive scripts PRESUBMIT.py" @@ -32,9 +32,6 @@ }, "homepage": "https://devtools.chrome.com", "devDependencies": { - "eslint": "3.10.0", - "clang-format": "1.0.45", - "async": "1.5.2", - "globby": "6.0.0" + "eslint": "3.10.0" } } diff --git a/scripts/build/generate_protocol_externs.py b/scripts/build/generate_protocol_externs.py index 09c7d3adba..a29f53e517 100755 --- a/scripts/build/generate_protocol_externs.py +++ b/scripts/build/generate_protocol_externs.py @@ -53,7 +53,8 @@ "Emulation", "HeapProfiler", "Profiler", - "LayerTree" + "LayerTree", + "Tracing" } # yapf: enable diff --git a/scripts/clang_format/index.js b/scripts/clang_format/index.js deleted file mode 100644 index 866bfe7c77..0000000000 --- a/scripts/clang_format/index.js +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var fs = require('fs'); -var os = require('os'); -var path = require('path'); -var spawn = require('child_process').spawn; -var globby = require('globby'); -var async = require('async'); - -var VERSION = '1.0.45'; -var LOCATION = __filename; -var CLANG_FORMAT_NODE_MODULES_PATH = path.resolve(__dirname, '..', '..', 'node_modules', 'clang-format'); - -/** - * Start a child process running the native clang-format binary. - * @param file a Vinyl virtual file reference - * @param enc the encoding to use for reading stdout - * @param style valid argument to clang-format's '-style' flag - * @param done callback invoked when the child process terminates - * @returns {Stream} the formatted code - */ -function clangFormat(file, enc, style, done) { - var args = ['-style=' + style, file.path]; - return spawnClangFormat(args, done, ['ignore', 'pipe', process.stderr]).stdout; -} - -/** - * Spawn the clang-format binary with given arguments. - */ -function spawnClangFormat(args, done, stdio) { - // WARNING: This function's interface should stay stable across versions for the cross-version - // loading below to work. - if (args.indexOf('-version') !== -1 || args.indexOf('--version') !== -1) { - // Print our version. - // This makes it impossible to format files called '-version' or '--version'. That's a feature. - // minimist & Co don't support single dash args, which we need to match binary clang-format. - console.log('clang-format NPM version', VERSION, 'at', LOCATION); - process.exit(0); - } - var nativeBinary; - if (os.platform() === 'win32') - nativeBinary = CLANG_FORMAT_NODE_MODULES_PATH + '/bin/win32/clang-format.exe'; - else - nativeBinary = CLANG_FORMAT_NODE_MODULES_PATH + '/bin/' + os.platform() + '_' + os.arch() + '/clang-format'; - - if (!fs.existsSync(nativeBinary)) { - message = 'FATAL: This module doesn\'t bundle the clang-format executable for your platform. ' + - '(' + os.platform() + '_' + os.arch() + ')\n' + - 'Consider installing it with your native package manager instead.\n'; - throw new Error(message); - } - - // extract glob, if present - var globString = args.filter(function(arg) { - return arg.indexOf('--glob=') === 0; - }) - .map(function(arg) { - return arg.replace('--glob=', ''); - }) - .shift(); - - // extract ignore, if present - var ignore = args.filter(function(arg) { - return arg.indexOf('--ignore=') === 0; - }) - .map(function(arg) { - return arg.replace('--ignore=', ''); - }) - .shift(); - - if (globString) { - var globs = globString.split(','); - // remove glob and ignore from arg list - args = args.filter(function(arg) { - return arg.indexOf('--glob=') === -1; - }) - .filter(function(arg) { - return arg.indexOf('--ignore=') === -1; - }); - - var options = {}; - if (ignore) - options.ignore = ignore.split(','); - - - return globby(globs, options).then(function(files) { - // split file array into chunks of 30 - var i, j, chunks = [], chunkSize = 30; - for (i = 0, j = files.length; i < j; i += chunkSize) - chunks.push(files.slice(i, i + chunkSize)); - - - // launch a new process for each chunk - async.series( - chunks.map(function(chunk) { - return function(callback) { - var clangFormatProcess = spawn(nativeBinary, args.concat(chunk), {stdio: stdio}); - clangFormatProcess.on('close', function(exit) { - if (exit !== 0) - callback(exit); - else - callback(null, exit); - }); - }; - }), - function(err, results) { - if (err) - done(err); - console.log('\n'); - console.log('ran clang-format on', files.length, files.length === 1 ? 'file' : 'files'); - done(results.shift() || 0); - }); - }); - } else { - var clangFormatProcess = spawn(nativeBinary, args, {stdio: stdio}); - clangFormatProcess.on('close', function(exit) { - if (exit) - done(exit); - }); - return clangFormatProcess; - } -} - -function main() { - try { - // Pass all arguments to clang-format, including e.g. -version etc. - spawnClangFormat(process.argv.slice(2), process.exit, 'inherit'); - } catch (e) { - process.stdout.write(e.message); - process.exit(1); - } -} - -module.exports = clangFormat; -module.exports.version = VERSION; -module.exports.location = LOCATION; -module.exports.spawnClangFormat = spawnClangFormat; - -if (require.main === module) - main(); diff --git a/scripts/format.js b/scripts/format.js deleted file mode 100644 index 449d10e356..0000000000 --- a/scripts/format.js +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -var childProcess = require('child_process'); -var fs = require('fs'); -var path = require('path'); - -var args = process.argv.slice(2); - -var CLANG_FORMAT_PATH = path.resolve(__dirname, 'clang_format', 'index.js'); -var IGNORE_FILE_PATH = path.resolve(__dirname, '..', '.eslintignore'); - -var ignoreFile = fs.readFileSync(IGNORE_FILE_PATH, 'utf-8'); -var ignores = ignoreFile.split('\n').filter(str => str.length); -var ignoreArg = '--ignore=' + ignores.join(','); - -console.log('Running clang-format'); -var clangArgs = ['-i', ignoreArg]; -if (args.length) - clangArgs = clangArgs.concat(args); -else - clangArgs.push('--glob=+(scripts|front_end)/**/*.js'); - - -var options = {cwd: path.resolve(__dirname, '..')}; - -childProcess.fork(CLANG_FORMAT_PATH, clangArgs, options);