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

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

Powered by Google App Engine
This is Rietveld 408576698