From 5d1141ceae046a5e87839c697b8951714ee567bf Mon Sep 17 00:00:00 2001 From: Antonin Hildebrand Date: Thu, 5 May 2016 00:46:29 +0200 Subject: [PATCH] squash 'resources/unpacked/devtools' changes from 064127e..4150aff 4150aff DevTools: [SASS] start parsing CSS with SCSS parser 51b0ebb DevTools: [SASS] parse SCSS rules and their selectors. 292d4f9 Revert of DevTools: fix focus restoration from command menu (patchset #4 id:60001 of https://codereview.chromium.org/1922303004/ ) d79bed2 DevTools: fix styles in rendering pane d21c547 DevTools: properly update close icon in search field dab74b9 DevTools: Reorder timeline checkboxes. 05809f9 DevTools: mute the node highlight & hide devtools while taking screenshots. a3b8435 Security panel: add listeners only to the added target. f4f510c [DevTools] 20px default top inset gutter to avoid Ruler overlap in emulation mode f2b80ce Fix issue causing no cookies to be shown in the Resources > Cookies panel. 78782d0 Revert of Fixed DevTools event-listener breakpoints for PointerEvents. (patchset #3 id:40001 of https://codereview.chromium.org/1915623002/ ) 0af8110 Timeline: use RAIL phases to color input events 8939357 DevTools: fix user agent custom behavior 9f84e26 DevTools: fix focus restoration from command menu 68642cb [Devtools] isTrusted in CustomEvents shown twice in console 4a00752 DevTools: brush up command menu looks, render badges. 81dfcdf DevTools: fix visual regressions in full text search d329629 [Devtools] Fix to XMLView in Network Preview panel broken 42f1d67 DevTools: Move network pane on timeline out of experiment 0e0cd5c Fixed DevTools event-listener breakpoints for PointerEvents. 3a717ab [DevTools] Add base JS Proxy support git-subtree-dir: resources/unpacked/devtools git-subtree-split: 4150affb121bfe1c9d0de69bef681e515be1cee9 --- front_end/console/ConsoleViewMessage.js | 9 +- front_end/console/consoleView.css | 25 +++- front_end/emulation/AdvancedApp.js | 1 + front_end/emulation/DeviceModeModel.js | 6 +- front_end/emulation/DeviceModeView.js | 18 ++- front_end/gonzales/SCSSParser.js | 117 ++++++++++++------- front_end/main/Main.js | 1 - front_end/main/renderingOptions.css | 12 -- front_end/network/NetworkConfigView.js | 8 +- front_end/network/RequestPreviewView.js | 6 +- front_end/resources/CookieItemsView.js | 2 +- front_end/sass/ASTService.js | 2 +- front_end/sass/SASSSupport.js | 63 +++------- front_end/sdk/DOMModel.js | 15 +++ front_end/sdk/RemoteObject.js | 20 +++- front_end/security/SecurityPanel.js | 24 ++-- front_end/sources/AdvancedSearchView.js | 4 +- front_end/sources/JavaScriptOutlineDialog.js | 2 +- front_end/sources/OpenResourceDialog.js | 22 +++- front_end/sources/StyleSheetOutlineDialog.js | 2 +- front_end/sources/sourcesSearch.css | 8 +- front_end/timeline/TimelineFlameChart.js | 50 ++++---- front_end/timeline/TimelineIRModel.js | 62 +++++++++- front_end/timeline/TimelinePanel.js | 35 +++--- front_end/timeline/TimelineUIUtils.js | 3 +- front_end/ui/Dialog.js | 28 ++++- front_end/ui/InspectorView.js | 20 ++++ front_end/ui/checkboxTextLabel.css | 4 + front_end/ui/inspectorCommon.css | 2 +- front_end/ui_lazy/CommandMenu.js | 46 ++++++-- front_end/ui_lazy/FilteredListWidget.js | 29 ++++- front_end/ui_lazy/FlameChart.js | 63 ++++++---- front_end/ui_lazy/filteredListWidget.css | 20 +++- 33 files changed, 499 insertions(+), 230 deletions(-) diff --git a/front_end/console/ConsoleViewMessage.js b/front_end/console/ConsoleViewMessage.js index 052c07272f..a5ee48bc32 100644 --- a/front_end/console/ConsoleViewMessage.js +++ b/front_end/console/ConsoleViewMessage.js @@ -56,6 +56,7 @@ WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLev "map": this._formatParameterAsObject, "node": this._formatParameterAsNode, "object": this._formatParameterAsObject, + "proxy": this._formatParameterAsObject, "set": this._formatParameterAsObject, "string": this._formatParameterAsString }; @@ -424,7 +425,13 @@ WebInspector.ConsoleViewMessage.prototype = { titleElement.createTextChild(obj.description || ""); } } - var note = titleElement.createChild("span", "object-info-state-note"); + if (obj.subtype === "proxy") { + var warning = titleElement.createChild("span", "object-state-note"); + warning.classList.add("warning-note"); + warning.title = WebInspector.UIString("Expansion of the Proxy object can lead to JavaScript execution."); + } + var note = titleElement.createChild("span", "object-state-note"); + note.classList.add("info-note"); note.title = WebInspector.UIString("Object value at left was snapshotted when logged, value below was evaluated just now."); var section = new WebInspector.ObjectPropertiesSection(obj, titleElement); section.enableContextMenu(); diff --git a/front_end/console/consoleView.css b/front_end/console/consoleView.css index 773921b7c7..b37f0a618f 100644 --- a/front_end/console/consoleView.css +++ b/front_end/console/consoleView.css @@ -425,11 +425,10 @@ white-space: nowrap !important; } -.object-info-state-note { +.object-state-note { display: inline-block; width: 11px; height: 11px; - background-color: rgb(179, 203, 247); color: white; text-align: center; border-radius: 3px; @@ -438,14 +437,30 @@ font-size: 9px; } -.-theme-with-dark-background .object-info-state-note { +.-theme-with-dark-background .object-state-note { background-color: hsl(230, 100%, 80%); } -.object-info-state-note::before { +.info-note { + background-color: rgb(179, 203, 247); +} + +.info-note::before { content: "i"; } -.console-view-object-properties-section:not(.expanded) .object-info-state-note { +.warning-note { + background-color: rgb(255, 161, 45); +} + +.warning-note::before { + content: "!"; +} + +.console-view-object-properties-section:not(.expanded) .info-note { + display: none; +} + +.console-view-object-properties-section.expanded .warning-note { display: none; } diff --git a/front_end/emulation/AdvancedApp.js b/front_end/emulation/AdvancedApp.js index 1b30aa8f69..26c3302ae2 100644 --- a/front_end/emulation/AdvancedApp.js +++ b/front_end/emulation/AdvancedApp.js @@ -24,6 +24,7 @@ WebInspector.AdvancedApp.prototype = { this._rootSplitWidget.show(rootView.element); this._rootSplitWidget.setSidebarWidget(WebInspector.inspectorView); + WebInspector.inspectorView.setOwnerSplit(this._rootSplitWidget); this._inspectedPagePlaceholder = new WebInspector.InspectedPagePlaceholder(); this._inspectedPagePlaceholder.addEventListener(WebInspector.InspectedPagePlaceholder.Events.Update, this._onSetInspectedPageBounds.bind(this), this); diff --git a/front_end/emulation/DeviceModeModel.js b/front_end/emulation/DeviceModeModel.js index 946ee71a6d..4b297da3eb 100644 --- a/front_end/emulation/DeviceModeModel.js +++ b/front_end/emulation/DeviceModeModel.js @@ -434,7 +434,7 @@ WebInspector.DeviceModeModel.prototype = { if (this._type === WebInspector.DeviceModeModel.Type.Device) { var orientation = this._device.orientationByName(this._mode.orientation); - var outline = new Insets(0, 0, 0, 0); + var outline = new Insets(0, 20, 0, 0); if (Runtime.experiments.isEnabled("deviceFrames") && this._deviceOutlineSetting.get()) outline = orientation.outlineInsets || outline; this._fitScale = this._calculateFitScale(orientation.width, orientation.height); @@ -448,7 +448,7 @@ WebInspector.DeviceModeModel.prototype = { } else if (this._type === WebInspector.DeviceModeModel.Type.None) { this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height); this._appliedUserAgentType = WebInspector.DeviceModeModel.UA.Desktop; - this._applyDeviceMetrics(this._availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, false, "", resetPageScaleFactor); + this._applyDeviceMetrics(this._availableSize, new Insets(0, 0, 0, 0), new Insets(0, 20, 0, 0), 1, 0, false, "", resetPageScaleFactor); this._applyUserAgent(""); this._applyTouch(false, false); } else if (this._type === WebInspector.DeviceModeModel.Type.Responsive) { @@ -462,7 +462,7 @@ WebInspector.DeviceModeModel.prototype = { var defaultDeviceScaleFactor = mobile ? WebInspector.DeviceModeModel.defaultMobileScaleFactor : 0; this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._heightSetting.get()); this._appliedUserAgentType = this._uaSetting.get(); - this._applyDeviceMetrics(new Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= screenWidth ? "portraitPrimary" : "landscapePrimary", resetPageScaleFactor); + this._applyDeviceMetrics(new Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 20, 0, 0), this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= screenWidth ? "portraitPrimary" : "landscapePrimary", resetPageScaleFactor); this._applyUserAgent(mobile ? WebInspector.DeviceModeModel._defaultMobileUserAgent : ""); this._applyTouch(this._uaSetting.get() === WebInspector.DeviceModeModel.UA.DesktopTouch || this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile, this._uaSetting.get() === WebInspector.DeviceModeModel.UA.Mobile); } diff --git a/front_end/emulation/DeviceModeView.js b/front_end/emulation/DeviceModeView.js index 47ce70d66b..c4447ec2a4 100644 --- a/front_end/emulation/DeviceModeView.js +++ b/front_end/emulation/DeviceModeView.js @@ -380,6 +380,17 @@ WebInspector.DeviceModeView.prototype = { var mainTarget = WebInspector.targetManager.mainTarget(); if (!mainTarget) return; + WebInspector.DOMModel.muteHighlight(); + + var zoomFactor = WebInspector.zoomManager.zoomFactor(); + var rect = this._contentArea.getBoundingClientRect(); + var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1)); + + if (availableSize.width < this._model.screenRect().width || + availableSize.height < this._model.screenRect().height) { + WebInspector.inspectorView.minimize(); + } + mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this)); /** @@ -389,8 +400,11 @@ WebInspector.DeviceModeView.prototype = { */ function screenshotCaptured(error, content) { - if (error) + if (error) { + WebInspector.DOMModel.unmuteHighlight(); + WebInspector.inspectorView.restore(); return; + } // Create a canvas to splice the images together. var canvas = createElement("canvas"); @@ -441,6 +455,8 @@ WebInspector.DeviceModeView.prototype = { link.download = fileName + ".png"; link.href = canvas.toDataURL("image/png"); link.click(); + WebInspector.DOMModel.unmuteHighlight(); + WebInspector.inspectorView.restore(); } } }, diff --git a/front_end/gonzales/SCSSParser.js b/front_end/gonzales/SCSSParser.js index 04cd9eb82e..2b04317e6c 100644 --- a/front_end/gonzales/SCSSParser.js +++ b/front_end/gonzales/SCSSParser.js @@ -10,51 +10,67 @@ WebInspector.SCSSParser = function() { } -/** - * @constructor - */ -WebInspector.SCSSParser.Result = function() -{ - this.properties = []; - this.variables = []; - this.mixins = []; -} - WebInspector.SCSSParser.prototype = { /** * @override * @param {string} content - * @return {!WebInspector.SCSSParser.Result} + * @return {!Array} */ parse: function(content) { - var result = new WebInspector.SCSSParser.Result(); var ast = null; try { ast = gonzales.parse(content, {syntax: "scss"}); } catch (e) { - return result; + return []; } - var extractedNodes = []; - WebInspector.SCSSParser.extractNodes(ast, extractedNodes); + /** @type {!{properties: !Array, node: !Gonzales.Node}} */ + var rootBlock = { + properties: [], + node: ast + }; + /** @type {!Array, node: !Gonzales.Node}>} */ + var blocks = [rootBlock]; + ast.selectors = []; + WebInspector.SCSSParser.extractNodes(ast, blocks, rootBlock); + + var rules = []; + for (var block of blocks) + this._handleBlock(block, rules); + return rules; + }, - for (var node of extractedNodes) { + /** + * @param {!{node: !Gonzales.Node, properties: !Array}} block + * @param {!Array} output + */ + _handleBlock: function(block, output) + { + var selectors = block.node.selectors.map(WebInspector.SCSSParser.rangeFromNode); + var properties = []; + var styleRange = WebInspector.SCSSParser.rangeFromNode(block.node); + styleRange.startColumn += 1; + styleRange.endColumn -= 1; + for (var node of block.properties) { if (node.type === "declaration") - this._handleDeclaration(node, result); + this._handleDeclaration(node, properties); else if (node.type === "include") - this._handleInclude(node, result); + this._handleInclude(node, properties); else if (node.type === "multilineComment" && node.start.line === node.end.line) - this._handleComment(node, result); + this._handleComment(node, properties); } - return result; + if (!selectors.length && !properties.length) + return; + var rule = new WebInspector.SCSSParser.Rule(selectors, properties, styleRange); + output.push(rule); }, /** * @param {!Gonzales.Node} node - * @param {!WebInspector.SCSSParser.Result} result + * @param {!Array} output */ - _handleDeclaration: function(node, result) + _handleDeclaration: function(node, output) { var propertyNode = node.content.find(node => node.type === "property"); var delimeterNode = node.content.find(node => node.type === "propertyDelimiter"); @@ -67,18 +83,14 @@ WebInspector.SCSSParser.prototype = { var range = /** @type {!WebInspector.TextRange} */(node.declarationRange); var property = new WebInspector.SCSSParser.Property(range, nameRange, valueRange, false); - var isVariable = !!propertyNode.content.find(node => node.type === "variable"); - if (isVariable) - result.variables.push(property); - else - result.properties.push(property); + output.push(property); }, /** * @param {!Gonzales.Node} node - * @param {!WebInspector.SCSSParser.Result} result + * @param {!Array} output */ - _handleInclude: function(node, result) + _handleInclude: function(node, output) { var mixinName = node.content.find(node => node.type === "ident"); if (!mixinName) @@ -92,25 +104,25 @@ WebInspector.SCSSParser.prototype = { var range = WebInspector.SCSSParser.rangeFromNode(node); var valueRange = WebInspector.SCSSParser.rangeFromNode(parameter); var property = new WebInspector.SCSSParser.Property(range, nameRange, valueRange, false); - result.mixins.push(property); + output.push(property); } }, /** * @param {!Gonzales.Node} node - * @param {!WebInspector.SCSSParser.Result} result + * @param {!Array} output */ - _handleComment: function(node, result) + _handleComment: function(node, output) { if (node.start.line !== node.end.line) return; var innerText = /** @type {string} */(node.content); var innerResult = this.parse(innerText); - if (innerResult.properties.length !== 1 || innerResult.variables.length !== 0 || innerResult.mixins.length !== 0) + if (innerResult.length !== 1 || innerResult[0].properties.length !== 1) return; - var property = innerResult.properties[0]; + var property = innerResult[0].properties[0]; var disabledProperty = property.rebaseInsideOneLineComment(node); - result.properties.push(disabledProperty); + output.push(disabledProperty); }, } @@ -166,29 +178,56 @@ WebInspector.SCSSParser.Property.prototype = { } } +/** + * @constructor + * @param {!Array} selectors + * @param {!Array} properties + * @param {!WebInspector.TextRange} styleRange + */ +WebInspector.SCSSParser.Rule = function(selectors, properties, styleRange) +{ + this.selectors = selectors; + this.properties = properties; + this.styleRange = styleRange; +} + /** * @param {!Gonzales.Node} node - * @param {!Array} output + * @param {!Array<{node: !Gonzales.Node, properties: !Array}>} blocks + * @param {!{node: !Gonzales.Node, properties: !Array}} lastBlock */ -WebInspector.SCSSParser.extractNodes = function(node, output) +WebInspector.SCSSParser.extractNodes = function(node, blocks, lastBlock) { if (!Array.isArray(node.content)) return; + if (node.type === "block") { + lastBlock = { + node: node, + properties: [] + }; + blocks.push(lastBlock); + } var lastDeclaration = null; + var selectors = []; for (var i = 0; i < node.content.length; ++i) { var child = node.content[i]; if (child.type === "declarationDelimiter" && lastDeclaration) { lastDeclaration.declarationRange.endLine = child.end.line - 1; lastDeclaration.declarationRange.endColumn = child.end.column; lastDeclaration = null; + } else if (child.type === "selector") { + selectors.push(child); + } else if (child.type === "block") { + child.selectors = selectors; + selectors = []; } if (child.type === "include" || child.type === "declaration" || child.type === "multilineComment") - output.push(child); + lastBlock.properties.push(child); if (child.type === "declaration") { lastDeclaration = child; lastDeclaration.declarationRange = WebInspector.TextRange.createFromLocation(child.start.line - 1, child.start.column - 1); } - WebInspector.SCSSParser.extractNodes(child, output); + WebInspector.SCSSParser.extractNodes(child, blocks, lastBlock); } if (lastDeclaration) { lastDeclaration.declarationRange.endLine = node.end.line - 1; diff --git a/front_end/main/Main.js b/front_end/main/Main.js index 711852f572..d012c5ab92 100644 --- a/front_end/main/Main.js +++ b/front_end/main/Main.js @@ -113,7 +113,6 @@ WebInspector.Main.prototype = { Runtime.experiments.register("layoutEditor", "Layout editor", true); Runtime.experiments.register("inspectTooltip", "Dark inspect element tooltip"); Runtime.experiments.register("liveSASS", "Live SASS", true); - Runtime.experiments.register("networkRequestsOnTimeline", "Network requests on Timeline", true); Runtime.experiments.register("privateScriptInspection", "Private script inspection"); Runtime.experiments.register("reducedIndentation", "Reduced indentation in Elements DOM tree"); Runtime.experiments.register("requestBlocking", "Request blocking", true); diff --git a/front_end/main/renderingOptions.css b/front_end/main/renderingOptions.css index 019ddf0bd0..bb269e5214 100644 --- a/front_end/main/renderingOptions.css +++ b/front_end/main/renderingOptions.css @@ -22,15 +22,3 @@ label { margin-bottom: 10px; background: #f0f0f0; } - -.dt-checkbox-text { - color: #262626; - font-size: 12px; - margin-left: 6px; -} - -.dt-checkbox-subtitle { - color: #4a4a4a; - font-size: 10px; - margin-top: 2px; -} diff --git a/front_end/network/NetworkConfigView.js b/front_end/network/NetworkConfigView.js index 4542502e47..cf8604acd7 100644 --- a/front_end/network/NetworkConfigView.js +++ b/front_end/network/NetworkConfigView.js @@ -126,7 +126,7 @@ WebInspector.NetworkConfigView.createUserAgentSelectAndInput = function() otherUserAgentElement.value = value; otherUserAgentElement.title = value; } else { - otherUserAgentElement.focus(); + otherUserAgentElement.select(); } } @@ -145,17 +145,13 @@ WebInspector.NetworkConfigView.createUserAgentSelectAndInput = function() if (!selectionRestored) userAgentSelectElement.selectedIndex = 0; - - if (otherUserAgentElement.value !== value) { - otherUserAgentElement.value = value; - otherUserAgentElement.title = value; - } } function textChanged() { if (userAgentSetting.get() !== otherUserAgentElement.value) { userAgentSetting.set(otherUserAgentElement.value); + otherUserAgentElement.title = otherUserAgentElement.value; settingChanged(); } } diff --git a/front_end/network/RequestPreviewView.js b/front_end/network/RequestPreviewView.js index c09084858f..5c77d9ee6a 100644 --- a/front_end/network/RequestPreviewView.js +++ b/front_end/network/RequestPreviewView.js @@ -148,8 +148,10 @@ WebInspector.RequestPreviewView.prototype = { } var xmlView = this._xmlView(); - if (xmlView) - return xmlView; + if (xmlView) { + callback(xmlView); + return; + } WebInspector.JSONView.parseJSON(this._requestContent()).then(chooseView.bind(this)).then(callback); diff --git a/front_end/resources/CookieItemsView.js b/front_end/resources/CookieItemsView.js index 96df23c5b8..980e14a81f 100644 --- a/front_end/resources/CookieItemsView.js +++ b/front_end/resources/CookieItemsView.js @@ -125,7 +125,7 @@ WebInspector.CookieItemsView.prototype = { function populateResourcesForDocuments(resource) { var url = resource.documentURL.asParsedURL(); - if (url && url.host == this._cookieDomain) + if (url && url.securityOrigin() == this._cookieDomain) resourceURLsForDocumentURL.push(resource.url); } WebInspector.forAllResources(populateResourcesForDocuments.bind(this)); diff --git a/front_end/sass/ASTService.js b/front_end/sass/ASTService.js index c780338050..b8f6724b13 100644 --- a/front_end/sass/ASTService.js +++ b/front_end/sass/ASTService.js @@ -17,7 +17,7 @@ WebInspector.ASTService.prototype = { */ parseCSS: function(url, text) { - return WebInspector.SASSSupport.parseCSS(url, text); + return WebInspector.SASSSupport.parseSCSS(url, text); }, /** diff --git a/front_end/sass/SASSSupport.js b/front_end/sass/SASSSupport.js index 07a53fe661..684965faff 100644 --- a/front_end/sass/SASSSupport.js +++ b/front_end/sass/SASSSupport.js @@ -4,43 +4,6 @@ WebInspector.SASSSupport = {} -/** - * @param {string} url - * @param {string} text - * @return {!Promise} - */ -WebInspector.SASSSupport.parseCSS = function(url, text) -{ - var cssParser = new WebInspector.CSSParser(); - return cssParser.parsePromise(text) - .then(onParsed); - - /** - * @param {!Array.} parsedCSS - * @return {!WebInspector.SASSSupport.AST} - */ - function onParsed(parsedCSS) - { - var document = new WebInspector.SASSSupport.ASTDocument(url, new WebInspector.Text(text)); - var rules = []; - for (var i = 0; i < parsedCSS.length; ++i) { - var rule = parsedCSS[i]; - if (!rule.properties) - continue; - var properties = []; - for (var j = 0; j < rule.properties.length; ++j) { - var cssProperty = rule.properties[j]; - var name = new WebInspector.SASSSupport.TextNode(document, cssProperty.name, WebInspector.TextRange.fromObject(cssProperty.nameRange)); - var value = new WebInspector.SASSSupport.TextNode(document, cssProperty.value, WebInspector.TextRange.fromObject(cssProperty.valueRange)); - var property = new WebInspector.SASSSupport.Property(document, name, value, WebInspector.TextRange.fromObject(cssProperty.range), !!cssProperty.disabled); - properties.push(property); - } - rules.push(new WebInspector.SASSSupport.Rule(document, rule.selectorText, WebInspector.TextRange.fromObject(rule.styleRange), properties)); - } - return new WebInspector.SASSSupport.AST(document, rules); - } -} - /** * @param {string} url * @param {string} content @@ -61,16 +24,22 @@ WebInspector.SASSSupport.parseSCSS = function(url, content) { if (!event) return new WebInspector.SASSSupport.AST(document, []); - var data = /** @type {!{properties: !Array, variables: !Array, mixins: !Array}} */(event.data); - var properties = data.properties.map(createProperty); - var variables = data.variables.map(createProperty); - var mixins = data.mixins.map(createProperty); - var rules = [ - new WebInspector.SASSSupport.Rule(document, "variables", WebInspector.TextRange.createFromLocation(0, 0), variables), - new WebInspector.SASSSupport.Rule(document, "properties", WebInspector.TextRange.createFromLocation(0, 0), properties), - new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.TextRange.createFromLocation(0, 0), mixins) - ]; - + var data = /** @type {!Array} */(event.data); + var rules = []; + for (var i = 0; i < data.length; ++i) { + var rulePayload = data[i]; + var selectorText = ""; + if (rulePayload.selectors.length) { + var first = rulePayload.selectors[0]; + var last = rulePayload.selectors.peekLast(); + var selectorRange = new WebInspector.TextRange(first.startLine, first.startColumn, last.endLine, last.endColumn); + selectorText = text.extract(selectorRange); + } + var properties = rulePayload.properties.map(createProperty); + var range = WebInspector.TextRange.fromObject(rulePayload.styleRange); + var rule = new WebInspector.SASSSupport.Rule(document, selectorText, range, properties); + rules.push(rule); + } return new WebInspector.SASSSupport.AST(document, rules); } diff --git a/front_end/sdk/DOMModel.js b/front_end/sdk/DOMModel.js index 840766e560..919c1d9e38 100644 --- a/front_end/sdk/DOMModel.js +++ b/front_end/sdk/DOMModel.js @@ -1135,6 +1135,17 @@ WebInspector.DOMModel.hideDOMNodeHighlight = function() domModel.highlightDOMNode(0); } +WebInspector.DOMModel.muteHighlight = function() +{ + WebInspector.DOMModel.hideDOMNodeHighlight(); + WebInspector.DOMModel._highlightDisabled = true; +} + +WebInspector.DOMModel.unmuteHighlight = function() +{ + WebInspector.DOMModel._highlightDisabled = false; +} + WebInspector.DOMModel.cancelSearch = function() { for (var domModel of WebInspector.DOMModel.instances()) @@ -1737,6 +1748,8 @@ WebInspector.DOMModel.prototype = { */ highlightDOMNodeWithConfig: function(nodeId, config, backendNodeId, objectId) { + if (WebInspector.DOMModel._highlightDisabled) + return; config = config || { mode: "all", showInfo: undefined, selectors: undefined }; if (this._hideDOMNodeHighlightTimeout) { clearTimeout(this._hideDOMNodeHighlightTimeout); @@ -1764,6 +1777,8 @@ WebInspector.DOMModel.prototype = { */ highlightFrame: function(frameId) { + if (WebInspector.DOMModel._highlightDisabled) + return; this._highlighter.highlightFrame(frameId); }, diff --git a/front_end/sdk/RemoteObject.js b/front_end/sdk/RemoteObject.js index bba2c6e5f6..905d050a99 100644 --- a/front_end/sdk/RemoteObject.js +++ b/front_end/sdk/RemoteObject.js @@ -978,13 +978,25 @@ WebInspector.RemoteObject.loadFromObjectPerProto = function(object, callback) if (--resultCounter) return; if (savedOwnProperties && savedAccessorProperties) { - var combinedList = savedAccessorProperties.slice(0); + var propertiesMap = new Map(); + var propertySymbols = []; + for (var i = 0; i < savedAccessorProperties.length; i++) { + var property = savedAccessorProperties[i]; + if (property.symbol) + propertySymbols.push(property); + else + propertiesMap.set(property.name, property); + } for (var i = 0; i < savedOwnProperties.length; i++) { var property = savedOwnProperties[i]; - if (!property.isAccessorProperty()) - combinedList.push(property); + if (property.isAccessorProperty()) + continue; + if (property.symbol) + propertySymbols.push(property); + else + propertiesMap.set(property.name, property); } - return callback(combinedList, savedInternalProperties ? savedInternalProperties : null); + return callback(propertiesMap.valuesArray().concat(propertySymbols), savedInternalProperties ? savedInternalProperties : null); } else { callback(null, null); } diff --git a/front_end/security/SecurityPanel.js b/front_end/security/SecurityPanel.js index 88ac526a25..fc199619bf 100644 --- a/front_end/security/SecurityPanel.js +++ b/front_end/security/SecurityPanel.js @@ -23,16 +23,11 @@ WebInspector.SecurityPanel = function() /** @type {!Map} */ this._origins = new Map(); - WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this); /** @type {!Map} */ this._filterRequestCounts = new Map(); WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page); - - WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.ResponseReceived, this._onResponseReceived, this); - WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this); - WebInspector.targetManager.addModelListener(WebInspector.SecurityModel, WebInspector.SecurityModel.EventTypes.SecurityStateChanged, this._onSecurityStateChanged, this); } /** @typedef {string} */ @@ -248,7 +243,17 @@ WebInspector.SecurityPanel.prototype = { */ targetAdded: function(target) { - WebInspector.SecurityModel.fromTarget(target); + if (this._target) + return; + + this._target = target; + + target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this); + target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResponseReceived, this._onResponseReceived, this); + target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this); + + var securityModel = WebInspector.SecurityModel.fromTarget(target); + securityModel.addEventListener(WebInspector.SecurityModel.EventTypes.SecurityStateChanged, this._onSecurityStateChanged, this); }, /** @@ -277,11 +282,12 @@ WebInspector.SecurityPanel.prototype = { var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId); this._clearOrigins(); - var origin = WebInspector.ParsedURL.splitURLIntoPathComponents(request.url)[0]; - this._sidebarTree.setMainOrigin(origin); - if (request) + if (request) { + var origin = WebInspector.ParsedURL.splitURLIntoPathComponents(request.url)[0]; + this._sidebarTree.setMainOrigin(origin); this._processRequest(request); + } }, __proto__: WebInspector.PanelWithSidebar.prototype diff --git a/front_end/sources/AdvancedSearchView.js b/front_end/sources/AdvancedSearchView.js index 6cc960fd29..b311cb64f6 100644 --- a/front_end/sources/AdvancedSearchView.js +++ b/front_end/sources/AdvancedSearchView.js @@ -18,7 +18,7 @@ WebInspector.AdvancedSearchView = function() this._searchPanelElement = this.contentElement.createChild("div", "search-drawer-header"); this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false); - this._searchPanelElement.addEventListener("keyup", this._onKeyUp.bind(this), false); + this._searchPanelElement.addEventListener("input", this._onInput.bind(this), false); this._searchResultsElement = this.contentElement.createChild("div"); this._searchResultsElement.className = "search-results"; @@ -296,7 +296,7 @@ WebInspector.AdvancedSearchView.prototype = { } }, - _onKeyUp: function() + _onInput: function() { if (this._search.value && this._search.value.length) this._searchInputClearElement.hidden = false; diff --git a/front_end/sources/JavaScriptOutlineDialog.js b/front_end/sources/JavaScriptOutlineDialog.js index f431c29fef..ab25ee9ef0 100644 --- a/front_end/sources/JavaScriptOutlineDialog.js +++ b/front_end/sources/JavaScriptOutlineDialog.js @@ -25,7 +25,7 @@ WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback */ WebInspector.JavaScriptOutlineDialog.show = function(uiSourceCode, selectItemCallback) { - new WebInspector.FilteredListWidget(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback), false).showAsDialog(); + new WebInspector.FilteredListWidget(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback)).showAsDialog(); } WebInspector.JavaScriptOutlineDialog.prototype = { diff --git a/front_end/sources/OpenResourceDialog.js b/front_end/sources/OpenResourceDialog.js index fb136b0ef9..600f6a01fe 100644 --- a/front_end/sources/OpenResourceDialog.js +++ b/front_end/sources/OpenResourceDialog.js @@ -54,6 +54,15 @@ WebInspector.OpenResourceDialog.prototype = { return !WebInspector.Project.isServiceProject(project); }, + /** + * @override + * @return {boolean} + */ + renderAsTwoRows: function() + { + return true; + }, + __proto__: WebInspector.FilteredUISourceCodeListDelegate.prototype } @@ -65,7 +74,7 @@ WebInspector.OpenResourceDialog.prototype = { */ WebInspector.OpenResourceDialog.show = function(sourcesView, query, defaultScores, history) { - var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.OpenResourceDialog(sourcesView, defaultScores, history), true); + var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.OpenResourceDialog(sourcesView, defaultScores, history)); filteredItemSelectionDialog.showAsDialog(); filteredItemSelectionDialog.setQuery(query); } @@ -105,6 +114,15 @@ WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = { return this._types.indexOf(project.type()) !== -1; }, + /** + * @override + * @return {boolean} + */ + renderAsTwoRows: function() + { + return true; + }, + __proto__: WebInspector.FilteredUISourceCodeListDelegate.prototype } @@ -115,7 +133,7 @@ WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = { */ WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback) { - var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback), true); + var filteredItemSelectionDialog = new WebInspector.FilteredListWidget(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback)); filteredItemSelectionDialog.showAsDialog(); filteredItemSelectionDialog.setQuery(name); } diff --git a/front_end/sources/StyleSheetOutlineDialog.js b/front_end/sources/StyleSheetOutlineDialog.js index 1c4281ef69..651733f893 100644 --- a/front_end/sources/StyleSheetOutlineDialog.js +++ b/front_end/sources/StyleSheetOutlineDialog.js @@ -48,7 +48,7 @@ WebInspector.StyleSheetOutlineDialog = function(uiSourceCode, selectItemCallback WebInspector.StyleSheetOutlineDialog.show = function(uiSourceCode, selectItemCallback) { WebInspector.StyleSheetOutlineDialog._instanceForTests = new WebInspector.StyleSheetOutlineDialog(uiSourceCode, selectItemCallback); - new WebInspector.FilteredListWidget(WebInspector.StyleSheetOutlineDialog._instanceForTests, false).showAsDialog(); + new WebInspector.FilteredListWidget(WebInspector.StyleSheetOutlineDialog._instanceForTests).showAsDialog(); } WebInspector.StyleSheetOutlineDialog.prototype = { diff --git a/front_end/sources/sourcesSearch.css b/front_end/sources/sourcesSearch.css index 0f1fd639e2..ed822d13fd 100644 --- a/front_end/sources/sourcesSearch.css +++ b/front_end/sources/sourcesSearch.css @@ -8,6 +8,8 @@ flex: none; display: flex; border-bottom: 2px solid #e8e8e8; + white-space: nowrap; + overflow: hidden; } .search-drawer-header input.search-config-search { @@ -17,6 +19,7 @@ border-radius: 2px; color: #303030; border: none; + min-width: 95px; } .search-drawer-header .search-icon { @@ -63,7 +66,7 @@ } .search-drawer-header label.search-config-label { - margin: 2px 0px; + margin: 2px 4px; margin-left: 8px; color: #303030; display: flex; @@ -81,6 +84,9 @@ .search-toolbar-summary .search-message { padding-top: 2px; padding-left: 1ex; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } #search-results-pane-file-based li { diff --git a/front_end/timeline/TimelineFlameChart.js b/front_end/timeline/TimelineFlameChart.js index 9b37d4433f..4e1bbc9702 100644 --- a/front_end/timeline/TimelineFlameChart.js +++ b/front_end/timeline/TimelineFlameChart.js @@ -316,13 +316,14 @@ WebInspector.TimelineFlameChartDataProvider = function(model, frameModel, irMode }; this._interactionsHeaderLevel2 = { - padding: 4, + padding: 2, height: 17, collapsible: true, color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground), font: this._font, backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background), - nestingLevel: 1 + nestingLevel: 1, + shareHeaderLine: true }; } @@ -384,9 +385,12 @@ WebInspector.TimelineFlameChartDataProvider.prototype = { this._entryTypeByLevel = []; /** @type {!Array} */ this._entryIndexToTitle = []; - /** @type {!Array.} */ + /** @type {!Array} */ this._markers = []; - this._asyncColorByCategory = {}; + /** @type {!Map} */ + this._asyncColorByCategory = new Map(); + /** @type {!Map} */ + this._asyncColorByInteractionPhase = new Map(); }, /** @@ -666,6 +670,18 @@ WebInspector.TimelineFlameChartDataProvider.prototype = { */ entryColor: function(entryIndex) { + // This is not annotated due to closure compiler failure to properly infer cache container's template type. + function patchColorAndCache(cache, key, lookupColor) + { + var color = cache.get(key); + if (color) + return color; + var parsedColor = WebInspector.Color.parse(lookupColor(key)); + color = parsedColor.setAlpha(0.7).asString(WebInspector.Color.Format.RGBA) || ""; + cache.set(key, color); + return color; + } + var type = this._entryType(entryIndex); if (type === WebInspector.TimelineFlameChartEntryType.Event) { var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]); @@ -673,14 +689,12 @@ WebInspector.TimelineFlameChartDataProvider.prototype = { return WebInspector.TimelineUIUtils.eventColor(event); if (event.hasCategory(WebInspector.TimelineModel.Category.Console) || event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)) return this._consoleColorGenerator.colorForID(event.name); + if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)) { + var phase = WebInspector.TimelineIRModel.phaseForEvent(event) || WebInspector.TimelineIRModel.Phases.Uncategorized; + return patchColorAndCache(this._asyncColorByInteractionPhase, phase, WebInspector.TimelineUIUtils.interactionPhaseColor); + } var category = WebInspector.TimelineUIUtils.eventStyle(event).category; - var color = this._asyncColorByCategory[category.name]; - if (color) - return color; - var parsedColor = WebInspector.Color.parse(category.color); - color = parsedColor.setAlpha(0.7).asString(WebInspector.Color.Format.RGBA) || ""; - this._asyncColorByCategory[category.name] = color; - return color; + return patchColorAndCache(this._asyncColorByCategory, category, () => category.color); } if (type === WebInspector.TimelineFlameChartEntryType.Frame) return "white"; @@ -737,9 +751,9 @@ WebInspector.TimelineFlameChartDataProvider.prototype = { if (type === WebInspector.TimelineFlameChartEntryType.Event) { var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]); if (event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo) && event.timeWaitingForMainThread) { - context.fillStyle = "rgba(255, 140, 120, 0.6)"; + context.fillStyle = "hsla(0, 70%, 60%, 1)"; var width = Math.floor(unclippedBarX - barX + event.timeWaitingForMainThread * timeToPixels); - context.fillRect(barX, barY, width, barHeight - 1); + context.fillRect(barX, barY + barHeight - 3, width, 2); } if (event.warning) paintWarningDecoration(barX, barWidth - 1.5); @@ -1306,13 +1320,9 @@ WebInspector.TimelineFlameChartView = function(delegate, timelineModel, frameMod this._networkDataProvider = new WebInspector.TimelineFlameChartNetworkDataProvider(this._model); this._networkView = new WebInspector.FlameChart(this._networkDataProvider, this); - if (Runtime.experiments.isEnabled("networkRequestsOnTimeline")) { - this._splitWidget.setMainWidget(this._mainView); - this._splitWidget.setSidebarWidget(this._networkView); - this._splitWidget.show(this.element); - } else { - this._mainView.show(this.element); - } + this._splitWidget.setMainWidget(this._mainView); + this._splitWidget.setSidebarWidget(this._networkView); + this._splitWidget.show(this.element); this._onMainEntrySelected = this._onEntrySelected.bind(this, this._dataProvider); this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider); diff --git a/front_end/timeline/TimelineIRModel.js b/front_end/timeline/TimelineIRModel.js index 0f9331f4cf..59bdeccc10 100644 --- a/front_end/timeline/TimelineIRModel.js +++ b/front_end/timeline/TimelineIRModel.js @@ -19,7 +19,8 @@ WebInspector.TimelineIRModel.Phases = { Scroll: "Scroll", Fling: "Fling", Drag: "Drag", - Animation: "Animation" + Animation: "Animation", + Uncategorized: "Uncategorized" }; /** @@ -62,6 +63,17 @@ WebInspector.TimelineIRModel._mergeThresholdsMs = { mouse: 40, }; +WebInspector.TimelineIRModel._eventIRPhase = Symbol("eventIRPhase"); + +/** + * @param {!WebInspector.TracingModel.Event} event + * @return {!WebInspector.TimelineIRModel.Phases} + */ +WebInspector.TimelineIRModel.phaseForEvent = function(event) +{ + return event[WebInspector.TimelineIRModel._eventIRPhase]; +} + WebInspector.TimelineIRModel.prototype = { /** * @param {!WebInspector.TimelineModel} timelineModel @@ -99,6 +111,7 @@ WebInspector.TimelineIRModel.prototype = { var phases = WebInspector.TimelineIRModel.Phases; var thresholdsMs = WebInspector.TimelineIRModel._mergeThresholdsMs; + var scrollStart; var flingStart; var touchStart; var firstTouchMove; @@ -112,6 +125,20 @@ WebInspector.TimelineIRModel.prototype = { console.assert(false, "Unordered input events"); var type = this._inputEventType(event.name); switch (type) { + + case eventTypes.ScrollBegin: + this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); + scrollStart = event; + break; + + case eventTypes.ScrollEnd: + if (scrollStart) + this._scrolls.append(this._segmentForEventRange(scrollStart, event, phases.Scroll)); + else + this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); + scrollStart = null; + break; + case eventTypes.ScrollUpdate: touchStart = null; // Since we're scrolling now, disregard other touch gestures. this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); @@ -129,7 +156,7 @@ WebInspector.TimelineIRModel.prototype = { // FIXME: also process renderer fling events. if (!flingStart) break; - this._scrolls.append(new WebInspector.Segment(flingStart.startTime, event.endTime, phases.Fling)); + this._scrolls.append(this._segmentForEventRange(flingStart, event, phases.Fling)); flingStart = null; break; @@ -156,6 +183,7 @@ WebInspector.TimelineIRModel.prototype = { break; } touchStart = event; + event.steps[0][WebInspector.TimelineIRModel._eventIRPhase] = phases.Response; firstTouchMove = null; break; @@ -168,7 +196,7 @@ WebInspector.TimelineIRModel.prototype = { this._drags.append(this._segmentForEvent(event, phases.Drag)); } else if (touchStart) { firstTouchMove = event; - this._responses.append(new WebInspector.Segment(touchStart.startTime, event.endTime, phases.Response)); + this._responses.append(this._segmentForEventRange(touchStart, event, phases.Response)); } break; @@ -199,8 +227,9 @@ WebInspector.TimelineIRModel.prototype = { case eventTypes.MouseWheel: // Do not consider first MouseWheel as trace viewer's implementation does -- in case of MouseWheel it's not really special. if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event)) - this._scrolls.append(new WebInspector.Segment(mouseWheel.endTime, event.startTime, phases.Scroll)); - this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); + this._scrolls.append(this._segmentForEventRange(mouseWheel, event, phases.Scroll)); + else + this._scrolls.append(this._segmentForEvent(event, phases.Scroll)); mouseWheel = event; break; } @@ -234,9 +263,32 @@ WebInspector.TimelineIRModel.prototype = { */ _segmentForEvent: function(event, phase) { + this._setPhaseForEvent(event, phase); return new WebInspector.Segment(event.startTime, event.endTime, phase); }, + /** + * @param {!WebInspector.TracingModel.AsyncEvent} startEvent + * @param {!WebInspector.TracingModel.AsyncEvent} endEvent + * @param {!WebInspector.TimelineIRModel.Phases} phase + * @return {!WebInspector.Segment} + */ + _segmentForEventRange: function(startEvent, endEvent, phase) + { + this._setPhaseForEvent(startEvent, phase); + this._setPhaseForEvent(endEvent, phase); + return new WebInspector.Segment(startEvent.startTime, endEvent.endTime, phase); + }, + + /** + * @param {!WebInspector.TracingModel.AsyncEvent} asyncEvent + * @param {!WebInspector.TimelineIRModel.Phases} phase + */ + _setPhaseForEvent: function(asyncEvent, phase) + { + asyncEvent.steps[0][WebInspector.TimelineIRModel._eventIRPhase] = phase; + }, + /** * @return {!Array} */ diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js index 737026e5d6..5506797c82 100644 --- a/front_end/timeline/TimelinePanel.js +++ b/front_end/timeline/TimelinePanel.js @@ -378,29 +378,26 @@ WebInspector.TimelinePanel.prototype = { this._panelToolbar.appendText(WebInspector.UIString("Capture:")); - this._captureNetworkSetting.addChangeListener(this._onNetworkChanged, this); + var screenshotCheckbox = this._createSettingCheckbox( + WebInspector.UIString("Screenshots"), this._captureFilmStripSetting, WebInspector.UIString("Capture screenshots while recording. (Has small performance overhead)")); + if (!Runtime.experiments.isEnabled("timelineRecordingPerspectives") || perspectiveSetting.get() === WebInspector.TimelinePanel.Perspectives.Custom) { - if (Runtime.experiments.isEnabled("networkRequestsOnTimeline")) { - this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Network"), - this._captureNetworkSetting, - WebInspector.UIString("Capture network requests information"))); - } - this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("JS Profile"), - this._captureJSProfileSetting, - WebInspector.UIString("Capture JavaScript stacks with sampling profiler. (Has performance overhead)"))); - this._captureMemorySetting.addChangeListener(this._onModeChanged, this); - this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Memory"), - this._captureMemorySetting, - WebInspector.UIString("Capture memory information on every timeline event."))); - this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Paint"), - this._captureLayersAndPicturesSetting, - WebInspector.UIString("Capture graphics layer positions and painted pictures. (Has performance overhead)"))); + this._panelToolbar.appendToolbarItem(this._createSettingCheckbox( + WebInspector.UIString("Network"), this._captureNetworkSetting, WebInspector.UIString("Show network requests information"))); + this._panelToolbar.appendToolbarItem(this._createSettingCheckbox( + WebInspector.UIString("JS Profile"), this._captureJSProfileSetting, WebInspector.UIString("Capture JavaScript stacks with sampling profiler. (Has small performance overhead)"))); + this._panelToolbar.appendToolbarItem(screenshotCheckbox); + this._panelToolbar.appendToolbarItem(this._createSettingCheckbox( + WebInspector.UIString("Memory"), this._captureMemorySetting, WebInspector.UIString("Capture memory information on every timeline event."))); + this._panelToolbar.appendToolbarItem(this._createSettingCheckbox( + WebInspector.UIString("Paint"), this._captureLayersAndPicturesSetting, WebInspector.UIString("Capture graphics layer positions and rasterization draw calls. (Has large performance overhead)"))); + } else { + this._panelToolbar.appendToolbarItem(screenshotCheckbox); } + this._captureNetworkSetting.addChangeListener(this._onNetworkChanged, this); + this._captureMemorySetting.addChangeListener(this._onModeChanged, this); this._captureFilmStripSetting.addChangeListener(this._onModeChanged, this); - this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("Screenshots"), - this._captureFilmStripSetting, - WebInspector.UIString("Capture screenshots while recording. (Has performance overhead)"))); this._panelToolbar.appendSeparator(); var garbageCollectButton = new WebInspector.ToolbarButton(WebInspector.UIString("Collect garbage"), "garbage-collect-toolbar-item"); diff --git a/front_end/timeline/TimelineUIUtils.js b/front_end/timeline/TimelineUIUtils.js index dd2220d21f..9b36e53dd8 100644 --- a/front_end/timeline/TimelineUIUtils.js +++ b/front_end/timeline/TimelineUIUtils.js @@ -226,7 +226,8 @@ WebInspector.TimelineUIUtils._interactionPhaseStyles = function() [WebInspector.TimelineIRModel.Phases.Scroll, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Scroll")}], [WebInspector.TimelineIRModel.Phases.Fling, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Fling")}], [WebInspector.TimelineIRModel.Phases.Drag, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Drag")}], - [WebInspector.TimelineIRModel.Phases.Animation, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Animation")}] + [WebInspector.TimelineIRModel.Phases.Animation, {color: "hsl(256, 67%, 70%)", label: WebInspector.UIString("Animation")}], + [WebInspector.TimelineIRModel.Phases.Uncategorized, {color: "hsl(0, 0%, 87%)", label: WebInspector.UIString("Uncategorized")}] ]); WebInspector.TimelineUIUtils._interactionPhaseStylesMap = map; } diff --git a/front_end/ui/Dialog.js b/front_end/ui/Dialog.js index fb24054e2b..dda2f68041 100644 --- a/front_end/ui/Dialog.js +++ b/front_end/ui/Dialog.js @@ -104,6 +104,16 @@ WebInspector.Dialog.prototype = { closeButton.addEventListener("click", this.detach.bind(this, false), false); }, + /** + * @param {number=} positionX + * @param {number=} positionY + */ + setPosition: function(positionX, positionY) + { + this._defaultPositionX = positionX; + this._defaultPositionY = positionY; + }, + /** * @param {!Size} size */ @@ -194,11 +204,21 @@ WebInspector.Dialog.prototype = { height = Math.min(height, this._maxSize.height); } - var positionX = (container.offsetWidth - width) / 2; - positionX = Number.constrain(positionX, 0, container.offsetWidth - width); + var positionX; + if (typeof this._defaultPositionX === "number") { + positionX = this._defaultPositionX; + } else { + positionX = (container.offsetWidth - width) / 2; + positionX = Number.constrain(positionX, 0, container.offsetWidth - width); + } - var positionY = (container.offsetHeight - height) / 2; - positionY = Number.constrain(positionY, 0, container.offsetHeight - height); + var positionY; + if (typeof this._defaultPositionY === "number") { + positionY = this._defaultPositionY; + } else { + positionY = (container.offsetHeight - height) / 2; + positionY = Number.constrain(positionY, 0, container.offsetHeight - height); + } this.element.style.width = width + "px"; this.element.style.height = height + "px"; diff --git a/front_end/ui/InspectorView.js b/front_end/ui/InspectorView.js index 7fd7299473..8f05331360 100644 --- a/front_end/ui/InspectorView.js +++ b/front_end/ui/InspectorView.js @@ -547,6 +547,26 @@ WebInspector.InspectorView.prototype = { this._tabOrderSetting.set(tabOrders); }, + /** + * @param {!WebInspector.SplitWidget} splitWidget + */ + setOwnerSplit: function(splitWidget) + { + this._ownerSplitWidget = splitWidget; + }, + + minimize: function() + { + if (this._ownerSplitWidget) + this._ownerSplitWidget.setSidebarMinimized(true); + }, + + restore: function() + { + if (this._ownerSplitWidget) + this._ownerSplitWidget.setSidebarMinimized(false); + }, + __proto__: WebInspector.VBox.prototype }; diff --git a/front_end/ui/checkboxTextLabel.css b/front_end/ui/checkboxTextLabel.css index bf77309138..5d876fe0fe 100644 --- a/front_end/ui/checkboxTextLabel.css +++ b/front_end/ui/checkboxTextLabel.css @@ -55,6 +55,10 @@ input.dt-checkbox-themed:after { } /* media */ +::content .dt-checkbox-text { + margin-left: 3px; +} + ::content .dt-checkbox-subtitle { color: gray; } diff --git a/front_end/ui/inspectorCommon.css b/front_end/ui/inspectorCommon.css index 3fd0816c72..a6f546e4e9 100644 --- a/front_end/ui/inspectorCommon.css +++ b/front_end/ui/inspectorCommon.css @@ -163,7 +163,7 @@ input { input[type="search"]:focus, input[type="text"]:focus { - outline: auto 5px -webkit-focus-ring-color; + outline: auto rgb(56, 121, 217); } diff --git a/front_end/ui_lazy/CommandMenu.js b/front_end/ui_lazy/CommandMenu.js index 4446daf3d4..76bac863e0 100644 --- a/front_end/ui_lazy/CommandMenu.js +++ b/front_end/ui_lazy/CommandMenu.js @@ -55,6 +55,8 @@ WebInspector.CommandMenuDelegate = function() this._appendAvailableCommands(); } +WebInspector.CommandMenuDelegate.MaterialPaletteColors = ["#F44336", "#E91E63", "#9C27B0", "#673AB7", "#3F51B5", "#03A9F4", "#00BCD4", "#009688", "#4CAF50", "#8BC34A", "#CDDC39", "#FFC107", "#FF9800", "#FF5722", "#795548", "#9E9E9E", "#607D8B"]; + WebInspector.CommandMenuDelegate.prototype = { _appendAvailableCommands: function() { @@ -81,7 +83,8 @@ WebInspector.CommandMenuDelegate.prototype = { */ function commandComparator(left, right) { - return left.title().compareTo(right.title()); + var cats = left.category().compareTo(right.category()); + return cats ? cats : left.title().compareTo(right.title()); } }, @@ -122,9 +125,9 @@ WebInspector.CommandMenuDelegate.prototype = { } // Score panel/drawer reveals above regular actions. - if (command.title().startsWith("Panel")) + if (command.category().startsWith("Panel")) score += 2; - else if (command.title().startsWith("Drawer")) + else if (command.category().startsWith("Drawer")) score += 1; return score; @@ -140,7 +143,12 @@ WebInspector.CommandMenuDelegate.prototype = { renderItem: function(itemIndex, query, titleElement, subtitleElement) { var command = this._commands[itemIndex]; - titleElement.textContent = command.title(); + titleElement.removeChildren(); + var tagElement = titleElement.createChild("span", "tag"); + var index = String.hashCode(command.category()) % WebInspector.CommandMenuDelegate.MaterialPaletteColors.length; + tagElement.style.backgroundColor = WebInspector.CommandMenuDelegate.MaterialPaletteColors[index]; + tagElement.textContent = command.category(); + titleElement.createTextChild(command.title()); this.highlightRanges(titleElement, query); subtitleElement.textContent = command.shortcut(); }, @@ -164,27 +172,46 @@ WebInspector.CommandMenuDelegate.prototype = { return false; }, + /** + * @override + * @return {boolean} + */ + renderMonospace: function() + { + return false; + }, + __proto__: WebInspector.FilteredListWidget.Delegate.prototype } /** * @constructor + * @param {string} category * @param {string} title * @param {string} key * @param {string} shortcut * @param {function()} executeHandler * @param {function()=} availableHandler */ -WebInspector.CommandMenu.Command = function(title, key, shortcut, executeHandler, availableHandler) +WebInspector.CommandMenu.Command = function(category, title, key, shortcut, executeHandler, availableHandler) { + this._category = category; this._title = title; - this._key = title + "\0" + key; + this._key = category + "\0" + title + "\0" + key; this._shortcut = shortcut; this._executeHandler = executeHandler; this._availableHandler = availableHandler; } WebInspector.CommandMenu.Command.prototype = { + /** + * @return {string} + */ + category: function() + { + return this._category; + }, + /** * @return {string} */ @@ -235,9 +262,8 @@ WebInspector.CommandMenu.Command.prototype = { WebInspector.CommandMenu.createCommand = function(category, keys, title, shortcut, executeHandler, availableHandler) { // Separate keys by null character, to prevent fuzzy matching from matching across them. - var key = keys ? keys.split(",").join("\0") : ""; - title = category ? WebInspector.UIString("%s: %s", category, title) : title; - return new WebInspector.CommandMenu.Command(title, key, shortcut, executeHandler, availableHandler); + var key = keys.replace(/,/g, "\0"); + return new WebInspector.CommandMenu.Command(category, title, key, shortcut, executeHandler, availableHandler); } /** @@ -329,7 +355,7 @@ WebInspector.CommandMenu.ShowActionDelegate.prototype = { */ handleAction: function(context, actionId) { - new WebInspector.FilteredListWidget(new WebInspector.CommandMenuDelegate(), false).showAsDialog(); + new WebInspector.FilteredListWidget(new WebInspector.CommandMenuDelegate()).showAsDialog(); InspectorFrontendHost.bringToFront(); return true; } diff --git a/front_end/ui_lazy/FilteredListWidget.js b/front_end/ui_lazy/FilteredListWidget.js index 0c014fa2de..e3f4bf7407 100644 --- a/front_end/ui_lazy/FilteredListWidget.js +++ b/front_end/ui_lazy/FilteredListWidget.js @@ -9,19 +9,20 @@ * @extends {WebInspector.VBox} * @implements {WebInspector.ViewportControl.Provider} * @param {!WebInspector.FilteredListWidget.Delegate} delegate - * @param {boolean} renderAsTwoRows */ -WebInspector.FilteredListWidget = function(delegate, renderAsTwoRows) +WebInspector.FilteredListWidget = function(delegate) { WebInspector.VBox.call(this, true); - this._renderAsTwoRows = renderAsTwoRows; + this._renderAsTwoRows = delegate.renderAsTwoRows(); this.contentElement.classList.add("filtered-list-widget"); this.contentElement.addEventListener("keydown", this._onKeyDown.bind(this), false); + if (delegate.renderMonospace()) + this.contentElement.classList.add("monospace"); this.registerRequiredCSS("ui_lazy/filteredListWidget.css"); - this._promptElement = this.contentElement.createChild("div", "monospace filtered-list-widget-input"); + this._promptElement = this.contentElement.createChild("div", "filtered-list-widget-input"); this._promptElement.setAttribute("spellcheck", "false"); this._promptElement.setAttribute("contenteditable", "plaintext-only"); this._prompt = new WebInspector.TextPrompt(this._autocomplete.bind(this)); @@ -35,7 +36,6 @@ WebInspector.FilteredListWidget = function(delegate, renderAsTwoRows) this._viewportControl = new WebInspector.ViewportControl(this); this._itemElementsContainer = this._viewportControl.element; this._itemElementsContainer.classList.add("container"); - this._itemElementsContainer.classList.add("monospace"); this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false); this.contentElement.appendChild(this._itemElementsContainer); @@ -72,7 +72,8 @@ WebInspector.FilteredListWidget.prototype = { showAsDialog: function() { this._dialog = new WebInspector.Dialog(); - this._dialog.setMaxSize(new Size(504, 600)); + this._dialog.setMaxSize(new Size(504, 340)); + this._dialog.setPosition(undefined, 22); this.show(this._dialog.element); this._dialog.show(); }, @@ -519,6 +520,22 @@ WebInspector.FilteredListWidget.Delegate.prototype = { return true; }, + /** + * @return {boolean} + */ + renderMonospace: function() + { + return true; + }, + + /** + * @return {boolean} + */ + renderAsTwoRows: function() + { + return false; + }, + /** * @param {number} itemIndex * @param {string} promptValue diff --git a/front_end/ui_lazy/FlameChart.js b/front_end/ui_lazy/FlameChart.js index b4c4859825..1673cc1582 100644 --- a/front_end/ui_lazy/FlameChart.js +++ b/front_end/ui_lazy/FlameChart.js @@ -106,7 +106,7 @@ WebInspector.FlameChart = function(dataProvider, flameChartDelegate, groupExpans /** @const */ this._arrowSide = 8; /** @const */ - this._expansionArrowX = this._headerLeftPadding + this._arrowSide / 2; + this._expansionArrowIndent = this._headerLeftPadding + this._arrowSide / 2; /** @const */ this._headerLabelXPadding = 3; /** @const */ @@ -844,10 +844,10 @@ WebInspector.FlameChart.prototype = { */ _toggleGroupVisibility: function(groupIndex) { + if (!this._isGroupCollapsible(groupIndex)) + return; var groups = this._rawTimelineData.groups; var group = groups[groupIndex]; - if (!group.style.collapsible) - return; group.expanded = !group.expanded; this._groupExpansionState[group.name] = group.expanded; if (this._groupExpansionSetting) @@ -1368,7 +1368,7 @@ WebInspector.FlameChart.prototype = { context.translate(0, -top); context.fillStyle = WebInspector.themeSupport.patchColor("#eee", colorUsage.Background); - forEachGroup((offset, index, group) => { + forEachGroup.call(this, (offset, index, group) => { var paddingHeight = group.style.padding; if (paddingHeight < 5) return; @@ -1379,7 +1379,7 @@ WebInspector.FlameChart.prototype = { context.strokeStyle = WebInspector.themeSupport.patchColor("#bbb", colorUsage.Background); context.beginPath(); - forEachGroup((offset, index, group, isFirst) => { + forEachGroup.call(this, (offset, index, group, isFirst) => { if (isFirst || group.style.padding < 4) return; hLine(offset - 2.5); @@ -1387,12 +1387,14 @@ WebInspector.FlameChart.prototype = { hLine(lastGroupOffset + 0.5); context.stroke(); - forEachGroup((offset, index, group) => { - if (group.style.shareHeaderLine) + forEachGroup.call(this, (offset, index, group) => { + if (group.style.useFirstLineForOverview) return; - if ((!group.style.collapsible || group.expanded)) { - context.fillStyle = group.style.backgroundColor; - context.fillRect(0, offset, width, group.style.height); + if (!this._isGroupCollapsible(index) || group.expanded) { + if (!group.style.shareHeaderLine) { + context.fillStyle = group.style.backgroundColor; + context.fillRect(0, offset, width, group.style.height); + } return; } var nextGroup = index + 1; @@ -1403,23 +1405,23 @@ WebInspector.FlameChart.prototype = { }); context.save(); - forEachGroup((offset, index, group) => { + forEachGroup.call(this, (offset, index, group) => { context.font = group.style.font; - if (group.style.collapsible && !group.expanded || group.style.shareHeaderLine) { + if (this._isGroupCollapsible(index) && !group.expanded || group.style.shareHeaderLine) { var width = this._labelWidthForGroup(context, group); context.fillStyle = WebInspector.Color.parse(group.style.backgroundColor).setAlpha(0.7).asString(null); context.fillRect(this._headerLeftPadding - this._headerLabelXPadding, offset + this._headerLabelYPadding, width, barHeight - 2 * this._headerLabelYPadding); } context.fillStyle = group.style.color; - context.fillText(group.name, Math.floor(this._expansionArrowX + this._arrowSide), offset + textBaseHeight); + context.fillText(group.name, Math.floor(this._expansionArrowIndent * (group.style.nestingLevel + 1) + this._arrowSide), offset + textBaseHeight); }); context.restore(); context.fillStyle = WebInspector.themeSupport.patchColor("#6e6e6e", colorUsage.Foreground); context.beginPath(); - forEachGroup((offset, index, group) => { - if (group.style.collapsible) - drawExpansionArrow.call(this, this._expansionArrowX, offset + textBaseHeight - this._arrowSide / 2, !!group.expanded) + forEachGroup.call(this, (offset, index, group) => { + if (this._isGroupCollapsible(index)) + drawExpansionArrow.call(this, this._expansionArrowIndent * (group.style.nestingLevel + 1), offset + textBaseHeight - this._arrowSide / 2, !!group.expanded) }); context.fill(); @@ -1459,6 +1461,7 @@ WebInspector.FlameChart.prototype = { /** * @param {function(number, number, !WebInspector.FlameChart.Group, boolean)} callback + * @this {WebInspector.FlameChart} */ function forEachGroup(callback) { @@ -1475,7 +1478,7 @@ WebInspector.FlameChart.prototype = { firstGroup = false; } var parentGroupVisible = groupStack.peekLast().visible; - var thisGroupVisible = parentGroupVisible && (!group.style.collapsible || group.expanded); + var thisGroupVisible = parentGroupVisible && (!this._isGroupCollapsible(i) || group.expanded); groupStack.push({nestingLevel: group.style.nestingLevel, visible: thisGroupVisible}); if (!parentGroupVisible || groupTop + group.style.height < top) continue; @@ -1491,7 +1494,7 @@ WebInspector.FlameChart.prototype = { */ _labelWidthForGroup: function(context, group) { - return this._measureWidth(context, group.name) + 1.5 * this._arrowSide + 2 * this._headerLabelXPadding; + return this._measureWidth(context, group.name) + this._expansionArrowIndent * (group.style.nestingLevel + 1) + 2 * this._headerLabelXPadding; }, /** @@ -1706,7 +1709,7 @@ WebInspector.FlameChart.prototype = { groupStack.pop(); nextLevel = false; } - var thisGroupIsVisible = style.collapsible ? groups[groupIndex].expanded : true; + var thisGroupIsVisible = groupIndex >= 0 && this._isGroupCollapsible(groupIndex) ? groups[groupIndex].expanded : true; var parentGroupIsVisible = groupStack.peekLast().visible; visible = thisGroupIsVisible && parentGroupIsVisible; groupStack.push({nestingLevel: style.nestingLevel, visible: visible}); @@ -1716,10 +1719,11 @@ WebInspector.FlameChart.prototype = { if (parentGroupIsVisible && !style.shareHeaderLine) currentOffset += style.height; } - var thisLevelIsVisible = visible || groupIndex >= 0 && groups[groupIndex].style.useFirstLineForOverview && level === groups[groupIndex].startLevel; + var isFirstOnLevel = groupIndex >= 0 && level === groups[groupIndex].startLevel; + var thisLevelIsVisible = visible || isFirstOnLevel && groups[groupIndex].style.useFirstLineForOverview; this._visibleLevels[level] = thisLevelIsVisible; this._visibleLevelOffsets[level] = currentOffset; - if (thisLevelIsVisible) + if (thisLevelIsVisible || (parentGroupIsVisible && style.shareHeaderLine && isFirstOnLevel)) currentOffset += this._barHeight; } if (groupIndex >= 0) @@ -1727,6 +1731,23 @@ WebInspector.FlameChart.prototype = { this._visibleLevelOffsets[level] = currentOffset; }, + /** + * @param {number} index + */ + _isGroupCollapsible: function(index) + { + var groups = this._rawTimelineData.groups || []; + var style = groups[index].style; + if (!style.shareHeaderLine || !style.collapsible) + return !!style.collapsible; + var isLastGroup = index + 1 >= groups.length; + if (!isLastGroup && groups[index + 1].style.nestingLevel > style.nestingLevel) + return true; + var nextGroupLevel = isLastGroup ? this._dataProvider.maxStackDepth() : groups[index + 1].startLevel; + // For groups that only have one line and share header line, pretend these are not collapsible. + return nextGroupLevel !== groups[index].startLevel + 1; + }, + /** * @param {number} entryIndex */ diff --git a/front_end/ui_lazy/filteredListWidget.css b/front_end/ui_lazy/filteredListWidget.css index 7ed987bc9c..0f3299b738 100644 --- a/front_end/ui_lazy/filteredListWidget.css +++ b/front_end/ui_lazy/filteredListWidget.css @@ -13,7 +13,7 @@ .filtered-list-widget-prompt-element { flex: 0 0 36px; border: 0; - box-shadow: rgba(140, 140, 140, 0.5) 0 4px 16px; + box-shadow: rgba(140, 140, 140, 0.2) 0 2px 2px; margin: 0; padding: 0 6px; z-index: 1; @@ -30,11 +30,11 @@ .filtered-list-widget > div.container { flex: auto; overflow-y: auto; - background: white; + background: #fbfbfb; } .filtered-list-widget-item { - padding: 6px; + padding: 4px 6px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; @@ -42,7 +42,7 @@ } .filtered-list-widget-item.selected { - background-color: #eee; + background-color: #f0f0f0; } .filtered-list-widget-item span.highlight { @@ -77,3 +77,15 @@ .filtered-list-widget-item.two-rows { border-bottom: 1px solid rgb(235, 235, 235); } + +.tag { + color: white; + padding: 1px 3px; + margin-right: 5px; + border-radius: 2px; + line-height: 18px; +} + +.filtered-list-widget-item .tag .highlight { + color: white; +}