summaryrefslogtreecommitdiff
path: root/Source/WebInspectorUI/UserInterface/TimelineManager.js
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/TimelineManager.js')
-rw-r--r--Source/WebInspectorUI/UserInterface/TimelineManager.js445
1 files changed, 0 insertions, 445 deletions
diff --git a/Source/WebInspectorUI/UserInterface/TimelineManager.js b/Source/WebInspectorUI/UserInterface/TimelineManager.js
deleted file mode 100644
index 0bea0c7f8..000000000
--- a/Source/WebInspectorUI/UserInterface/TimelineManager.js
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2013 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-WebInspector.TimelineManager = function()
-{
- WebInspector.Object.call(this);
-
- WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadStarted, this._startAutoRecording, this);
- WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
- WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
-
- this._recording = new WebInspector.TimelineRecording;
- this._recordingEnabled = false;
-};
-
-WebInspector.TimelineManager.Event = {
- RecordingStarted: "timeline-manager-recording-started",
- RecordingStopped: "timeline-manager-recording-stopped"
-};
-
-WebInspector.TimelineManager.MaximumAutoRecordDuration = 90000; // 90 seconds
-WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent = 10000; // 10 seconds
-WebInspector.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly = 2000; // 2 seconds
-
-WebInspector.TimelineManager.prototype = {
- constructor: WebInspector.TimelineManager,
-
- // Public
-
- get recording()
- {
- return this._recording;
- },
-
- get recordingEnabled()
- {
- return this._recordingEnabled;
- },
-
- startRecording: function()
- {
- if (this._recordingEnabled)
- return;
-
- this._recordingEnabled = true;
-
- TimelineAgent.start();
-
- this.dispatchEventToListeners(WebInspector.TimelineManager.Event.RecordingStarted);
- },
-
- stopRecording: function()
- {
- if (!this._recordingEnabled)
- return;
-
- if (this._stopRecordingTimeout) {
- clearTimeout(this._stopRecordingTimeout);
- delete this._stopRecordingTimeout;
- }
-
- if (this._deadTimeTimeout) {
- clearTimeout(this._deadTimeTimeout);
- delete this._deadTimeTimeout;
- }
-
- TimelineAgent.stop();
-
- this._recordingEnabled = false;
- this._autoRecordingMainResource = null;
-
- this.dispatchEventToListeners(WebInspector.TimelineManager.Event.RecordingStopped);
- },
-
- eventRecorded: function(originalRecordPayload)
- {
- // Called from WebInspector.TimelineObserver.
-
- if (!this._recordingEnabled)
- return;
-
- function processRecord(recordPayload, parentRecordPayload)
- {
- // Convert the timestamps to seconds to match the resource timestamps.
- var startTime = recordPayload.startTime / 1000;
- var endTime = recordPayload.endTime / 1000;
-
- var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
-
- var significantCallFrame = null;
- if (callFrames) {
- for (var i = 0; i < callFrames.length; ++i) {
- if (callFrames[i].nativeCode)
- continue;
- significantCallFrame = callFrames[i];
- break;
- }
- }
-
- var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation;
-
- switch (recordPayload.type) {
- case TimelineAgent.EventType.MarkLoad:
- console.assert(isNaN(endTime));
-
- var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
- console.assert(frame);
- if (!frame)
- break;
-
- frame.markLoadEvent(startTime);
-
- if (!frame.isMainFrame())
- break;
-
- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.LoadEvent);
- this._recording.addEventMarker(eventMarker);
-
- this._stopAutoRecordingSoon();
- break;
-
- case TimelineAgent.EventType.MarkDOMContent:
- console.assert(isNaN(endTime));
-
- var frame = WebInspector.frameResourceManager.frameForIdentifier(recordPayload.frameId);
- console.assert(frame);
- if (!frame)
- break;
-
- frame.markDOMContentReadyEvent(startTime);
-
- if (!frame.isMainFrame())
- break;
-
- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.DOMContentEvent);
- this._recording.addEventMarker(eventMarker);
- break;
-
- case TimelineAgent.EventType.ScheduleStyleRecalculation:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation));
- break;
-
- case TimelineAgent.EventType.RecalculateStyles:
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation));
- break;
-
- case TimelineAgent.EventType.InvalidateLayout:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation));
- break;
-
- case TimelineAgent.EventType.Layout:
- // COMPATIBILITY (iOS 6): Layout records did not contain area properties. This is not exposed via a quad "root".
- var quad = recordPayload.data.root ? new WebInspector.Quad(recordPayload.data.root) : null;
- if (quad)
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Layout, startTime, endTime, callFrames, sourceCodeLocation, quad.points[0].x, quad.points[0].y, quad.width, quad.height, quad));
- else
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Layout, startTime, endTime, callFrames, sourceCodeLocation));
- break;
-
- case TimelineAgent.EventType.Paint:
- // COMPATIBILITY (iOS 6): Paint records data contained x, y, width, height properties. This became a quad "clip".
- var quad = recordPayload.data.clip ? new WebInspector.Quad(recordPayload.data.clip) : null;
- if (quad)
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, null, null, quad.width, quad.height, quad));
- else
- this._addRecord(new WebInspector.LayoutTimelineRecord(WebInspector.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.x, recordPayload.data.y, recordPayload.data.width, recordPayload.data.height));
- break;
-
- case TimelineAgent.EventType.EvaluateScript:
- if (!sourceCodeLocation) {
- var mainFrame = WebInspector.frameResourceManager.mainFrame;
- var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true);
- if (scriptResource) {
- // The lineNumber is 1-based, but we expect 0-based.
- var lineNumber = recordPayload.data.lineNumber - 1;
-
- // FIXME: No column number is provided.
- sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
- }
- }
-
- switch (parentRecordPayload && parentRecordPayload.type) {
- case TimelineAgent.EventType.TimerFire:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId));
- break;
- default:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null));
- break;
- }
-
- break;
-
- case TimelineAgent.EventType.TimeStamp:
- var eventMarker = new WebInspector.TimelineMarker(startTime, WebInspector.TimelineMarker.Type.TimeStamp);
- this._recording.addEventMarker(eventMarker);
- break;
-
- case TimelineAgent.EventType.FunctionCall:
- // FunctionCall always happens as a child of another record, and since the FunctionCall record
- // has useful info we just make the timeline record here (combining the data from both records).
- if (!parentRecordPayload)
- break;
-
- if (!sourceCodeLocation) {
- var mainFrame = WebInspector.frameResourceManager.mainFrame;
- var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true);
- if (scriptResource) {
- // The lineNumber is 1-based, but we expect 0-based.
- var lineNumber = recordPayload.data.scriptLine - 1;
-
- // FIXME: No column number is provided.
- sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, 0);
- }
- }
-
- switch (parentRecordPayload.type) {
- case TimelineAgent.EventType.TimerFire:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId));
- break;
- case TimelineAgent.EventType.EventDispatch:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type));
- break;
- case TimelineAgent.EventType.XHRLoad:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "load"));
- break;
- case TimelineAgent.EventType.XHRReadyStateChange:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, "readystatechange"));
- break;
- case TimelineAgent.EventType.FireAnimationFrame:
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id));
- break;
- }
-
- break;
-
- case TimelineAgent.EventType.TimerInstall:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
- break;
-
- case TimelineAgent.EventType.TimerRemove:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
- break;
-
- case TimelineAgent.EventType.RequestAnimationFrame:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
- break;
-
- case TimelineAgent.EventType.CancelAnimationFrame:
- console.assert(isNaN(endTime));
-
- // Pass the startTime as the endTime since this record type has no duration.
- this._addRecord(new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId));
- break;
- }
- }
-
- // Iterate over the records tree using a stack. Doing this recursively has
- // been known to cause a call stack overflow. https://webkit.org/b/79106
- var stack = [{array: [originalRecordPayload], parent: null, index: 0}];
- while (stack.length) {
- var entry = stack.lastValue;
- var recordPayloads = entry.array;
- var parentRecordPayload = entry.parent;
-
- if (entry.index < recordPayloads.length) {
- var recordPayload = recordPayloads[entry.index];
-
- processRecord.call(this, recordPayload, parentRecordPayload);
-
- if (recordPayload.children)
- stack.push({array: recordPayload.children, parent: recordPayload, index: 0});
- ++entry.index;
- } else
- stack.pop();
- }
- },
-
- pageDidLoad: function(timestamp)
- {
- if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
- WebInspector.frameResourceManager.mainFrame.markLoadEvent(timestamp);
- },
-
- // Private
-
- _callFramesFromPayload: function(payload)
- {
- if (!payload)
- return null;
-
- function createCallFrame(payload)
- {
- var url = payload.url;
- var nativeCode = false;
-
- if (url === "[native code]") {
- nativeCode = true;
- url = null;
- }
-
- var sourceCode = WebInspector.frameResourceManager.resourceForURL(url);
- if (!sourceCode)
- sourceCode = WebInspector.debuggerManager.scriptsForURL(url)[0];
-
- // The lineNumber is 1-based, but we expect 0-based.
- var lineNumber = payload.lineNumber - 1;
-
- var sourceCodeLocation = sourceCode ? sourceCode.createSourceCodeLocation(lineNumber, payload.columnNumber) : null;
- var functionName = payload.functionName !== "global code" ? payload.functionName : null;
-
- return new WebInspector.CallFrame(null, sourceCodeLocation, functionName, null, null, nativeCode);
- }
-
- return payload.map(createCallFrame);
- },
-
- _addRecord: function(record)
- {
- this._recording.addRecord(record);
-
- // Only worry about dead time after the load event.
- if (!isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
- this._resetAutoRecordingDeadTimeTimeout();
- },
-
- _startAutoRecording: function(event)
- {
- if (!event.target.isMainFrame() || (this._recordingEnabled && !this._autoRecordingMainResource))
- return false;
-
- var mainResource = event.target.provisionalMainResource || event.target.mainResource;
- if (mainResource === this._autoRecordingMainResource)
- return false;
-
- this.stopRecording();
-
- this._autoRecordingMainResource = mainResource;
-
- this._recording.reset();
-
- this.startRecording();
-
- this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
-
- if (this._stopRecordingTimeout)
- clearTimeout(this._stopRecordingTimeout);
- this._stopRecordingTimeout = setTimeout(this.stopRecording.bind(this), WebInspector.TimelineManager.MaximumAutoRecordDuration);
-
- return true;
- },
-
- _stopAutoRecordingSoon: function()
- {
- // Only auto stop when auto recording.
- if (!this._recordingEnabled || !this._autoRecordingMainResource)
- return;
-
- if (this._stopRecordingTimeout)
- clearTimeout(this._stopRecordingTimeout);
- this._stopRecordingTimeout = setTimeout(this.stopRecording.bind(this), WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
- },
-
- _resetAutoRecordingDeadTimeTimeout: function()
- {
- // Only monitor dead time when auto recording.
- if (!this._recordingEnabled || !this._autoRecordingMainResource)
- return;
-
- if (this._deadTimeTimeout)
- clearTimeout(this._deadTimeTimeout);
- this._deadTimeTimeout = setTimeout(this.stopRecording.bind(this), WebInspector.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly);
- },
-
- _mainResourceDidChange: function(event)
- {
- // Ignore resource events when there isn't a main frame yet. Those events are triggered by
- // loading the cached resources when the inspector opens, and they do not have timing information.
- if (!WebInspector.frameResourceManager.mainFrame)
- return;
-
- if (this._startAutoRecording(event))
- return;
-
- if (!this._recordingEnabled)
- return;
-
- var mainResource = event.target.mainResource;
- if (mainResource === this._autoRecordingMainResource)
- return;
-
- this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
- },
-
- _resourceWasAdded: function(event)
- {
- // Ignore resource events when there isn't a main frame yet. Those events are triggered by
- // loading the cached resources when the inspector opens, and they do not have timing information.
- if (!WebInspector.frameResourceManager.mainFrame)
- return;
-
- if (!this._recordingEnabled)
- return;
-
- this._addRecord(new WebInspector.ResourceTimelineRecord(event.data.resource));
- }
-};
-
-WebInspector.TimelineManager.prototype.__proto__ = WebInspector.Object.prototype;