Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: Source/devtools/front_end/timeline/TimelineUIUtils.js

Issue 307353004: Timeline: extract tracing-specific UI helpers into TracingTimelineUIUtils.js (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Inc. All rights reserved. 3 * Copyright (C) 2012 Intel Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 /** 661 /**
662 * @param {!Array.<number>} quad 662 * @param {!Array.<number>} quad
663 * @return {number} 663 * @return {number}
664 */ 664 */
665 WebInspector.TimelineUIUtils._quadWidth = function(quad) 665 WebInspector.TimelineUIUtils._quadWidth = function(quad)
666 { 666 {
667 return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1 ] - quad[3], 2))); 667 return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1 ] - quad[3], 2)));
668 } 668 }
669 669
670 /** 670 /**
671 * @param {!WebInspector.TracingModel.Event} event
672 * @param {!WebInspector.TracingModel} model
673 * @param {!WebInspector.Linkifier} linkifier
674 * @param {function(!DocumentFragment)} callback
675 * @param {boolean} loadedFromFile
676 * @param {?WebInspector.TimelineTraceEventBindings} bindings
677 * @param {!WebInspector.Target} target
678 */
679 WebInspector.TimelineUIUtils.buildTraceEventDetails = function(event, model, lin kifier, callback, loadedFromFile, bindings, target)
680 {
681 var relatedNode = null;
682 var barrier = new CallbackBarrier();
683 if (event.imageURL && !event.previewElement)
684 WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, even t.imageURL, false, barrier.createCallback(saveImage));
685 if (event.backendNodeId)
686 target.domModel.pushNodesByBackendIdsToFrontend([event.backendNodeId], b arrier.createCallback(setRelatedNode));
687 barrier.callWhenDone(callbackWrapper);
688
689 /**
690 * @param {!Element=} element
691 */
692 function saveImage(element)
693 {
694 event.previewElement = element || null;
695 }
696
697 /**
698 * @param {?Array.<!DOMAgent.NodeId>} nodeIds
699 */
700 function setRelatedNode(nodeIds)
701 {
702 if (nodeIds)
703 relatedNode = target.domModel.nodeForId(nodeIds[0]);
704 }
705
706 function callbackWrapper()
707 {
708 callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronous ly(event, model, linkifier, relatedNode, loadedFromFile, bindings, target));
709 }
710 }
711
712 /**
713 * @param {!WebInspector.TracingModel.Event} event
714 * @param {!WebInspector.TracingModel} model
715 * @param {!WebInspector.Linkifier} linkifier
716 * @param {?WebInspector.DOMNode} relatedNode
717 * @param {boolean} loadedFromFile
718 * @param {?WebInspector.TimelineTraceEventBindings} bindings
719 * @param {!WebInspector.Target} target
720 * @return {!DocumentFragment}
721 */
722 WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously = function(eve nt, model, linkifier, relatedNode, loadedFromFile, bindings, target)
723 {
724 var fragment = document.createDocumentFragment();
725 var stats = WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(model , event);
726 var pieChart = stats.hasChildren ?
727 WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats, Web Inspector.TimelineUIUtils.styleForTimelineEvent(event.name).category, event.self Time / 1000) :
728 WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats);
729 fragment.appendChild(pieChart);
730
731 var recordTypes = WebInspector.TimelineTraceEventBindings.RecordType;
732
733 // The messages may vary per event.name;
734 var callSiteStackTraceLabel;
735 var callStackLabel;
736 var relatedNodeLabel;
737
738 var contentHelper = new WebInspector.TimelineDetailsContentHelper(target, li nkifier, true);
739 contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.milli sToString(event.selfTime / 1000, true));
740 contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.mill isToString((event.startTime - model.minimumRecordTime()) / 1000));
741 var eventData = event.args.data;
742 var initiator = event.initiator;
743
744 switch (event.name) {
745 case recordTypes.GCEvent:
746 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA fter"];
747 contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.b ytesToString(delta));
748 break;
749 case recordTypes.TimerFire:
750 callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
751 // Fall-through intended.
752
753 case recordTypes.TimerInstall:
754 case recordTypes.TimerRemove:
755 contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData ["timerId"]);
756 if (event.name === recordTypes.TimerInstall) {
757 contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number .millisToString(eventData["timeout"]));
758 contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !event Data["singleShot"]);
759 }
760 break;
761 case recordTypes.FireAnimationFrame:
762 callSiteStackTraceLabel = WebInspector.UIString("Animation frame request ed");
763 contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventD ata["id"]);
764 break;
765 case recordTypes.FunctionCall:
766 if (eventData["scriptName"])
767 contentHelper.appendLocationRow(WebInspector.UIString("Location"), e ventData["scriptName"], eventData["scriptLine"]);
768 break;
769 case recordTypes.ResourceSendRequest:
770 case recordTypes.ResourceReceiveResponse:
771 case recordTypes.ResourceReceivedData:
772 case recordTypes.ResourceFinish:
773 var url = (event.name === recordTypes.ResourceSendRequest) ? eventData[" url"] : initiator.args.data["url"];
774 if (url)
775 contentHelper.appendElementRow(WebInspector.UIString("Resource"), We bInspector.linkifyResourceAsNode(url));
776 if (event.previewElement)
777 contentHelper.appendElementRow(WebInspector.UIString("Preview"), eve nt.previewElement);
778 if (eventData["requestMethod"])
779 contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]);
780 if (typeof eventData["statusCode"] === "number")
781 contentHelper.appendTextRow(WebInspector.UIString("Status Code"), ev entData["statusCode"]);
782 if (eventData["mimeType"])
783 contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), even tData["mimeType"]);
784 if (eventData["encodedDataLength"])
785 contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Leng th"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"]));
786 break;
787 case recordTypes.EvaluateScript:
788 var url = eventData["url"];
789 if (url)
790 contentHelper.appendLocationRow(WebInspector.UIString("Script"), url , eventData["lineNumber"]);
791 break;
792 case recordTypes.Paint:
793 var clip = eventData["clip"];
794 contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspec tor.UIString("(%d, %d)", clip[0], clip[1]));
795 var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip);
796 var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip);
797 contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInsp ector.UIString("%d × %d", clipWidth, clipHeight));
798 // Fall-through intended.
799
800 case recordTypes.PaintSetup:
801 case recordTypes.Rasterize:
802 case recordTypes.ScrollLayer:
803 relatedNodeLabel = WebInspector.UIString("Layer root");
804 break;
805 case recordTypes.PaintImage:
806 case recordTypes.DecodeLazyPixelRef:
807 case recordTypes.DecodeImage:
808 case recordTypes.ResizeImage:
809 case recordTypes.DrawLazyPixelRef:
810 relatedNodeLabel = WebInspector.UIString("Image element");
811 if (event.imageURL)
812 contentHelper.appendElementRow(WebInspector.UIString("Image URL"), W ebInspector.linkifyResourceAsNode(event.imageURL));
813 if (event.previewElement)
814 contentHelper.appendElementRow(WebInspector.UIString("Preview"), eve nt.previewElement);
815 break;
816 case recordTypes.RecalculateStyles: // We don't want to see default details.
817 contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), event.args["elementCount"]);
818 callStackLabel = WebInspector.UIString("Styles recalculation forced");
819 break;
820 case recordTypes.Layout:
821 var beginData = event.args["beginData"];
822 contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layou t"), beginData["dirtyObjects"]);
823 contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), b eginData["totalObjects"]);
824 contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
825 beginData["partialLayout"] ? WebInspector.UI String("Partial") : WebInspector.UIString("Whole document"));
826 callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
827 callStackLabel = WebInspector.UIString("Layout forced");
828 relatedNodeLabel = WebInspector.UIString("Layout root");
829 break;
830 case recordTypes.ConsoleTime:
831 contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData[ "message"]);
832 break;
833 case recordTypes.WebSocketCreate:
834 case recordTypes.WebSocketSendHandshakeRequest:
835 case recordTypes.WebSocketReceiveHandshakeResponse:
836 case recordTypes.WebSocketDestroy:
837 var initiatorData = initiator ? initiator.args.data : eventData;
838 if (typeof initiatorData["webSocketURL"] !== "undefined")
839 contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorD ata["webSocketURL"]);
840 if (typeof initiatorData["webSocketProtocol"] !== "undefined")
841 contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protoco l"), initiatorData["webSocketProtocol"]);
842 if (typeof eventData["message"] !== "undefined")
843 contentHelper.appendTextRow(WebInspector.UIString("Message"), eventD ata["message"]);
844 break;
845 case recordTypes.EmbedderCallback:
846 contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]);
847 break;
848 default:
849 var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNodeForTraceE vent(event, linkifier, loadedFromFile, bindings, target);
850 if (detailsNode)
851 contentHelper.appendElementRow(WebInspector.UIString("Details"), det ailsNode);
852 break;
853 }
854
855 if (relatedNode)
856 contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString ("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(related Node));
857
858 if (eventData && eventData["scriptName"] && event.name !== recordTypes.Funct ionCall)
859 contentHelper.appendLocationRow(WebInspector.UIString("Function Call"), eventData["scriptName"], eventData["scriptLine"]);
860
861 if (initiator) {
862 var callSiteStackTrace = initiator.stackTrace;
863 if (callSiteStackTrace)
864 contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspect or.UIString("Call Site stack"), callSiteStackTrace);
865 }
866 var eventStackTrace = event.stackTrace;
867 if (eventStackTrace)
868 contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString(" Call Stack"), eventStackTrace);
869
870 var warning = event.warning;
871 if (warning) {
872 var div = document.createElement("div");
873 div.textContent = warning;
874 contentHelper.appendElementRow(WebInspector.UIString("Warning"), div);
875 }
876 fragment.appendChild(contentHelper.element);
877 return fragment;
878 }
879
880 /**
881 * @param {!WebInspector.TracingModel} model
882 * @param {!WebInspector.TracingModel.Event} event
883 * @return {!{ aggregatedStats: !Object, hasChildren: boolean }}
884 */
885 WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent = function(model, eve nt)
886 {
887 var events = model.inspectedTargetEvents();
888 /**
889 * @param {number} startTime
890 * @param {!WebInspector.TracingModel.Event} e
891 * @return {number}
892 */
893 function eventComparator(startTime, e)
894 {
895 return startTime - e.startTime;
896 }
897 var index = events.binaryIndexOf(event.startTime, eventComparator);
898 var hasChildren = false;
899 var aggregatedStats = {};
900 var endTime = event.endTime;
901 if (endTime) {
902 for (var i = index; i < events.length; i++) {
903 var nextEvent = events[i];
904 if (nextEvent.startTime >= endTime)
905 break;
906 if (!nextEvent.selfTime)
907 continue;
908 if (i > index)
909 hasChildren = true;
910 var category = WebInspector.TimelineUIUtils.styleForTimelineEvent(ne xtEvent.name).category.name;
911 aggregatedStats[category] = (aggregatedStats[category] || 0) + nextE vent.selfTime / 1000;
912 }
913 }
914 return { aggregatedStats: aggregatedStats, hasChildren: hasChildren };
915 }
916
917 /**
918 * @param {!Array.<number>} quad 671 * @param {!Array.<number>} quad
919 * @return {number} 672 * @return {number}
920 */ 673 */
921 WebInspector.TimelineUIUtils._quadHeight = function(quad) 674 WebInspector.TimelineUIUtils._quadHeight = function(quad)
922 { 675 {
923 return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1 ] - quad[7], 2))); 676 return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1 ] - quad[7], 2)));
924 } 677 }
925 678
926 /** 679 /**
927 * @param {!WebInspector.TimelineModel.Record} record 680 * @param {!WebInspector.TimelineModel.Record} record
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 { 802 {
1050 if (record.stackTrace()) 803 if (record.stackTrace())
1051 return linkifyCallFrame(record.stackTrace()[0]); 804 return linkifyCallFrame(record.stackTrace()[0]);
1052 if (record.callSiteStackTrace()) 805 if (record.callSiteStackTrace())
1053 return linkifyCallFrame(record.callSiteStackTrace()[0]); 806 return linkifyCallFrame(record.callSiteStackTrace()[0]);
1054 return null; 807 return null;
1055 } 808 }
1056 } 809 }
1057 810
1058 /** 811 /**
1059 * @param {!WebInspector.TracingModel.Event} event
1060 * @param {!WebInspector.Linkifier} linkifier
1061 * @param {boolean} loadedFromFile
1062 * @param {?WebInspector.TimelineTraceEventBindings} bindings
1063 * @param {!WebInspector.Target} target
1064 * @return {?Node}
1065 */
1066 WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, lin kifier, loadedFromFile, bindings, target)
1067 {
1068 var recordType = WebInspector.TimelineTraceEventBindings.RecordType;
1069
1070 var details;
1071 var detailsText;
1072 var eventData = event.args.data;
1073 switch (event.name) {
1074 case recordType.GCEvent:
1075 var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeA fter"];
1076 detailsText = WebInspector.UIString("%s collected", Number.bytesToString (delta));
1077 break;
1078 case recordType.TimerFire:
1079 detailsText = eventData["timerId"];
1080 break;
1081 case recordType.FunctionCall:
1082 details = linkifyLocation(eventData["scriptId"], eventData["scriptName"] , eventData["scriptLine"], 0);
1083 break;
1084 case recordType.FireAnimationFrame:
1085 detailsText = eventData["id"];
1086 break;
1087 case recordType.EventDispatch:
1088 detailsText = eventData ? eventData["type"] : null;
1089 break;
1090 case recordType.Paint:
1091 var width = WebInspector.TimelineUIUtils._quadWidth(eventData.clip);
1092 var height = WebInspector.TimelineUIUtils._quadHeight(eventData.clip);
1093 if (width && height)
1094 detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
1095 break;
1096 case recordType.TimerInstall:
1097 case recordType.TimerRemove:
1098 details = linkifyTopCallFrame();
1099 detailsText = eventData["timerId"];
1100 break;
1101 case recordType.RequestAnimationFrame:
1102 case recordType.CancelAnimationFrame:
1103 details = linkifyTopCallFrame();
1104 detailsText = eventData["id"];
1105 break;
1106 case recordType.ParseHTML:
1107 case recordType.RecalculateStyles:
1108 details = linkifyTopCallFrame();
1109 break;
1110 case recordType.EvaluateScript:
1111 var url = eventData["url"];
1112 if (url)
1113 details = linkifyLocation("", url, eventData["lineNumber"], 0);
1114 break;
1115 case recordType.XHRReadyStateChange:
1116 case recordType.XHRLoad:
1117 case recordType.ResourceSendRequest:
1118 case recordType.DecodeImage:
1119 case recordType.ResizeImage:
1120 var url = eventData["url"];
1121 if (url)
1122 detailsText = WebInspector.displayNameForURL(url);
1123 break;
1124 case recordType.ResourceReceivedData:
1125 case recordType.ResourceReceiveResponse:
1126 case recordType.ResourceFinish:
1127 var initiator = event.initiator;
1128 if (initiator) {
1129 var url = initiator.args.data["url"];
1130 if (url)
1131 detailsText = WebInspector.displayNameForURL(url);
1132 }
1133 break;
1134 case recordType.ConsoleTime:
1135 detailsText = eventData["message"];
1136 break;
1137 case recordType.EmbedderCallback:
1138 detailsText = eventData["callbackName"];
1139 break;
1140
1141 case recordType.PaintImage:
1142 case recordType.DecodeImage:
1143 case recordType.ResizeImage:
1144 case recordType.DecodeLazyPixelRef:
1145 var url = event.imageURL;
1146 if (url)
1147 detailsText = WebInspector.displayNameForURL(url);
1148 break;
1149
1150 default:
1151 details = linkifyTopCallFrame();
1152 break;
1153 }
1154
1155 if (!details && detailsText)
1156 details = document.createTextNode(detailsText);
1157 return details;
1158
1159 /**
1160 * @param {string} scriptId
1161 * @param {string} url
1162 * @param {number} lineNumber
1163 * @param {number=} columnNumber
1164 */
1165 function linkifyLocation(scriptId, url, lineNumber, columnNumber)
1166 {
1167 if (!loadedFromFile && scriptId !== "0") {
1168 var location = new WebInspector.DebuggerModel.Location(
1169 target,
1170 scriptId,
1171 lineNumber - 1,
1172 (columnNumber || 1) - 1);
1173 return linkifier.linkifyRawLocation(location, "timeline-details");
1174 }
1175
1176 if (!url)
1177 return null;
1178
1179 // FIXME(62725): stack trace line/column numbers are one-based.
1180 columnNumber = columnNumber ? columnNumber - 1 : 0;
1181 return linkifier.linkifyLocation(target, url, lineNumber - 1, columnNumb er, "timeline-details");
1182 }
1183
1184 /**
1185 * @param {!ConsoleAgent.CallFrame} callFrame
1186 */
1187 function linkifyCallFrame(callFrame)
1188 {
1189 return linkifyLocation(callFrame.scriptId, callFrame.url, callFrame.line Number, callFrame.columnNumber);
1190 }
1191
1192 /**
1193 * @return {?Element}
1194 */
1195 function linkifyTopCallFrame()
1196 {
1197 if (!bindings)
1198 return null;
1199 var stackTrace = event.stackTrace;
1200 if (!stackTrace) {
1201 var initiator = event.initiator;
1202 if (initiator)
1203 stackTrace = initiator.stackTrace;
1204 }
1205 if (!stackTrace || !stackTrace.length)
1206 return null;
1207 return linkifyCallFrame(stackTrace[0]);
1208 }
1209 }
1210
1211 /**
1212 * @constructor 812 * @constructor
1213 * @extends {WebInspector.Object} 813 * @extends {WebInspector.Object}
1214 * @param {string} name 814 * @param {string} name
1215 * @param {string} title 815 * @param {string} title
1216 * @param {number} overviewStripGroupIndex 816 * @param {number} overviewStripGroupIndex
1217 * @param {string} borderColor 817 * @param {string} borderColor
1218 * @param {string} backgroundColor 818 * @param {string} backgroundColor
1219 * @param {string} fillColorStop0 819 * @param {string} fillColorStop0
1220 * @param {string} fillColorStop1 820 * @param {string} fillColorStop1
1221 */ 821 */
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 for (var i = 0; i < stackTrace.length; ++i) { 994 for (var i = 0; i < stackTrace.length; ++i) {
1395 var stackFrame = stackTrace[i]; 995 var stackFrame = stackTrace[i];
1396 var row = stackTraceElement.createChild("div"); 996 var row = stackTraceElement.createChild("div");
1397 row.createTextChild(stackFrame.functionName || WebInspector.UIString ("(anonymous function)")); 997 row.createTextChild(stackFrame.functionName || WebInspector.UIString ("(anonymous function)"));
1398 row.createTextChild(" @ "); 998 row.createTextChild(" @ ");
1399 var urlElement = this._linkifier.linkifyLocation(this._target, stack Frame.url, stackFrame.lineNumber - 1); 999 var urlElement = this._linkifier.linkifyLocation(this._target, stack Frame.url, stackFrame.lineNumber - 1);
1400 row.appendChild(urlElement); 1000 row.appendChild(urlElement);
1401 } 1001 }
1402 } 1002 }
1403 } 1003 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698