Index: Source/devtools/front_end/timeline/TimelineUIUtils.js |
diff --git a/Source/devtools/front_end/timeline/TimelineUIUtils.js b/Source/devtools/front_end/timeline/TimelineUIUtils.js |
index a32b796afdf420e77bb7fee9098b290e5582e1ae..c3b5e5bef6f1c6962d953b6ccf5b8f1d089172fa 100644 |
--- a/Source/devtools/front_end/timeline/TimelineUIUtils.js |
+++ b/Source/devtools/front_end/timeline/TimelineUIUtils.js |
@@ -699,7 +699,7 @@ WebInspector.TimelineUIUtils._generateCauses = function(event, target, contentHe |
contentHelper.appendStackTrace(stackLabel || WebInspector.UIString("Stack trace"), event.stackTrace); |
// Indirect causes. |
- if (event.invalidationTrackingEvents) { // Full invalidation tracking (experimental). |
+ if (event.invalidationTrackingEvents && target) { // Full invalidation tracking (experimental). |
WebInspector.TimelineUIUtils._generateInvalidations(event, target, contentHelper); |
} else if (initiator && initiator.stackTrace) { // Partial invalidation tracking. |
contentHelper.appendStackTrace(callSiteStackLabel || WebInspector.UIString("First invalidated"), initiator.stackTrace); |
@@ -708,7 +708,7 @@ WebInspector.TimelineUIUtils._generateCauses = function(event, target, contentHe |
/** |
* @param {!WebInspector.TracingModel.Event} event |
- * @param {?WebInspector.Target} target |
+ * @param {!WebInspector.Target} target |
* @param {!WebInspector.TimelineDetailsContentHelper} contentHelper |
*/ |
WebInspector.TimelineUIUtils._generateInvalidations = function(event, target, contentHelper) |
@@ -732,7 +732,7 @@ WebInspector.TimelineUIUtils._generateInvalidations = function(event, target, co |
/** |
* @param {string} type |
- * @param {?WebInspector.Target} target |
+ * @param {!WebInspector.Target} target |
* @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
* @param {!WebInspector.TimelineDetailsContentHelper} contentHelper |
*/ |
@@ -754,10 +754,17 @@ WebInspector.TimelineUIUtils._generateInvalidationsForType = function(type, targ |
var detailsNode = createElementWithClass("div", "timeline-details-view-row"); |
var titleElement = detailsNode.createChild("span", "timeline-details-view-row-title"); |
titleElement.textContent = WebInspector.UIString("%s: ", title); |
- var eventsList = detailsNode.createChild("div", "timeline-details-view-row-value"); |
+ |
+ var invalidationsTreeOutline = new TreeOutlineInShadow(); |
+ invalidationsTreeOutline.registerRequiredCSS("timeline/invalidationsTree.css"); |
+ invalidationsTreeOutline.element.classList.add("timeline-details-view-row-value"); |
pfeldman
2015/04/09 10:15:52
classList.add(a, b, c) would work.
pdr.
2015/04/09 18:20:34
Done.
|
+ invalidationsTreeOutline.element.classList.add("invalidations-tree"); |
+ detailsNode.appendChild(invalidationsTreeOutline.element); |
+ |
var invalidationGroups = groupInvalidationsByCause(invalidations); |
invalidationGroups.forEach(function(group) { |
- appendInvalidationGroup(eventsList, group); |
+ var groupElement = new WebInspector.TimelineUIUtils.InvalidationsGroupElement(target, contentHelper, group); |
+ invalidationsTreeOutline.appendChild(groupElement); |
}); |
contentHelper.element.appendChild(detailsNode); |
@@ -789,74 +796,130 @@ WebInspector.TimelineUIUtils._generateInvalidationsForType = function(type, targ |
} |
return Object.values(causeToInvalidationMap); |
} |
+} |
+ |
+/** |
+ * @param {!Set<number>} nodeIds |
+ * @param {!WebInspector.InvalidationTrackingEvent} invalidations |
+ */ |
+WebInspector.TimelineUIUtils._collectInvalidationNodeIds = function(nodeIds, invalidations) |
+{ |
+ for (var i = 0; i < invalidations.length; ++i) { |
+ if (invalidations[i].nodeId) |
+ nodeIds.add(invalidations[i].nodeId); |
+ } |
+} |
+ |
+/** |
+ * @constructor |
+ * @param {!WebInspector.Target} target |
+ * @param {!WebInspector.TimelineDetailsContentHelper} contentHelper |
+ * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
+ * @extends {TreeElement} |
+ */ |
+WebInspector.TimelineUIUtils.InvalidationsGroupElement = function(target, contentHelper, invalidations) |
+{ |
+ TreeElement.call(this, "", true); |
+ |
+ this.listItemElement.classList.add("header"); |
+ this.selectable = false; |
+ this.toggleOnClick = true; |
+ |
+ this._contentHelper = contentHelper; |
+ this._invalidations = invalidations; |
+ this.title = this._createTitle(target); |
+} |
+ |
+WebInspector.TimelineUIUtils.InvalidationsGroupElement.prototype = { |
/** |
- * @param {!Element} parentElement |
- * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
+ * @param {!WebInspector.Target} target |
+ * @return {!Element} |
*/ |
- function appendInvalidationGroup(parentElement, invalidations) |
+ _createTitle: function(target) |
{ |
- if (!target) |
- return; |
- |
- var row = parentElement.createChild("div", "invalidations-group section"); |
- var header = row.createChild("div", "header"); |
- header.addEventListener("click", function() { |
- toggleDetails(header, invalidations); |
- }); |
- |
- var first = invalidations[0]; |
+ var first = this._invalidations[0]; |
var reason = first.cause.reason; |
var topFrame = first.cause.stackTrace && first.cause.stackTrace[0]; |
+ var title = createElement("span"); |
if (reason) |
- header.createTextChild(WebInspector.UIString("%s for ", reason)); |
+ title.createTextChild(WebInspector.UIString("%s for ", reason)); |
else |
- header.createTextChild(WebInspector.UIString("Unknown cause for ")); |
- |
- appendTruncatedNodeList(header, invalidations); |
+ title.createTextChild(WebInspector.UIString("Unknown cause for ")); |
- if (topFrame && contentHelper.linkifier()) { |
- header.createTextChild(WebInspector.UIString(". ")); |
- var stack = header.createChild("span", "monospace"); |
+ this._appendTruncatedNodeList(title, this._invalidations); |
+ if (topFrame && this._contentHelper.linkifier()) { |
+ title.createTextChild(WebInspector.UIString(". ")); |
+ var stack = title.createChild("span", "monospace"); |
stack.createChild("span").textContent = WebInspector.beautifyFunctionName(topFrame.functionName); |
stack.createChild("span").textContent = " @ "; |
- stack.createChild("span").appendChild(contentHelper.linkifier().linkifyConsoleCallFrame(target, topFrame)); |
+ stack.createChild("span").appendChild(this._contentHelper.linkifier().linkifyConsoleCallFrame(target, topFrame)); |
} |
- } |
+ |
+ return title; |
+ }, |
/** |
- * @param {!WebInspector.InvalidationTrackingEvent} invalidation |
- * @param {boolean} showUnknownNodes |
+ * @override |
*/ |
- function createInvalidationNode(invalidation, showUnknownNodes) |
+ onpopulate: function() |
{ |
- var node = contentHelper.nodeForBackendId(invalidation.nodeId); |
- if (node) |
- return WebInspector.DOMPresentationUtils.linkifyNodeReference(node); |
- if (invalidation.nodeName) { |
- var nodeSpan = createElement("span"); |
- nodeSpan.textContent = WebInspector.UIString("[ %s ]", invalidation.nodeName); |
- return nodeSpan; |
+ var content = createElementWithClass("div", "content"); |
+ |
+ var first = this._invalidations[0]; |
+ if (first.cause.stackTrace) { |
+ var stack = content.createChild("div"); |
+ stack.createTextChild(WebInspector.UIString("Stack trace:")); |
+ this._contentHelper.createChildStackTraceElement(stack, first.cause.stackTrace); |
} |
- if (showUnknownNodes) { |
- var nodeSpan = createElement("span"); |
- return nodeSpan.createTextChild(WebInspector.UIString("[ unknown node ]")); |
+ |
+ content.createTextChild(this._invalidations.length > 1 ? WebInspector.UIString("Nodes:") : WebInspector.UIString("Node:")); |
+ var nodeList = content.createChild("div", "node-list"); |
+ var firstNode = true; |
+ for (var i = 0; i < this._invalidations.length; i++) { |
+ var invalidation = this._invalidations[i]; |
+ var invalidationNode = this._createInvalidationNode(invalidation, true); |
+ if (invalidationNode) { |
+ if (!firstNode) |
+ nodeList.createTextChild(WebInspector.UIString(", ")); |
+ firstNode = false; |
+ |
+ nodeList.appendChild(invalidationNode); |
+ |
+ var extraData = invalidation.extraData ? ", " + invalidation.extraData : ""; |
+ if (invalidation.changedId) { |
pfeldman
2015/04/09 10:15:52
All one-liners? Drop the {}!
pdr.
2015/04/09 18:20:34
Dropped. -20bytes!
|
+ nodeList.createTextChild(WebInspector.UIString("(changed id to \"%s\"%s)", invalidation.changedId, extraData)); |
+ } else if (invalidation.changedClass) { |
+ nodeList.createTextChild(WebInspector.UIString("(changed class to \"%s\"%s)", invalidation.changedClass, extraData)); |
+ } else if (invalidation.changedAttribute) { |
+ nodeList.createTextChild(WebInspector.UIString("(changed attribute to \"%s\"%s)", invalidation.changedAttribute, extraData)); |
+ } else if (invalidation.changedPseudo) { |
+ nodeList.createTextChild(WebInspector.UIString("(changed pesudo to \"%s\"%s)", invalidation.changedPseudo, extraData)); |
+ } else if (invalidation.selectorPart) { |
+ nodeList.createTextChild(WebInspector.UIString("(changed \"%s\"%s)", invalidation.selectorPart, extraData)); |
+ } |
+ } |
} |
- } |
+ |
+ var contentTreeElement = new TreeElement(content, false); |
+ contentTreeElement.selectable = false; |
+ this.appendChild(contentTreeElement); |
+ }, |
/** |
* @param {!Element} parentElement |
* @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
*/ |
- function appendTruncatedNodeList(parentElement, invalidations) |
+ _appendTruncatedNodeList: function(parentElement, invalidations) |
{ |
var invalidationNodes = []; |
var invalidationNodeIdMap = {}; |
for (var i = 0; i < invalidations.length; i++) { |
var invalidation = invalidations[i]; |
- var invalidationNode = createInvalidationNode(invalidation, false); |
+ var invalidationNode = this._createInvalidationNode(invalidation, false); |
+ invalidationNode.addEventListener("click", consumeEvent, false); |
if (invalidationNode && !invalidationNodeIdMap[invalidation.nodeId]) { |
invalidationNodes.push(invalidationNode); |
invalidationNodeIdMap[invalidation.nodeId] = true; |
@@ -875,91 +938,39 @@ WebInspector.TimelineUIUtils._generateInvalidationsForType = function(type, targ |
parentElement.appendChild(invalidationNodes[1]); |
parentElement.createTextChild(WebInspector.UIString(", and %s others", invalidationNodes.length - 2)); |
} |
- } |
- /** |
- * @param {!Element} header |
- * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
- */ |
- function toggleDetails(header, invalidations) |
- { |
- var wasExpanded = header.classList.contains("expanded"); |
- header.classList.toggle("expanded", !wasExpanded); |
- header.parentElement.classList.toggle("expanded", !wasExpanded); |
- |
- if (wasExpanded) { |
- var content = header.nextElementSibling; |
- if (content) |
- content.remove(); |
- } else { |
- createInvalidationGroupDetails(header.parentElement, invalidations); |
+ /** |
+ * Consume clicks on nodes to prevent tree element expansion. |
+ * @param {!Event} event |
+ */ |
+ function consumeEvent(event) |
pfeldman
2015/04/09 10:15:52
You don't seem to need to preventDefault, so you c
pdr.
2015/04/09 18:20:34
Oh my.. Didn't realize this already existed.
|
+ { |
+ event.consume(true); |
+ return; |
} |
- } |
+ }, |
/** |
- * @param {!Element} parentElement |
- * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
+ * @param {!WebInspector.InvalidationTrackingEvent} invalidation |
+ * @param {boolean} showUnknownNodes |
*/ |
- function createInvalidationGroupDetails(parentElement, invalidations) |
+ _createInvalidationNode: function(invalidation, showUnknownNodes) |
{ |
- var content = parentElement.createChild("div", "content"); |
- |
- var first = invalidations[0]; |
- if (first.cause.stackTrace) { |
- var stack = content.createChild("div"); |
- stack.createTextChild(WebInspector.UIString("Stack trace:")); |
- contentHelper.createChildStackTraceElement(stack, first.cause.stackTrace); |
+ var node = this._contentHelper.nodeForBackendId(invalidation.nodeId); |
+ if (node) |
+ return WebInspector.DOMPresentationUtils.linkifyNodeReference(node); |
+ if (invalidation.nodeName) { |
+ var nodeSpan = createElement("span"); |
+ nodeSpan.textContent = WebInspector.UIString("[ %s ]", invalidation.nodeName); |
+ return nodeSpan; |
} |
- |
- content.createTextChild(invalidations.length > 1 ? WebInspector.UIString("Nodes:") : WebInspector.UIString("Node:")); |
- var nodeList = content.createChild("div", "node-list timeline-details-view-row-stack-trace"); |
- appendDetailedNodeList(nodeList, invalidations); |
- } |
- |
- /** |
- * @param {!Element} parentElement |
- * @param {!Array.<!WebInspector.InvalidationTrackingEvent>} invalidations |
- */ |
- function appendDetailedNodeList(parentElement, invalidations) |
- { |
- var firstNode = true; |
- for (var i = 0; i < invalidations.length; i++) { |
- var invalidation = invalidations[i]; |
- var invalidationNode = createInvalidationNode(invalidation, true); |
- if (invalidationNode) { |
- if (!firstNode) |
- parentElement.createTextChild(WebInspector.UIString(", ")); |
- firstNode = false; |
- |
- parentElement.appendChild(invalidationNode); |
- |
- var extraData = invalidation.extraData ? ", " + invalidation.extraData : ""; |
- if (invalidation.changedId) { |
- parentElement.createTextChild(WebInspector.UIString("(changed id to \"%s\"%s)", invalidation.changedId, extraData)); |
- } else if (invalidation.changedClass) { |
- parentElement.createTextChild(WebInspector.UIString("(changed class to \"%s\"%s)", invalidation.changedClass, extraData)); |
- } else if (invalidation.changedAttribute) { |
- parentElement.createTextChild(WebInspector.UIString("(changed attribute to \"%s\"%s)", invalidation.changedAttribute, extraData)); |
- } else if (invalidation.changedPseudo) { |
- parentElement.createTextChild(WebInspector.UIString("(changed pesudo to \"%s\"%s)", invalidation.changedPseudo, extraData)); |
- } else if (invalidation.selectorPart) { |
- parentElement.createTextChild(WebInspector.UIString("(changed \"%s\"%s)", invalidation.selectorPart, extraData)); |
- } |
- } |
+ if (showUnknownNodes) { |
+ var nodeSpan = createElement("span"); |
+ return nodeSpan.createTextChild(WebInspector.UIString("[ unknown node ]")); |
} |
- } |
-} |
+ }, |
-/** |
- * @param {!Set<number>} nodeIds |
- * @param {!WebInspector.InvalidationTrackingEvent} invalidations |
- */ |
-WebInspector.TimelineUIUtils._collectInvalidationNodeIds = function(nodeIds, invalidations) |
-{ |
- for (var i = 0; i < invalidations.length; ++i) { |
- if (invalidations[i].nodeId) |
- nodeIds.add(invalidations[i].nodeId); |
- } |
+ __proto__: TreeElement.prototype |
} |
/** |