summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js')
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js1891
1 files changed, 0 insertions, 1891 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js
deleted file mode 100644
index 95111ea1437..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js
+++ /dev/null
@@ -1,1891 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2012 Intel Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.TimelinePresentationModel = function()
-{
- this._linkifier = new WebInspector.Linkifier();
- this._glueRecords = false;
- this._filters = [];
- this.reset();
-}
-
-WebInspector.TimelinePresentationModel.categories = function()
-{
- if (WebInspector.TimelinePresentationModel._categories)
- return WebInspector.TimelinePresentationModel._categories;
- WebInspector.TimelinePresentationModel._categories = {
- loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), 0, "#5A8BCC", "#8EB6E9", "#70A2E3"),
- scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), 1, "#D8AA34", "#F3D07A", "#F1C453"),
- rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), 2, "#8266CC", "#AF9AEB", "#9A7EE6"),
- painting: new WebInspector.TimelineCategory("painting", WebInspector.UIString("Painting"), 2, "#5FA050", "#8DC286", "#71B363"),
- other: new WebInspector.TimelineCategory("other", WebInspector.UIString("Other"), -1, "#BBBBBB", "#DDDDDD", "#DDDDDD"),
- idle: new WebInspector.TimelineCategory("idle", WebInspector.UIString("Idle"), -1, "#DDDDDD", "#FFFFFF", "#FFFFFF")
- };
- return WebInspector.TimelinePresentationModel._categories;
-};
-
-/**
- * @return {!Object.<string, {title: string, category: !WebInspector.TimelineCategory}>}
- */
-WebInspector.TimelinePresentationModel._initRecordStyles = function()
-{
- if (WebInspector.TimelinePresentationModel._recordStylesMap)
- return WebInspector.TimelinePresentationModel._recordStylesMap;
-
- var recordTypes = WebInspector.TimelineModel.RecordType;
- var categories = WebInspector.TimelinePresentationModel.categories();
-
- var recordStyles = {};
- recordStyles[recordTypes.Root] = { title: "#root", category: categories["loading"] };
- recordStyles[recordTypes.Program] = { title: WebInspector.UIString("Other"), category: categories["other"] };
- recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: categories["scripting"] };
- recordStyles[recordTypes.BeginFrame] = { title: WebInspector.UIString("Frame Start"), category: categories["rendering"] };
- recordStyles[recordTypes.ScheduleStyleRecalculation] = { title: WebInspector.UIString("Schedule Style Recalculation"), category: categories["rendering"] };
- recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: categories["rendering"] };
- recordStyles[recordTypes.InvalidateLayout] = { title: WebInspector.UIString("Invalidate Layout"), category: categories["rendering"] };
- recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: categories["rendering"] };
- recordStyles[recordTypes.AutosizeText] = { title: WebInspector.UIString("Autosize Text"), category: categories["rendering"] };
- recordStyles[recordTypes.PaintSetup] = { title: WebInspector.UIString("Paint Setup"), category: categories["painting"] };
- recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
- recordStyles[recordTypes.Rasterize] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
- recordStyles[recordTypes.ScrollLayer] = { title: WebInspector.UIString("Scroll"), category: categories["rendering"] };
- recordStyles[recordTypes.DecodeImage] = { title: WebInspector.UIString("Image Decode"), category: categories["painting"] };
- recordStyles[recordTypes.ResizeImage] = { title: WebInspector.UIString("Image Resize"), category: categories["painting"] };
- recordStyles[recordTypes.CompositeLayers] = { title: WebInspector.UIString("Composite Layers"), category: categories["painting"] };
- recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse HTML"), category: categories["loading"] };
- recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: categories["scripting"] };
- recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: categories["scripting"] };
- recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: categories["scripting"] };
- recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: categories["scripting"] };
- recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: categories["scripting"] };
- recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: categories["scripting"] };
- recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: categories["loading"] };
- recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: categories["loading"] };
- recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: categories["loading"] };
- recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: categories["scripting"] };
- recordStyles[recordTypes.ResourceReceivedData] = { title: WebInspector.UIString("Receive Data"), category: categories["loading"] };
- recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("DOMContentLoaded event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkFirstPaint] = { title: WebInspector.UIString("First paint"), category: categories["painting"] };
- recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Stamp"), category: categories["scripting"] };
- recordStyles[recordTypes.Time] = { title: WebInspector.UIString("Time"), category: categories["scripting"] };
- recordStyles[recordTypes.TimeEnd] = { title: WebInspector.UIString("Time End"), category: categories["scripting"] };
- recordStyles[recordTypes.ScheduleResourceRequest] = { title: WebInspector.UIString("Schedule Request"), category: categories["loading"] };
- recordStyles[recordTypes.RequestAnimationFrame] = { title: WebInspector.UIString("Request Animation Frame"), category: categories["scripting"] };
- recordStyles[recordTypes.CancelAnimationFrame] = { title: WebInspector.UIString("Cancel Animation Frame"), category: categories["scripting"] };
- recordStyles[recordTypes.FireAnimationFrame] = { title: WebInspector.UIString("Animation Frame Fired"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketCreate] = { title: WebInspector.UIString("Create WebSocket"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketSendHandshakeRequest] = { title: WebInspector.UIString("Send WebSocket Handshake"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketReceiveHandshakeResponse] = { title: WebInspector.UIString("Receive WebSocket Handshake"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketDestroy] = { title: WebInspector.UIString("Destroy WebSocket"), category: categories["scripting"] };
-
- WebInspector.TimelinePresentationModel._recordStylesMap = recordStyles;
- return recordStyles;
-}
-
-/**
- * @param {!Object} record
- * @return {{title: string, category: !WebInspector.TimelineCategory}}
- */
-WebInspector.TimelinePresentationModel.recordStyle = function(record)
-{
- var recordStyles = WebInspector.TimelinePresentationModel._initRecordStyles();
- var result = recordStyles[record.type];
- if (!result) {
- result = {
- title: WebInspector.UIString("Unknown: %s", record.type),
- category: WebInspector.TimelinePresentationModel.categories()["other"]
- };
- recordStyles[record.type] = result;
- }
- return result;
-}
-
-WebInspector.TimelinePresentationModel.categoryForRecord = function(record)
-{
- return WebInspector.TimelinePresentationModel.recordStyle(record).category;
-}
-
-WebInspector.TimelinePresentationModel.isEventDivider = function(record)
-{
- var recordTypes = WebInspector.TimelineModel.RecordType;
- if (record.type === recordTypes.TimeStamp)
- return true;
- if (record.type === recordTypes.MarkFirstPaint)
- return true;
- if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad) {
- if (record.data && ((typeof record.data.isMainFrame) === "boolean"))
- return record.data.isMainFrame;
- }
- return false;
-}
-
-/**
- * @param {!Array.<*>} recordsArray
- * @param {?function(*)} preOrderCallback
- * @param {function(*)=} postOrderCallback
- */
-WebInspector.TimelinePresentationModel.forAllRecords = function(recordsArray, preOrderCallback, postOrderCallback)
-{
- if (!recordsArray)
- return;
- var stack = [{array: recordsArray, index: 0}];
- while (stack.length) {
- var entry = stack[stack.length - 1];
- var records = entry.array;
- if (entry.index < records.length) {
- var record = records[entry.index];
- if (preOrderCallback && preOrderCallback(record))
- return;
- if (record.children)
- stack.push({array: record.children, index: 0, record: record});
- else if (postOrderCallback && postOrderCallback(record))
- return;
- ++entry.index;
- } else {
- if (entry.record && postOrderCallback && postOrderCallback(entry.record))
- return;
- stack.pop();
- }
- }
-}
-
-/**
- * @param {string=} recordType
- * @return {boolean}
- */
-WebInspector.TimelinePresentationModel.needsPreviewElement = function(recordType)
-{
- if (!recordType)
- return false;
- const recordTypes = WebInspector.TimelineModel.RecordType;
- switch (recordType) {
- case recordTypes.ScheduleResourceRequest:
- case recordTypes.ResourceSendRequest:
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- return true;
- default:
- return false;
- }
-}
-
-/**
- * @param {string} recordType
- * @param {string=} title
- */
-WebInspector.TimelinePresentationModel.createEventDivider = function(recordType, title)
-{
- var eventDivider = document.createElement("div");
- eventDivider.className = "resources-event-divider";
- var recordTypes = WebInspector.TimelineModel.RecordType;
-
- if (recordType === recordTypes.MarkDOMContent)
- eventDivider.className += " resources-blue-divider";
- else if (recordType === recordTypes.MarkLoad)
- eventDivider.className += " resources-red-divider";
- else if (recordType === recordTypes.MarkFirstPaint)
- eventDivider.className += " resources-green-divider";
- else if (recordType === recordTypes.TimeStamp)
- eventDivider.className += " resources-orange-divider";
- else if (recordType === recordTypes.BeginFrame)
- eventDivider.className += " timeline-frame-divider";
-
- if (title)
- eventDivider.title = title;
-
- return eventDivider;
-}
-
-WebInspector.TimelinePresentationModel._hiddenRecords = { }
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkDOMContent] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkLoad] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkFirstPaint] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.InvalidateLayout] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.GPUTask] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.ActivateLayerTree] = 1;
-
-WebInspector.TimelinePresentationModel.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Filter} filter
- */
- addFilter: function(filter)
- {
- this._filters.push(filter);
- },
-
- /**
- * @param {?WebInspector.TimelinePresentationModel.Filter} filter
- */
- setSearchFilter: function(filter)
- {
- this._searchFilter = filter;
- },
-
- rootRecord: function()
- {
- return this._rootRecord;
- },
-
- frames: function()
- {
- return this._frames;
- },
-
- reset: function()
- {
- this._linkifier.reset();
- this._rootRecord = new WebInspector.TimelinePresentationModel.Record(this, { type: WebInspector.TimelineModel.RecordType.Root }, null, null, null, false);
- this._sendRequestRecords = {};
- this._scheduledResourceRequests = {};
- this._timerRecords = {};
- this._requestAnimationFrameRecords = {};
- this._eventDividerRecords = [];
- this._timeRecords = {};
- this._timeRecordStack = [];
- this._frames = [];
- this._minimumRecordTime = -1;
- this._layoutInvalidateStack = {};
- this._lastScheduleStyleRecalculation = {};
- this._webSocketCreateRecords = {};
- this._coalescingBuckets = {};
- },
-
- addFrame: function(frame)
- {
- if (!frame.isBackground)
- this._frames.push(frame);
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
- */
- addRecord: function(record)
- {
- if (this._minimumRecordTime === -1 || record.startTime < this._minimumRecordTime)
- this._minimumRecordTime = WebInspector.TimelineModel.startTimeInSeconds(record);
-
- var records;
- if (record.type === WebInspector.TimelineModel.RecordType.Program)
- records = this._foldSyncTimeRecords(record.children || []);
- else
- records = [record];
- var result = Array(records.length);
- for (var i = 0; i < records.length; ++i)
- result[i] = this._innerAddRecord(this._rootRecord, records[i]);
- return result;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} parentRecord
- * @param {!TimelineAgent.TimelineEvent} record
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- _innerAddRecord: function(parentRecord, record)
- {
- const recordTypes = WebInspector.TimelineModel.RecordType;
- var isHiddenRecord = record.type in WebInspector.TimelinePresentationModel._hiddenRecords;
- var origin;
- var coalescingBucket;
-
- if (!isHiddenRecord) {
- var newParentRecord = this._findParentRecord(record);
- if (newParentRecord) {
- origin = parentRecord;
- parentRecord = newParentRecord;
- }
- // On main thread, only coalesce if the last event is of same type.
- if (parentRecord === this._rootRecord)
- coalescingBucket = record.thread ? record.type : "mainThread";
- var coalescedRecord = this._findCoalescedParent(record, parentRecord, coalescingBucket);
- if (coalescedRecord) {
- if (!origin)
- origin = parentRecord;
- parentRecord = coalescedRecord;
- }
- }
-
- var children = record.children;
- var scriptDetails = null;
- if (record.data && record.data["scriptName"]) {
- scriptDetails = {
- scriptName: record.data["scriptName"],
- scriptLine: record.data["scriptLine"]
- }
- };
-
- if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
- var childRecord = children[0];
- if (childRecord.type === recordTypes.FunctionCall) {
- scriptDetails = {
- scriptName: childRecord.data["scriptName"],
- scriptLine: childRecord.data["scriptLine"]
- };
- children = childRecord.children.concat(children.slice(1));
- }
- }
-
- var formattedRecord = new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, origin, scriptDetails, isHiddenRecord);
-
- if (WebInspector.TimelinePresentationModel.isEventDivider(formattedRecord))
- this._eventDividerRecords.push(formattedRecord);
-
- if (isHiddenRecord)
- return formattedRecord;
-
- formattedRecord.collapsed = parentRecord === this._rootRecord;
- if (coalescingBucket)
- this._coalescingBuckets[coalescingBucket] = formattedRecord;
-
- if (children) {
- children = this._foldSyncTimeRecords(children);
- for (var i = 0; i < children.length; ++i)
- this._innerAddRecord(formattedRecord, children[i]);
- }
-
- formattedRecord.calculateAggregatedStats();
- if (parentRecord.coalesced)
- this._updateCoalescingParent(formattedRecord);
- else if (origin)
- this._updateAncestorStats(formattedRecord);
-
- origin = formattedRecord.origin();
- if (!origin.isRoot() && !origin.coalesced)
- origin.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
- return formattedRecord;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- */
- _updateAncestorStats: function(record)
- {
- var lastChildEndTime = record.lastChildEndTime;
- var aggregatedStats = record.aggregatedStats;
- for (var currentRecord = record.parent; currentRecord && !currentRecord.isRoot(); currentRecord = currentRecord.parent) {
- currentRecord._cpuTime += record._cpuTime;
- if (currentRecord.lastChildEndTime < lastChildEndTime)
- currentRecord.lastChildEndTime = lastChildEndTime;
- for (var category in aggregatedStats)
- currentRecord.aggregatedStats[category] += aggregatedStats[category];
- }
- },
-
- /**
- * @param {!Object} record
- * @param {!Object} newParent
- * @param {string=} bucket
- * @return {?WebInspector.TimelinePresentationModel.Record}
- */
- _findCoalescedParent: function(record, newParent, bucket)
- {
- const coalescingThresholdSeconds = 0.005;
-
- var lastRecord = bucket ? this._coalescingBuckets[bucket] : newParent.children.peekLast();
- if (lastRecord && lastRecord.coalesced)
- lastRecord = lastRecord.children.peekLast();
- var startTime = WebInspector.TimelineModel.startTimeInSeconds(record);
- var endTime = WebInspector.TimelineModel.endTimeInSeconds(record);
- if (!lastRecord)
- return null;
- if (lastRecord.type !== record.type)
- return null;
- if (lastRecord.endTime + coalescingThresholdSeconds < startTime)
- return null;
- if (endTime + coalescingThresholdSeconds < lastRecord.startTime)
- return null;
- if (WebInspector.TimelinePresentationModel.coalescingKeyForRecord(record) !== WebInspector.TimelinePresentationModel.coalescingKeyForRecord(lastRecord._record))
- return null;
- if (lastRecord.parent.coalesced)
- return lastRecord.parent;
- return this._replaceWithCoalescedRecord(lastRecord);
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- _replaceWithCoalescedRecord: function(record)
- {
- var rawRecord = {
- type: record._record.type,
- startTime: record._record.startTime,
- endTime: record._record.endTime,
- data: { }
- };
- if (record._record.thread)
- rawRecord.thread = "aggregated";
- if (record.type === WebInspector.TimelineModel.RecordType.TimeStamp)
- rawRecord.data.message = record.data.message;
-
- var coalescedRecord = new WebInspector.TimelinePresentationModel.Record(this, rawRecord, null, null, null, false);
- var parent = record.parent;
-
- coalescedRecord.coalesced = true;
- coalescedRecord.collapsed = true;
- coalescedRecord._children.push(record);
- record.parent = coalescedRecord;
- if (record.hasWarnings() || record.childHasWarnings())
- coalescedRecord._childHasWarnings = true;
-
- coalescedRecord.parent = parent;
- parent._children[parent._children.indexOf(record)] = coalescedRecord;
- WebInspector.TimelineModel.aggregateTimeByCategory(coalescedRecord._aggregatedStats, record._aggregatedStats);
-
- return coalescedRecord;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- */
- _updateCoalescingParent: function(record)
- {
- var parentRecord = record.parent;
- WebInspector.TimelineModel.aggregateTimeByCategory(parentRecord._aggregatedStats, record._aggregatedStats);
- if (parentRecord.startTime > record._record.startTime)
- parentRecord._record.startTime = record._record.startTime;
- if (parentRecord.endTime < record._record.endTime) {
- parentRecord._record.endTime = record._record.endTime;
- parentRecord.lastChildEndTime = parentRecord.endTime;
- }
- },
-
- /**
- * @param {!Array.<!TimelineAgent.TimelineEvent>} records
- */
- _foldSyncTimeRecords: function(records)
- {
- var recordTypes = WebInspector.TimelineModel.RecordType;
- // Fast case -- if there are no Time records, return input as is.
- for (var i = 0; i < records.length && records[i].type !== recordTypes.Time; ++i) {}
- if (i === records.length)
- return records;
-
- var result = [];
- var stack = [];
- for (var i = 0; i < records.length; ++i) {
- result.push(records[i]);
- if (records[i].type === recordTypes.Time) {
- stack.push(result.length - 1);
- continue;
- }
- if (records[i].type !== recordTypes.TimeEnd)
- continue;
- while (stack.length) {
- var begin = stack.pop();
- if (result[begin].data.message !== records[i].data.message)
- continue;
- var timeEndRecord = /** @type {!TimelineAgent.TimelineEvent} */ (result.pop());
- var children = result.splice(begin + 1, result.length - begin);
- result[begin] = this._createSynchronousTimeRecord(result[begin], timeEndRecord, children);
- break;
- }
- }
- return result;
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} beginRecord
- * @param {!TimelineAgent.TimelineEvent} endRecord
- * @param {!Array.<!TimelineAgent.TimelineEvent>} children
- * @return {!TimelineAgent.TimelineEvent}
- */
- _createSynchronousTimeRecord: function(beginRecord, endRecord, children)
- {
- return {
- type: beginRecord.type,
- startTime: beginRecord.startTime,
- endTime: endRecord.startTime,
- stackTrace: beginRecord.stackTrace,
- children: children,
- data: {
- message: beginRecord.data.message,
- isSynchronous: true
- },
- };
- },
-
- _findParentRecord: function(record)
- {
- if (!this._glueRecords)
- return null;
- var recordTypes = WebInspector.TimelineModel.RecordType;
-
- switch (record.type) {
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceFinish:
- case recordTypes.ResourceReceivedData:
- return this._sendRequestRecords[record.data["requestId"]];
-
- case recordTypes.ResourceSendRequest:
- return this._rootRecord;
-
- case recordTypes.TimerFire:
- return this._timerRecords[record.data["timerId"]];
-
- case recordTypes.ResourceSendRequest:
- return this._scheduledResourceRequests[record.data["url"]];
-
- case recordTypes.FireAnimationFrame:
- return this._requestAnimationFrameRecords[record.data["id"]];
- }
- },
-
- setGlueRecords: function(glue)
- {
- this._glueRecords = glue;
- },
-
- invalidateFilteredRecords: function()
- {
- delete this._filteredRecords;
- },
-
- filteredRecords: function()
- {
- if (this._filteredRecords)
- return this._filteredRecords;
-
- var recordsInWindow = [];
- var stack = [{children: this._rootRecord.children, index: 0, parentIsCollapsed: false, parentRecord: {}}];
- var revealedDepth = 0;
-
- function revealRecordsInStack() {
- for (var depth = revealedDepth + 1; depth < stack.length; ++depth) {
- if (stack[depth - 1].parentIsCollapsed) {
- stack[depth].parentRecord.parent._expandable = true;
- return;
- }
- stack[depth - 1].parentRecord.collapsed = false;
- recordsInWindow.push(stack[depth].parentRecord);
- stack[depth].windowLengthBeforeChildrenTraversal = recordsInWindow.length;
- stack[depth].parentIsRevealed = true;
- revealedDepth = depth;
- }
- }
-
- while (stack.length) {
- var entry = stack[stack.length - 1];
- var records = entry.children;
- if (records && entry.index < records.length) {
- var record = records[entry.index];
- ++entry.index;
-
- if (this.isVisible(record)) {
- record.parent._expandable = true;
- if (this._searchFilter)
- revealRecordsInStack();
- if (!entry.parentIsCollapsed) {
- recordsInWindow.push(record);
- revealedDepth = stack.length;
- entry.parentRecord.collapsed = false;
- }
- }
-
- record._expandable = false;
-
- stack.push({children: record.children,
- index: 0,
- parentIsCollapsed: (entry.parentIsCollapsed || (record.collapsed && (!this._searchFilter || record.clicked))),
- parentRecord: record,
- windowLengthBeforeChildrenTraversal: recordsInWindow.length});
- } else {
- stack.pop();
- revealedDepth = Math.min(revealedDepth, stack.length - 1);
- entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
- }
- }
-
- this._filteredRecords = recordsInWindow;
- return recordsInWindow;
- },
-
- filteredFrames: function(startTime, endTime)
- {
- function compareStartTime(value, object)
- {
- return value - object.startTime;
- }
- function compareEndTime(value, object)
- {
- return value - object.endTime;
- }
- var firstFrame = insertionIndexForObjectInListSortedByFunction(startTime, this._frames, compareStartTime);
- var lastFrame = insertionIndexForObjectInListSortedByFunction(endTime, this._frames, compareEndTime);
- while (lastFrame < this._frames.length && this._frames[lastFrame].endTime <= endTime)
- ++lastFrame;
- return this._frames.slice(firstFrame, lastFrame);
- },
-
- eventDividerRecords: function()
- {
- return this._eventDividerRecords;
- },
-
- isVisible: function(record)
- {
- for (var i = 0; i < this._filters.length; ++i) {
- if (!this._filters[i].accept(record))
- return false;
- }
- return !this._searchFilter || this._searchFilter.accept(record);
- },
-
- /**
- * @param {{tasks: !Array.<{startTime: number, endTime: number}>, firstTaskIndex: number, lastTaskIndex: number}} info
- * @return {!Element}
- */
- generateMainThreadBarPopupContent: function(info)
- {
- var firstTaskIndex = info.firstTaskIndex;
- var lastTaskIndex = info.lastTaskIndex;
- var tasks = info.tasks;
- var messageCount = lastTaskIndex - firstTaskIndex + 1;
- var cpuTime = 0;
-
- for (var i = firstTaskIndex; i <= lastTaskIndex; ++i) {
- var task = tasks[i];
- cpuTime += WebInspector.TimelineModel.endTimeInSeconds(task) - WebInspector.TimelineModel.startTimeInSeconds(task);
- }
- var startTime = WebInspector.TimelineModel.startTimeInSeconds(tasks[firstTaskIndex]);
- var endTime = WebInspector.TimelineModel.endTimeInSeconds(tasks[lastTaskIndex]);
- var duration = endTime - startTime;
- var offset = this._minimumRecordTime;
-
- var contentHelper = new WebInspector.TimelinePopupContentHelper(info.name);
- var durationText = WebInspector.UIString("%s (at %s)", Number.secondsToString(duration, true),
- Number.secondsToString(startTime - offset, true));
- contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
- contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.secondsToString(cpuTime, true));
- contentHelper.appendTextRow(WebInspector.UIString("Message Count"), messageCount);
- return contentHelper.contentTable();
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {!WebInspector.TimelinePresentationModel} presentationModel
- * @param {!Object} record
- * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord
- * @param {?WebInspector.TimelinePresentationModel.Record} origin
- * @param {?Object} scriptDetails
- * @param {boolean} hidden
- */
-WebInspector.TimelinePresentationModel.Record = function(presentationModel, record, parentRecord, origin, scriptDetails, hidden)
-{
- this._linkifier = presentationModel._linkifier;
- this._aggregatedStats = {};
- this._record = record;
- this._children = [];
- if (!hidden && parentRecord) {
- this.parent = parentRecord;
- if (this.isBackground)
- WebInspector.TimelinePresentationModel.insertRetrospectiveRecord(parentRecord, this);
- else
- parentRecord.children.push(this);
- }
- if (origin)
- this._origin = origin;
-
- this._selfTime = this.endTime - this.startTime;
- this._lastChildEndTime = this.endTime;
- this._startTimeOffset = this.startTime - presentationModel._minimumRecordTime;
-
- if (record.data) {
- if (record.data["url"])
- this.url = record.data["url"];
- if (record.data["rootNode"])
- this._relatedBackendNodeId = record.data["rootNode"];
- else if (record.data["elementId"])
- this._relatedBackendNodeId = record.data["elementId"];
- }
- if (scriptDetails) {
- this.scriptName = scriptDetails.scriptName;
- this.scriptLine = scriptDetails.scriptLine;
- }
- if (parentRecord && parentRecord.callSiteStackTrace)
- this.callSiteStackTrace = parentRecord.callSiteStackTrace;
-
- var recordTypes = WebInspector.TimelineModel.RecordType;
- switch (record.type) {
- case recordTypes.ResourceSendRequest:
- // Make resource receive record last since request was sent; make finish record last since response received.
- presentationModel._sendRequestRecords[record.data["requestId"]] = this;
- break;
-
- case recordTypes.ScheduleResourceRequest:
- presentationModel._scheduledResourceRequests[record.data["url"]] = this;
- break;
-
- case recordTypes.ResourceReceiveResponse:
- var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
- if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
- this.url = sendRequestRecord.url;
- // Now that we have resource in the collection, recalculate details in order to display short url.
- sendRequestRecord._refreshDetails();
- if (sendRequestRecord.parent !== presentationModel._rootRecord && sendRequestRecord.parent.type === recordTypes.ScheduleResourceRequest)
- sendRequestRecord.parent._refreshDetails();
- }
- break;
-
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
- if (sendRequestRecord) // False for main resource.
- this.url = sendRequestRecord.url;
- break;
-
- case recordTypes.TimerInstall:
- this.timeout = record.data["timeout"];
- this.singleShot = record.data["singleShot"];
- presentationModel._timerRecords[record.data["timerId"]] = this;
- break;
-
- case recordTypes.TimerFire:
- var timerInstalledRecord = presentationModel._timerRecords[record.data["timerId"]];
- if (timerInstalledRecord) {
- this.callSiteStackTrace = timerInstalledRecord.stackTrace;
- this.timeout = timerInstalledRecord.timeout;
- this.singleShot = timerInstalledRecord.singleShot;
- }
- break;
-
- case recordTypes.RequestAnimationFrame:
- presentationModel._requestAnimationFrameRecords[record.data["id"]] = this;
- break;
-
- case recordTypes.FireAnimationFrame:
- var requestAnimationRecord = presentationModel._requestAnimationFrameRecords[record.data["id"]];
- if (requestAnimationRecord)
- this.callSiteStackTrace = requestAnimationRecord.stackTrace;
- break;
-
- case recordTypes.Time:
- if (record.data.isSynchronous)
- break;
- var message = record.data["message"];
- var oldReference = presentationModel._timeRecords[message];
- if (oldReference)
- break;
- presentationModel._timeRecords[message] = this;
- if (origin)
- presentationModel._timeRecordStack.push(this);
- break;
-
- case recordTypes.TimeEnd:
- var message = record.data["message"];
- var timeRecord = presentationModel._timeRecords[message];
- delete presentationModel._timeRecords[message];
- if (timeRecord) {
- this.timeRecord = timeRecord;
- timeRecord.timeEndRecord = this;
- var intervalDuration = this.startTime - timeRecord.startTime;
- this.intervalDuration = intervalDuration;
- timeRecord.intervalDuration = intervalDuration;
- }
- break;
-
- case recordTypes.ScheduleStyleRecalculation:
- presentationModel._lastScheduleStyleRecalculation[this.frameId] = this;
- break;
-
- case recordTypes.RecalculateStyles:
- var scheduleStyleRecalculationRecord = presentationModel._lastScheduleStyleRecalculation[this.frameId];
- if (!scheduleStyleRecalculationRecord)
- break;
- this.callSiteStackTrace = scheduleStyleRecalculationRecord.stackTrace;
- break;
-
- case recordTypes.InvalidateLayout:
- // Consider style recalculation as a reason for layout invalidation,
- // but only if we had no earlier layout invalidation records.
- var styleRecalcStack;
- if (!presentationModel._layoutInvalidateStack[this.frameId]) {
- for (var outerRecord = parentRecord; outerRecord; outerRecord = record.parent) {
- if (outerRecord.type === recordTypes.RecalculateStyles) {
- styleRecalcStack = outerRecord.callSiteStackTrace;
- break;
- }
- }
- }
- presentationModel._layoutInvalidateStack[this.frameId] = styleRecalcStack || this.stackTrace;
- break;
-
- case recordTypes.Layout:
- var layoutInvalidateStack = presentationModel._layoutInvalidateStack[this.frameId];
- if (layoutInvalidateStack)
- this.callSiteStackTrace = layoutInvalidateStack;
- if (this.stackTrace)
- this.addWarning(WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck."));
-
- presentationModel._layoutInvalidateStack[this.frameId] = null;
- this.highlightQuad = record.data.root || WebInspector.TimelinePresentationModel.quadFromRectData(record.data);
- this._relatedBackendNodeId = record.data["rootNode"];
- break;
-
- case recordTypes.AutosizeText:
- if (record.data.needsRelayout && parentRecord.type === recordTypes.Layout)
- parentRecord.addWarning(WebInspector.UIString("Layout required two passes due to text autosizing, consider setting viewport."));
- break;
-
- case recordTypes.Paint:
- this.highlightQuad = record.data.clip || WebInspector.TimelinePresentationModel.quadFromRectData(record.data);
- break;
-
- case recordTypes.WebSocketCreate:
- this.webSocketURL = record.data["url"];
- if (typeof record.data["webSocketProtocol"] !== "undefined")
- this.webSocketProtocol = record.data["webSocketProtocol"];
- presentationModel._webSocketCreateRecords[record.data["identifier"]] = this;
- break;
-
- case recordTypes.WebSocketSendHandshakeRequest:
- case recordTypes.WebSocketReceiveHandshakeResponse:
- case recordTypes.WebSocketDestroy:
- var webSocketCreateRecord = presentationModel._webSocketCreateRecords[record.data["identifier"]];
- if (webSocketCreateRecord) { // False if we started instrumentation in the middle of request.
- this.webSocketURL = webSocketCreateRecord.webSocketURL;
- if (typeof webSocketCreateRecord.webSocketProtocol !== "undefined")
- this.webSocketProtocol = webSocketCreateRecord.webSocketProtocol;
- }
- break;
- }
-}
-
-WebInspector.TimelinePresentationModel.adoptRecord = function(newParent, record)
-{
- record.parent.children.splice(record.parent.children.indexOf(record));
- WebInspector.TimelinePresentationModel.insertRetrospectiveRecord(newParent, record);
- record.parent = newParent;
-}
-
-WebInspector.TimelinePresentationModel.insertRetrospectiveRecord = function(parent, record)
-{
- function compareStartTime(value, record)
- {
- return value < record.startTime ? -1 : 1;
- }
-
- parent.children.splice(insertionIndexForObjectInListSortedByFunction(record.startTime, parent.children, compareStartTime), 0, record);
-}
-
-WebInspector.TimelinePresentationModel.Record.prototype = {
- get lastChildEndTime()
- {
- return this._lastChildEndTime;
- },
-
- set lastChildEndTime(time)
- {
- this._lastChildEndTime = time;
- },
-
- get selfTime()
- {
- return this.coalesced ? this._lastChildEndTime - this.startTime : this._selfTime;
- },
-
- set selfTime(time)
- {
- this._selfTime = time;
- },
-
- get cpuTime()
- {
- return this._cpuTime;
- },
-
- /**
- * @return {boolean}
- */
- isRoot: function()
- {
- return this.type === WebInspector.TimelineModel.RecordType.Root;
- },
-
- /**
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- origin: function()
- {
- return this._origin || this.parent;
- },
-
- /**
- * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
- */
- get children()
- {
- return this._children;
- },
-
- /**
- * @return {number}
- */
- get visibleChildrenCount()
- {
- return this._visibleChildrenCount || 0;
- },
-
- /**
- * @return {boolean}
- */
- get expandable()
- {
- return !!this._expandable;
- },
-
- /**
- * @return {!WebInspector.TimelineCategory}
- */
- get category()
- {
- return WebInspector.TimelinePresentationModel.recordStyle(this._record).category
- },
-
- /**
- * @return {string}
- */
- get title()
- {
- return this.type === WebInspector.TimelineModel.RecordType.TimeStamp ? this._record.data["message"] :
- WebInspector.TimelinePresentationModel.recordStyle(this._record).title;
- },
-
- /**
- * @return {number}
- */
- get startTime()
- {
- return WebInspector.TimelineModel.startTimeInSeconds(this._record);
- },
-
- /**
- * @return {number}
- */
- get endTime()
- {
- return WebInspector.TimelineModel.endTimeInSeconds(this._record);
- },
-
- /**
- * @return {boolean}
- */
- get isBackground()
- {
- return !!this._record.thread;
- },
-
- /**
- * @return {!Object}
- */
- get data()
- {
- return this._record.data;
- },
-
- /**
- * @return {string}
- */
- get type()
- {
- return this._record.type;
- },
-
- /**
- * @return {string}
- */
- get frameId()
- {
- return this._record.frameId;
- },
-
- /**
- * @return {number}
- */
- get usedHeapSizeDelta()
- {
- return this._record.usedHeapSizeDelta || 0;
- },
-
- /**
- * @return {number}
- */
- get usedHeapSize()
- {
- return this._record.usedHeapSize;
- },
-
- /**
- * @return {?Array.<!ConsoleAgent.CallFrame>}
- */
- get stackTrace()
- {
- if (this._record.stackTrace && this._record.stackTrace.length)
- return this._record.stackTrace;
- return null;
- },
-
- containsTime: function(time)
- {
- return this.startTime <= time && time <= this.endTime;
- },
-
- /**
- * @param {function(!DocumentFragment)} callback
- */
- generatePopupContent: function(callback)
- {
- var barrier = new CallbackBarrier();
- if (WebInspector.TimelinePresentationModel.needsPreviewElement(this.type) && !this._imagePreviewElement)
- WebInspector.DOMPresentationUtils.buildImagePreviewContents(this.url, false, barrier.createCallback(this._setImagePreviewElement.bind(this)));
- if (this._relatedBackendNodeId && !this._relatedNode)
- WebInspector.domAgent.pushNodeByBackendIdToFrontend(this._relatedBackendNodeId, barrier.createCallback(this._setRelatedNode.bind(this)));
-
- barrier.callWhenDone(callbackWrapper.bind(this));
-
- /**
- * @this {WebInspector.TimelinePresentationModel.Record}
- */
- function callbackWrapper()
- {
- callback(this._generatePopupContentSynchronously());
- }
- },
-
- /**
- * @param {string} key
- * @return {?Object}
- */
- getUserObject: function(key)
- {
- if (!this._userObjects)
- return null;
- return this._userObjects.get(key);
- },
-
- /**
- * @param {string} key
- * @param {!Object} value
- */
- setUserObject: function(key, value)
- {
- if (!this._userObjects)
- this._userObjects = new StringMap();
- this._userObjects.put(key, value);
- },
-
- /**
- * @param {!Element} element
- */
- _setImagePreviewElement: function(element)
- {
- this._imagePreviewElement = element;
- },
-
- /**
- * @param {?DOMAgent.NodeId} nodeId
- */
- _setRelatedNode: function(nodeId)
- {
- if (typeof nodeId === "number")
- this._relatedNode = WebInspector.domAgent.nodeForId(nodeId);
- },
-
- /**
- * @return {!DocumentFragment}
- */
- _generatePopupContentSynchronously: function()
- {
- var fragment = document.createDocumentFragment();
- var pie = WebInspector.TimelinePresentationModel.generatePieChart(this._aggregatedStats, this.category.name);
- // Insert self time.
- if (!this.coalesced && this._children.length) {
- pie.pieChart.addSlice(this._selfTime, this.category.fillColorStop1);
- var rowElement = document.createElement("div");
- pie.footerElement.insertBefore(rowElement, pie.footerElement.firstChild);
- rowElement.createChild("div", "timeline-aggregated-category timeline-" + this.category.name);
- rowElement.createTextChild(WebInspector.UIString("%s %s (Self)", Number.secondsToString(this._selfTime, true), this.category.title));
- }
- fragment.appendChild(pie.element);
-
- var contentHelper = new WebInspector.TimelineDetailsContentHelper(true);
-
- if (this.coalesced)
- return fragment;
-
- const recordTypes = WebInspector.TimelineModel.RecordType;
-
- // The messages may vary per record type;
- var callSiteStackTraceLabel;
- var callStackLabel;
- var relatedNodeLabel;
-
- switch (this.type) {
- case recordTypes.GCEvent:
- contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(this.data["usedHeapSizeDelta"]));
- break;
- case recordTypes.TimerFire:
- callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
- // Fall-through intended.
-
- case recordTypes.TimerInstall:
- case recordTypes.TimerRemove:
- contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), this.data["timerId"]);
- if (typeof this.timeout === "number") {
- contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.secondsToString(this.timeout / 1000));
- contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !this.singleShot);
- }
- break;
- case recordTypes.FireAnimationFrame:
- callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested");
- contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), this.data["id"]);
- break;
- case recordTypes.FunctionCall:
- if (this.scriptName)
- contentHelper.appendElementRow(WebInspector.UIString("Location"), this._linkifyLocation(this.scriptName, this.scriptLine, 0));
- break;
- case recordTypes.ScheduleResourceRequest:
- case recordTypes.ResourceSendRequest:
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(this.url));
- if (this._imagePreviewElement)
- contentHelper.appendElementRow(WebInspector.UIString("Preview"), this._imagePreviewElement);
- if (this.data["requestMethod"])
- contentHelper.appendTextRow(WebInspector.UIString("Request Method"), this.data["requestMethod"]);
- if (typeof this.data["statusCode"] === "number")
- contentHelper.appendTextRow(WebInspector.UIString("Status Code"), this.data["statusCode"]);
- if (this.data["mimeType"])
- contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), this.data["mimeType"]);
- if (this.data["encodedDataLength"])
- contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", this.data["encodedDataLength"]));
- break;
- case recordTypes.EvaluateScript:
- if (this.data && this.url)
- contentHelper.appendElementRow(WebInspector.UIString("Script"), this._linkifyLocation(this.url, this.data["lineNumber"]));
- break;
- case recordTypes.Paint:
- var clip = this.data["clip"];
- if (clip) {
- contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1]));
- var clipWidth = WebInspector.TimelinePresentationModel.quadWidth(clip);
- var clipHeight = WebInspector.TimelinePresentationModel.quadHeight(clip);
- contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight));
- } else {
- // Backward compatibility: older version used x, y, width, height fields directly in data.
- if (typeof this.data["x"] !== "undefined" && typeof this.data["y"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data["x"], this.data["y"]));
- if (typeof this.data["width"] !== "undefined" && typeof this.data["height"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d\u2009\u00d7\u2009%d", this.data["width"], this.data["height"]));
- }
- // Fall-through intended.
-
- case recordTypes.PaintSetup:
- case recordTypes.Rasterize:
- case recordTypes.ScrollLayer:
- relatedNodeLabel = WebInspector.UIString("Layer root");
- break;
- case recordTypes.AutosizeText:
- relatedNodeLabel = WebInspector.UIString("Root node");
- break;
- case recordTypes.DecodeImage:
- case recordTypes.ResizeImage:
- relatedNodeLabel = WebInspector.UIString("Image element");
- if (this.url)
- contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(this.url));
- break;
- case recordTypes.RecalculateStyles: // We don't want to see default details.
- if (this.data["elementCount"])
- contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), this.data["elementCount"]);
- callStackLabel = WebInspector.UIString("Styles recalculation forced");
- break;
- case recordTypes.Layout:
- if (this.data["dirtyObjects"])
- contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), this.data["dirtyObjects"]);
- if (this.data["totalObjects"])
- contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), this.data["totalObjects"]);
- if (typeof this.data["partialLayout"] === "boolean") {
- contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
- this.data["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document"));
- }
- callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
- callStackLabel = WebInspector.UIString("Layout forced");
- relatedNodeLabel = WebInspector.UIString("Layout root");
- break;
- case recordTypes.Time:
- case recordTypes.TimeEnd:
- contentHelper.appendTextRow(WebInspector.UIString("Message"), this.data["message"]);
- if (typeof this.intervalDuration === "number")
- contentHelper.appendTextRow(WebInspector.UIString("Interval Duration"), Number.secondsToString(this.intervalDuration, true));
- break;
- case recordTypes.WebSocketCreate:
- case recordTypes.WebSocketSendHandshakeRequest:
- case recordTypes.WebSocketReceiveHandshakeResponse:
- case recordTypes.WebSocketDestroy:
- if (typeof this.webSocketURL !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("URL"), this.webSocketURL);
- if (typeof this.webSocketProtocol !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), this.webSocketProtocol);
- if (typeof this.data["message"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Message"), this.data["message"]);
- break;
- default:
- if (this.detailsNode())
- contentHelper.appendElementRow(WebInspector.UIString("Details"), this.detailsNode().childNodes[1].cloneNode());
- break;
- }
-
- if (this._relatedNode)
- contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString("Related node"), this._createNodeAnchor(this._relatedNode));
-
- if (this.scriptName && this.type !== recordTypes.FunctionCall)
- contentHelper.appendElementRow(WebInspector.UIString("Function Call"), this._linkifyLocation(this.scriptName, this.scriptLine, 0));
-
- if (this.usedHeapSize) {
- if (this.usedHeapSizeDelta) {
- var sign = this.usedHeapSizeDelta > 0 ? "+" : "-";
- contentHelper.appendTextRow(WebInspector.UIString("Used Heap Size"),
- WebInspector.UIString("%s (%s%s)", Number.bytesToString(this.usedHeapSize), sign, Number.bytesToString(Math.abs(this.usedHeapSizeDelta))));
- } else if (this.category === WebInspector.TimelinePresentationModel.categories().scripting)
- contentHelper.appendTextRow(WebInspector.UIString("Used Heap Size"), Number.bytesToString(this.usedHeapSize));
- }
-
- if (this.callSiteStackTrace)
- contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.UIString("Call Site stack"), this.callSiteStackTrace, this._linkifyCallFrame.bind(this));
-
- if (this.stackTrace)
- contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("Call Stack"), this.stackTrace, this._linkifyCallFrame.bind(this));
-
- if (this._warnings) {
- var ul = document.createElement("ul");
- for (var i = 0; i < this._warnings.length; ++i)
- ul.createChild("li").textContent = this._warnings[i];
- contentHelper.appendElementRow(WebInspector.UIString("Warning"), ul);
- }
- fragment.appendChild(contentHelper.element);
- return fragment;
- },
-
- /**
- * @param {!WebInspector.DOMAgent} node
- */
- _createNodeAnchor: function(node)
- {
- var span = document.createElement("span");
- span.classList.add("node-link");
- span.addEventListener("click", onClick, false);
- WebInspector.DOMPresentationUtils.decorateNodeLabel(node, span);
- function onClick()
- {
- WebInspector.showPanel("elements").revealAndSelectNode(node.id);
- }
- return span;
- },
-
- _refreshDetails: function()
- {
- delete this._detailsNode;
- },
-
- /**
- * @return {?Node}
- */
- detailsNode: function()
- {
- if (typeof this._detailsNode === "undefined") {
- this._detailsNode = this._getRecordDetails();
-
- if (this._detailsNode && !this.coalesced) {
- this._detailsNode.insertBefore(document.createTextNode("("), this._detailsNode.firstChild);
- this._detailsNode.appendChild(document.createTextNode(")"));
- }
- }
- return this._detailsNode;
- },
-
- _createSpanWithText: function(textContent)
- {
- var node = document.createElement("span");
- node.textContent = textContent;
- return node;
- },
-
- /**
- * @return {?Node}
- */
- _getRecordDetails: function()
- {
- var details;
- if (this.coalesced)
- return this._createSpanWithText(WebInspector.UIString("× %d", this.children.length));
-
- switch (this.type) {
- case WebInspector.TimelineModel.RecordType.GCEvent:
- details = WebInspector.UIString("%s collected", Number.bytesToString(this.data["usedHeapSizeDelta"]));
- break;
- case WebInspector.TimelineModel.RecordType.TimerFire:
- details = this._linkifyScriptLocation(this.data["timerId"]);
- break;
- case WebInspector.TimelineModel.RecordType.FunctionCall:
- if (this.scriptName)
- details = this._linkifyLocation(this.scriptName, this.scriptLine, 0);
- break;
- case WebInspector.TimelineModel.RecordType.FireAnimationFrame:
- details = this._linkifyScriptLocation(this.data["id"]);
- break;
- case WebInspector.TimelineModel.RecordType.EventDispatch:
- details = this.data ? this.data["type"] : null;
- break;
- case WebInspector.TimelineModel.RecordType.Paint:
- var width = this.data.clip ? WebInspector.TimelinePresentationModel.quadWidth(this.data.clip) : this.data.width;
- var height = this.data.clip ? WebInspector.TimelinePresentationModel.quadHeight(this.data.clip) : this.data.height;
- if (width && height)
- details = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
- break;
- case WebInspector.TimelineModel.RecordType.TimerInstall:
- case WebInspector.TimelineModel.RecordType.TimerRemove:
- details = this._linkifyTopCallFrame(this.data["timerId"]);
- break;
- case WebInspector.TimelineModel.RecordType.RequestAnimationFrame:
- case WebInspector.TimelineModel.RecordType.CancelAnimationFrame:
- details = this._linkifyTopCallFrame(this.data["id"]);
- break;
- case WebInspector.TimelineModel.RecordType.ParseHTML:
- case WebInspector.TimelineModel.RecordType.RecalculateStyles:
- details = this._linkifyTopCallFrame();
- break;
- case WebInspector.TimelineModel.RecordType.EvaluateScript:
- details = this.url ? this._linkifyLocation(this.url, this.data["lineNumber"], 0) : null;
- break;
- case WebInspector.TimelineModel.RecordType.XHRReadyStateChange:
- case WebInspector.TimelineModel.RecordType.XHRLoad:
- case WebInspector.TimelineModel.RecordType.ScheduleResourceRequest:
- case WebInspector.TimelineModel.RecordType.ResourceSendRequest:
- case WebInspector.TimelineModel.RecordType.ResourceReceivedData:
- case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse:
- case WebInspector.TimelineModel.RecordType.ResourceFinish:
- case WebInspector.TimelineModel.RecordType.DecodeImage:
- case WebInspector.TimelineModel.RecordType.ResizeImage:
- details = WebInspector.displayNameForURL(this.url);
- break;
- case WebInspector.TimelineModel.RecordType.Time:
- case WebInspector.TimelineModel.RecordType.TimeEnd:
- details = this.data["message"];
- break;
- default:
- details = this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : (this._linkifyTopCallFrame() || null);
- break;
- }
-
- if (details) {
- if (details instanceof Node)
- details.tabIndex = -1;
- else
- return this._createSpanWithText("" + details);
- }
-
- return details || null;
- },
-
- /**
- * @param {string} url
- * @param {number} lineNumber
- * @param {number=} columnNumber
- */
- _linkifyLocation: function(url, lineNumber, columnNumber)
- {
- // FIXME(62725): stack trace line/column numbers are one-based.
- columnNumber = columnNumber ? columnNumber - 1 : 0;
- return this._linkifier.linkifyLocation(url, lineNumber - 1, columnNumber, "timeline-details");
- },
-
- /**
- * @param {!ConsoleAgent.CallFrame} callFrame
- */
- _linkifyCallFrame: function(callFrame)
- {
- return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
- },
-
- /**
- * @param {string=} defaultValue
- */
- _linkifyTopCallFrame: function(defaultValue)
- {
- if (this.stackTrace)
- return this._linkifyCallFrame(this.stackTrace[0]);
- if (this.callSiteStackTrace)
- return this._linkifyCallFrame(this.callSiteStackTrace[0]);
- return defaultValue;
- },
-
- /**
- * @param {*} defaultValue
- * @return {!Element|string}
- */
- _linkifyScriptLocation: function(defaultValue)
- {
- return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : "" + defaultValue;
- },
-
- calculateAggregatedStats: function()
- {
- this._aggregatedStats = {};
- this._cpuTime = this._selfTime;
-
- for (var index = this._children.length; index; --index) {
- var child = this._children[index - 1];
- for (var category in child._aggregatedStats)
- this._aggregatedStats[category] = (this._aggregatedStats[category] || 0) + child._aggregatedStats[category];
- }
- for (var category in this._aggregatedStats)
- this._cpuTime += this._aggregatedStats[category];
- this._aggregatedStats[this.category.name] = (this._aggregatedStats[this.category.name] || 0) + this._selfTime;
- },
-
- get aggregatedStats()
- {
- return this._aggregatedStats;
- },
-
- /**
- * @param {string} message
- */
- addWarning: function(message)
- {
- if (this._warnings)
- this._warnings.push(message);
- else
- this._warnings = [message];
- for (var parent = this.parent; parent && !parent._childHasWarnings; parent = parent.parent)
- parent._childHasWarnings = true;
- },
-
- /**
- * @return {boolean}
- */
- hasWarnings: function()
- {
- return !!this._warnings;
- },
-
- /**
- * @return {boolean}
- */
- childHasWarnings: function()
- {
- return this._childHasWarnings;
- }
-}
-
-/**
- * @param {!Object} aggregatedStats
- */
-WebInspector.TimelinePresentationModel._generateAggregatedInfo = function(aggregatedStats)
-{
- var cell = document.createElement("span");
- cell.className = "timeline-aggregated-info";
- for (var index in aggregatedStats) {
- var label = document.createElement("div");
- label.className = "timeline-aggregated-category timeline-" + index;
- cell.appendChild(label);
- var text = document.createElement("span");
- text.textContent = Number.secondsToString(aggregatedStats[index], true);
- cell.appendChild(text);
- }
- return cell;
-}
-
-/**
- * @param {!Object} aggregatedStats
- * @param {string=} firstCategoryName
- * @return {{pieChart: !WebInspector.PieChart, element: !Element, footerElement: !Element}}
- */
-WebInspector.TimelinePresentationModel.generatePieChart = function(aggregatedStats, firstCategoryName)
-{
- var element = document.createElement("div");
- element.className = "timeline-aggregated-info";
-
- var total = 0;
- var categoryNames = [];
- if (firstCategoryName)
- categoryNames.push(firstCategoryName);
- for (var categoryName in WebInspector.TimelinePresentationModel.categories()) {
- if (aggregatedStats[categoryName]) {
- total += aggregatedStats[categoryName];
- if (firstCategoryName !== categoryName)
- categoryNames.push(categoryName);
- }
- }
-
- var pieChart = new WebInspector.PieChart(total);
- element.appendChild(pieChart.element);
- var footerElement = element.createChild("div", "timeline-aggregated-info-legend");
-
- for (var i = 0; i < categoryNames.length; ++i) {
- var category = WebInspector.TimelinePresentationModel.categories()[categoryNames[i]];
- pieChart.addSlice(aggregatedStats[category.name], category.fillColorStop0);
- var rowElement = footerElement.createChild("div");
- rowElement.createChild("div", "timeline-aggregated-category timeline-" + category.name);
- rowElement.createTextChild(WebInspector.UIString("%s %s", Number.secondsToString(aggregatedStats[category.name], true), category.title));
- }
- return { pieChart: pieChart, element: element, footerElement: footerElement };
-}
-
-WebInspector.TimelinePresentationModel.generatePopupContentForFrame = function(frame)
-{
- var contentHelper = new WebInspector.TimelinePopupContentHelper(WebInspector.UIString("Frame"));
- var durationInSeconds = frame.endTime - frame.startTime;
- var durationText = WebInspector.UIString("%s (at %s)", Number.secondsToString(frame.endTime - frame.startTime, true),
- Number.secondsToString(frame.startTimeOffset, true));
- contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
- contentHelper.appendTextRow(WebInspector.UIString("FPS"), Math.floor(1 / durationInSeconds));
- contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.secondsToString(frame.cpuTime, true));
- contentHelper.appendTextRow(WebInspector.UIString("Thread"), frame.isBackground ? WebInspector.UIString("background") : WebInspector.UIString("main"));
- contentHelper.appendElementRow(WebInspector.UIString("Aggregated Time"),
- WebInspector.TimelinePresentationModel._generateAggregatedInfo(frame.timeByCategory));
- return contentHelper.contentTable();
-}
-
-/**
- * @param {!WebInspector.FrameStatistics} statistics
- */
-WebInspector.TimelinePresentationModel.generatePopupContentForFrameStatistics = function(statistics)
-{
- /**
- * @param {number} time
- */
- function formatTimeAndFPS(time)
- {
- return WebInspector.UIString("%s (%.0f FPS)", Number.secondsToString(time, true), 1 / time);
- }
-
- var contentHelper = new WebInspector.TimelineDetailsContentHelper(false);
- contentHelper.appendTextRow(WebInspector.UIString("Minimum Time"), formatTimeAndFPS(statistics.minDuration));
- contentHelper.appendTextRow(WebInspector.UIString("Average Time"), formatTimeAndFPS(statistics.average));
- contentHelper.appendTextRow(WebInspector.UIString("Maximum Time"), formatTimeAndFPS(statistics.maxDuration));
- contentHelper.appendTextRow(WebInspector.UIString("Standard Deviation"), Number.secondsToString(statistics.stddev, true));
-
- return contentHelper.element;
-}
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {number} width
- * @param {number} height
- * @param {string} color0
- * @param {string} color1
- * @param {string} color2
- */
-WebInspector.TimelinePresentationModel.createFillStyle = function(context, width, height, color0, color1, color2)
-{
- var gradient = context.createLinearGradient(0, 0, width, height);
- gradient.addColorStop(0, color0);
- gradient.addColorStop(0.25, color1);
- gradient.addColorStop(0.75, color1);
- gradient.addColorStop(1, color2);
- return gradient;
-}
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {number} width
- * @param {number} height
- * @param {!WebInspector.TimelineCategory} category
- */
-WebInspector.TimelinePresentationModel.createFillStyleForCategory = function(context, width, height, category)
-{
- return WebInspector.TimelinePresentationModel.createFillStyle(context, width, height, category.fillColorStop0, category.fillColorStop1, category.borderColor);
-}
-
-/**
- * @param {!WebInspector.TimelineCategory} category
- */
-WebInspector.TimelinePresentationModel.createStyleRuleForCategory = function(category)
-{
- var selector = ".timeline-category-" + category.name + " .timeline-graph-bar, " +
- ".panel.timeline .timeline-filters-header .filter-checkbox-filter.filter-checkbox-filter-" + category.name + " .checkbox-filter-checkbox, " +
- ".popover .timeline-" + category.name + ", " +
- ".timeline-details-view .timeline-" + category.name + ", " +
- ".timeline-category-" + category.name + " .timeline-tree-icon"
-
- return selector + " { background-image: -webkit-linear-gradient(" +
- category.fillColorStop0 + ", " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + ");" +
- " border-color: " + category.borderColor +
- "}";
-}
-
-
-/**
- * @param {!Object} rawRecord
- * @return {?string}
- */
-WebInspector.TimelinePresentationModel.coalescingKeyForRecord = function(rawRecord)
-{
- var recordTypes = WebInspector.TimelineModel.RecordType;
- switch (rawRecord.type)
- {
- case recordTypes.EventDispatch: return rawRecord.data["type"];
- case recordTypes.Time: return rawRecord.data["message"];
- case recordTypes.TimeStamp: return rawRecord.data["message"];
- default: return null;
- }
-}
-
-/**
- * @param {!Array.<number>} quad
- * @return {number}
- */
-WebInspector.TimelinePresentationModel.quadWidth = function(quad)
-{
- return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1] - quad[3], 2)));
-}
-
-/**
- * @param {!Array.<number>} quad
- * @return {number}
- */
-WebInspector.TimelinePresentationModel.quadHeight = function(quad)
-{
- return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1] - quad[7], 2)));
-}
-
-/**
- * @param {!Object} data
- * @return {?Array.<number>}
- */
-WebInspector.TimelinePresentationModel.quadFromRectData = function(data)
-{
- if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined")
- return null;
- var x0 = data["x"];
- var x1 = data["x"] + data["width"];
- var y0 = data["y"];
- var y1 = data["y"] + data["height"];
- return [x0, y0, x1, y0, x1, y1, x0, y1];
-}
-
-/**
- * @interface
- */
-WebInspector.TimelinePresentationModel.Filter = function()
-{
-}
-
-WebInspector.TimelinePresentationModel.Filter.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record) { return false; }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- * @param {string} name
- * @param {string} title
- * @param {number} overviewStripGroupIndex
- * @param {string} borderColor
- * @param {string} fillColorStop0
- * @param {string} fillColorStop1
- */
-WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, borderColor, fillColorStop0, fillColorStop1)
-{
- this.name = name;
- this.title = title;
- this.overviewStripGroupIndex = overviewStripGroupIndex;
- this.borderColor = borderColor;
- this.fillColorStop0 = fillColorStop0;
- this.fillColorStop1 = fillColorStop1;
- this.hidden = false;
-}
-
-WebInspector.TimelineCategory.Events = {
- VisibilityChanged: "VisibilityChanged"
-};
-
-WebInspector.TimelineCategory.prototype = {
- /**
- * @return {boolean}
- */
- get hidden()
- {
- return this._hidden;
- },
-
- set hidden(hidden)
- {
- this._hidden = hidden;
- this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged, this);
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {string} title
- */
-WebInspector.TimelinePopupContentHelper = function(title)
-{
- this._contentTable = document.createElement("table");
- var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title");
- titleCell.colSpan = 2;
- var titleRow = document.createElement("tr");
- titleRow.appendChild(titleCell);
- this._contentTable.appendChild(titleRow);
-}
-
-WebInspector.TimelinePopupContentHelper.prototype = {
- contentTable: function()
- {
- return this._contentTable;
- },
-
- /**
- * @param {string=} styleName
- */
- _createCell: function(content, styleName)
- {
- var text = document.createElement("label");
- text.appendChild(document.createTextNode(content));
- var cell = document.createElement("td");
- cell.className = "timeline-details";
- if (styleName)
- cell.className += " " + styleName;
- cell.textContent = content;
- return cell;
- },
-
- /**
- * @param {string} title
- * @param {string|number|boolean} content
- */
- appendTextRow: function(title, content)
- {
- var row = document.createElement("tr");
- row.appendChild(this._createCell(title, "timeline-details-row-title"));
- row.appendChild(this._createCell(content, "timeline-details-row-data"));
- this._contentTable.appendChild(row);
- },
-
- /**
- * @param {string} title
- * @param {!Element|string} content
- */
- appendElementRow: function(title, content)
- {
- var row = document.createElement("tr");
- var titleCell = this._createCell(title, "timeline-details-row-title");
- row.appendChild(titleCell);
- var cell = document.createElement("td");
- cell.className = "details";
- if (content instanceof Node)
- cell.appendChild(content);
- else
- cell.createTextChild(content || "");
- row.appendChild(cell);
- this._contentTable.appendChild(row);
- }
-}
-
-/**
- * @constructor
- * @param {boolean} monospaceValues
- */
-WebInspector.TimelineDetailsContentHelper = function(monospaceValues)
-{
- this.element = document.createElement("div");
- this.element.className = "timeline-details-view-block";
- this._monospaceValues = monospaceValues;
-}
-
-WebInspector.TimelineDetailsContentHelper.prototype = {
- /**
- * @param {string} title
- * @param {string|number|boolean} value
- */
- appendTextRow: function(title, value)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- rowElement.createChild("span", "timeline-details-view-row-value" + (this._monospaceValues ? " monospace" : "")).textContent = value;
- },
-
- /**
- * @param {string} title
- * @param {!Element|string} content
- */
- appendElementRow: function(title, content)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- var valueElement = rowElement.createChild("span", "timeline-details-view-row-details" + (this._monospaceValues ? " monospace" : ""));
- if (content instanceof Node)
- valueElement.appendChild(content);
- else
- valueElement.createTextChild(content || "");
- },
-
- /**
- * @param {string} title
- * @param {!Array.<!ConsoleAgent.CallFrame>} stackTrace
- * @param {function(!ConsoleAgent.CallFrame)} callFrameLinkifier
- */
- appendStackTrace: function(title, stackTrace, callFrameLinkifier)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- var stackTraceElement = rowElement.createChild("div", "timeline-details-view-row-stack-trace monospace");
-
- for (var i = 0; i < stackTrace.length; ++i) {
- var stackFrame = stackTrace[i];
- var row = stackTraceElement.createChild("div");
- row.createTextChild(stackFrame.functionName || WebInspector.UIString("(anonymous function)"));
- row.createTextChild(" @ ");
- var urlElement = callFrameLinkifier(stackFrame);
- row.appendChild(urlElement);
- }
- }
-}