Timeline: quit using Progress, introduce TimelineLifecycleDelegate
- let TimelineLoader operate on TracingModel, not TimelineModel;
- introduce TimelineLifecycleDelegate, implemented by TimelinePanel;
- do not use Progress/ProgressIndicator in Timeline, use StatusPane instead
for consistency with recording and fetching;
- use callback, not event in TimelineStatusPane to indicate stop is requested;
- rename "Finish" to "Stop" in the status pane.
BUG=
Review URL: https://codereview.chromium.org/1755123003
Cr-Commit-Position: refs/heads/master@{#378898}
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
index 6ba202c..fe55ddb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -796,7 +796,6 @@
{
this._chunks = [];
this._name = name;
- this._size = 0;
}
InspectorTest.TempFileMock.prototype = {
@@ -806,10 +805,11 @@
*/
write: function(chunks, callback)
{
+ var size = 0;
for (var i = 0; i < chunks.length; ++i)
- this._size += chunks[i].length;
+ size += chunks[i].length;
this._chunks.push.apply(this._chunks, chunks);
- setTimeout(callback.bind(this, this._size), 1);
+ setTimeout(callback.bind(this, size), 1);
},
finishWriting: function() { },
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
index 2d9b050..e5e8d95 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -397,7 +397,7 @@
}
InspectorTest.override(WebInspector.TimelineLoader, "_createFileReader", createFileReader);
- WebInspector.TimelineLoader.loadFromFile(InspectorTest.timelineModel(), {}, new WebInspector.Progress());
+ timeline._loadFromFile({});
}
};
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load-expected.txt
index 9d01dc2..cf66b45 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load-expected.txt
@@ -2,18 +2,23 @@
Running: testNormal
+TimelineLifecycleDelegate.loadingStarted()
+TimelineLifecycleDelegate.loadingProgress()
+TimelineLifecycleDelegate.loadingComplete(true)
Saved data is equal to restored data: true
Running: testJSONObjectFormat
+TimelineLifecycleDelegate.loadingStarted()
+TimelineLifecycleDelegate.loadingProgress()
+TimelineLifecycleDelegate.loadingComplete(true)
Saved data is equal to restored data: true
Running: testBroken
-error: TracingStartedInPage event not found.
+TimelineLifecycleDelegate.loadingStarted()
+TimelineLifecycleDelegate.loadingComplete(true)
Model is empty: true
Running: testMalformedJSON
-error: TracingStartedInPage event not found.
-error: TracingStartedInPage event not found.
-error: TracingStartedInPage event not found.
+TimelineLifecycleDelegate.loadingComplete(false)
Model is empty: true
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
index 573909450..559c36e 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
@@ -7,10 +7,28 @@
function test()
{
+ InspectorTest.TestTimelineLifecycleDelegate = function() {}
+
+ InspectorTest.TestTimelineLifecycleDelegate.prototype = {
+ loadingStarted: function()
+ {
+ InspectorTest.addResult("TimelineLifecycleDelegate.loadingStarted()");
+ },
+
+ loadingProgress: function()
+ {
+ InspectorTest.addResult("TimelineLifecycleDelegate.loadingProgress()");
+ },
+
+ loadingComplete: function(success)
+ {
+ InspectorTest.addResult(`TimelineLifecycleDelegate.loadingComplete(${success})`);
+ },
+ }
+
function runTestWithDataAndCheck(input, expectedOutput, callback)
{
- InspectorTest.tracingModel().reset();
- var model = InspectorTest.tracingTimelineModel();
+ var model = InspectorTest.tracingModel();
model.reset();
var timeline = WebInspector.panels.timeline;
@@ -27,18 +45,20 @@
}
InspectorTest.override(WebInspector.TimelineLoader, "_createFileReader", createFileReader);
- WebInspector.TimelineLoader.loadFromFile(model, {}, new WebInspector.Progress());
+ WebInspector.TimelineLoader.loadFromFile(model, {}, new InspectorTest.TestTimelineLifecycleDelegate());
+ model.tracingComplete();
+ var saver = new WebInspector.TracingTimelineSaver();
var stream = new InspectorTest.StringOutputStream(InspectorTest.safeWrap(checkSaveData));
- var saver = new WebInspector.TracingTimelineSaver(stream);
var storage = timeline._tracingModelBackingStorage;
stream.open("", storage.writeToStream.bind(storage, stream, saver));
}
function runTestOnMalformedInput(input, callback)
{
- InspectorTest.tracingModel().reset();
- var model = InspectorTest.tracingTimelineModel();
+ var model = InspectorTest.tracingModel();
+ var timeline = WebInspector.panels.timeline;
+
model.reset();
function createFileReader(file, delegate)
@@ -48,12 +68,12 @@
function checkLoadedData(data)
{
- InspectorTest.addResult("Model is empty: " + model.isEmpty());
+ InspectorTest.addResult("Model is empty: " + (!model.minimumRecordTime() && !model.maximumRecordTime()));
callback();
}
InspectorTest.override(WebInspector.TimelineLoader, "_createFileReader", createFileReader);
- WebInspector.TimelineLoader.loadFromFile(model, {}, new WebInspector.Progress());
+ WebInspector.TimelineLoader.loadFromFile(model, {}, new InspectorTest.TestTimelineLifecycleDelegate());
}
var data = [{"args":{"number":32},"cat":"__metadata","name":"num_cpus","ph":"M","pid":32127,"tid":0,"ts":0},
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
index 8b786f8e..051bd61 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
@@ -6,23 +6,20 @@
* @constructor
* @implements {WebInspector.OutputStream}
* @implements {WebInspector.OutputStreamDelegate}
- * @param {!WebInspector.TimelineModel} model
- * @param {!WebInspector.Progress} progress
+ * @param {!WebInspector.TracingModel} model
+ * @param {!WebInspector.TimelineLifecycleDelegate} delegate
*/
-WebInspector.TimelineLoader = function(model, progress)
+WebInspector.TimelineLoader = function(model, delegate)
{
this._model = model;
+ this._delegate = delegate;
/** @type {?function()} */
this._canceledCallback = null;
- this._progress = progress;
- this._progress.setTitle(WebInspector.UIString("Loading"));
- this._progress.setTotalWork(WebInspector.TimelineLoader._totalProgress); // Unknown, will loop the values.
this._state = WebInspector.TimelineLoader.State.Initial;
this._buffer = "";
this._firstChunk = true;
- this._wasCanceledOnce = false;
this._loadedBytes = 0;
/** @type {number} */
@@ -31,31 +28,36 @@
}
/**
- * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TracingModel} model
* @param {!File} file
- * @param {!WebInspector.Progress} progress
+ * @param {!WebInspector.TimelineLifecycleDelegate} delegate
+ * @return {!WebInspector.TimelineLoader}
*/
-WebInspector.TimelineLoader.loadFromFile = function(model, file, progress)
+WebInspector.TimelineLoader.loadFromFile = function(model, file, delegate)
{
- var loader = new WebInspector.TimelineLoader(model, progress);
+ var loader = new WebInspector.TimelineLoader(model, delegate);
var fileReader = WebInspector.TimelineLoader._createFileReader(file, loader);
loader._canceledCallback = fileReader.cancel.bind(fileReader);
loader._totalSize = file.size;
- progress.setTotalWork(loader._totalSize);
fileReader.start(loader);
+ return loader;
}
/**
- * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TracingModel} model
* @param {string} url
- * @param {!WebInspector.Progress} progress
+ * @param {!WebInspector.TimelineLifecycleDelegate} delegate
+ * @return {!WebInspector.TimelineLoader}
*/
-WebInspector.TimelineLoader.loadFromURL = function(model, url, progress)
+WebInspector.TimelineLoader.loadFromURL = function(model, url, delegate)
{
- var stream = new WebInspector.TimelineLoader(model, progress);
+ var stream = new WebInspector.TimelineLoader(model, delegate);
WebInspector.ResourceLoader.loadAsStream(url, null, stream);
+ return stream;
}
+WebInspector.TimelineLoader.TransferChunkLengthBytes = 5000000;
+
/**
* @param {!File} file
* @param {!WebInspector.OutputStreamDelegate} delegate
@@ -63,12 +65,9 @@
*/
WebInspector.TimelineLoader._createFileReader = function(file, delegate)
{
- return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModel.TransferChunkLengthBytes, delegate);
+ return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineLoader.TransferChunkLengthBytes, delegate);
}
-
-WebInspector.TimelineLoader._totalProgress = 100000;
-
WebInspector.TimelineLoader.State = {
Initial: "Initial",
LookingForEvents: "LookingForEvents",
@@ -76,26 +75,27 @@
}
WebInspector.TimelineLoader.prototype = {
+ cancel: function()
+ {
+ this._model.reset();
+ this._delegate.loadingComplete(false);
+ this._delegate = null;
+ if (this._canceledCallback)
+ this._canceledCallback();
+ },
+
/**
* @override
* @param {string} chunk
*/
write: function(chunk)
{
- this._loadedBytes += chunk.length;
- if (this._progress.isCanceled() && !this._wasCanceledOnce) {
- this._wasCanceled = true;
- this._reportErrorAndCancelLoading();
+ if (!this._delegate)
return;
- }
- if (this._firstChunk)
- this._progress.setTitle(WebInspector.UIString("Loading\u2026"));
- if (this._totalSize) {
- this._progress.setWorked(this._loadedBytes);
- } else {
- this._progress.setWorked(this._loadedBytes % WebInspector.TimelineLoader._totalProgress,
- WebInspector.UIString("Loaded %s", Number.bytesToString(this._loadedBytes)));
- }
+ this._loadedBytes += chunk.length;
+ if (!this._firstChunk)
+ this._delegate.loadingProgress(this._totalSize ? this._loadedBytes / this._totalSize : undefined);
+
if (this._state === WebInspector.TimelineLoader.State.Initial) {
if (chunk[0] === "{")
this._state = WebInspector.TimelineLoader.State.LookingForEvents;
@@ -129,7 +129,7 @@
var json = data + "]";
if (this._firstChunk) {
- this._model.startCollectingTraceEvents(true);
+ this._delegate.loadingStarted();
} else {
var commaIndex = json.indexOf(",");
if (commaIndex !== -1)
@@ -154,7 +154,7 @@
}
try {
- this._model.traceEventsCollected(items);
+ this._model.addEvents(items);
} catch(e) {
this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s", e.toString()));
return;
@@ -168,11 +168,7 @@
{
if (message)
WebInspector.console.error(message);
- this._model.tracingComplete();
- this._model.reset();
- if (this._canceledCallback)
- this._canceledCallback();
- this._progress.done();
+ this.cancel();
},
/**
@@ -190,8 +186,8 @@
close: function()
{
this._model._loadedFromFile = true;
- this._model.tracingComplete();
- this._progress.done();
+ if (this._delegate)
+ this._delegate.loadingComplete(true);
},
/**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
index 21905ea0..3f27d0c 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
@@ -261,8 +261,6 @@
return processRecords(recordsArray, 0);
}
-WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000;
-
WebInspector.TimelineModel.DevToolsMetadataEvent = {
TracingStartedInBrowser: "TracingStartedInBrowser",
TracingStartedInPage: "TracingStartedInPage",
@@ -660,6 +658,7 @@
*/
startCollectingTraceEvents: function(fromFile)
{
+ this._loadedFromFile = fromFile;
this._tracingModel.reset();
this.reset();
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted, { fromFile: fromFile });
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index cb89855..e527444 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -32,6 +32,7 @@
/**
* @constructor
* @extends {WebInspector.Panel}
+ * @implements {WebInspector.TimelineLifecycleDelegate}
* @implements {WebInspector.TimelineModeViewDelegate}
* @implements {WebInspector.Searchable}
*/
@@ -388,7 +389,7 @@
this._updateTimelineControls();
var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear recording"), "clear-toolbar-item");
- clearButton.addEventListener("click", this._onClearButtonClick, this);
+ clearButton.addEventListener("click", this._clear, this);
this._panelToolbar.appendToolbarItem(clearButton);
this._panelToolbar.appendSeparator();
@@ -444,33 +445,12 @@
addGroupingOption.call(this, WebInspector.UIString("%fx slowdown", rate), rate);
this._panelToolbar.appendToolbarItem(this._cpuThrottlingCombobox);
}
-
- this._progressToolbarItem = new WebInspector.ToolbarItem(createElement("div"));
- this._progressToolbarItem.setVisible(false);
- this._panelToolbar.appendToolbarItem(this._progressToolbarItem);
},
- /**
- * @return {!WebInspector.Progress}
- */
_prepareToLoadTimeline: function()
{
- /**
- * @this {!WebInspector.TimelinePanel}
- */
- function finishLoading()
- {
- this._setState(WebInspector.TimelinePanel.State.Idle);
- this._progressToolbarItem.setVisible(false);
- this._progressToolbarItem.element.removeChildren();
- this._hideRecordingHelpMessage();
- }
- console.assert(this._state === WebInspector.TimelinePanel.State.Idle);
- this._setState(WebInspector.TimelinePanel.State.Loading);
- var progressIndicator = new WebInspector.ProgressIndicator();
- this._progressToolbarItem.setVisible(true);
- this._progressToolbarItem.element.appendChild(progressIndicator.element);
- return new WebInspector.ProgressProxy(progressIndicator, finishLoading.bind(this));
+ console.assert(this._state === WebInspector.TimelinePanel.State.Idle);
+ this._setState(WebInspector.TimelinePanel.State.Loading);
},
_createFileSelector: function()
@@ -536,7 +516,8 @@
{
if (this._state !== WebInspector.TimelinePanel.State.Idle)
return;
- WebInspector.TimelineLoader.loadFromFile(this._model, file, this._prepareToLoadTimeline());
+ this._prepareToLoadTimeline();
+ this._loader = WebInspector.TimelineLoader.loadFromFile(this._tracingModel, file, this);
this._createFileSelector();
},
@@ -547,7 +528,8 @@
{
if (this._state !== WebInspector.TimelinePanel.State.Idle)
return;
- WebInspector.TimelineLoader.loadFromURL(this._model, url, this._prepareToLoadTimeline());
+ this._prepareToLoadTimeline();
+ this._loader = WebInspector.TimelineLoader.loadFromURL(this._tracingModel, url, this);
},
_refreshViews: function()
@@ -637,8 +619,7 @@
{
console.assert(!this._statusPane, "Status pane is already opened.");
this._setState(WebInspector.TimelinePanel.State.StartPending);
- this._statusPane = new WebInspector.TimelinePanel.StatusPane();
- this._statusPane.addEventListener(WebInspector.TimelinePanel.StatusPane.Events.Finish, this._stopRecording, this);
+ this._statusPane = new WebInspector.TimelinePanel.StatusPane(true, this._stopRecording.bind(this));
this._statusPane.showPane(this._statusPaneContainer);
this._statusPane.updateStatus(WebInspector.UIString("Initializing recording\u2026"));
@@ -698,7 +679,7 @@
targets[i].heapProfilerAgent().collectGarbage();
},
- _onClearButtonClick: function()
+ _clear: function()
{
this._tracingModel.reset();
this._model.reset();
@@ -816,6 +797,53 @@
this._detailsSplitWidget.showBoth();
},
+ /**
+ * @override
+ */
+ loadingStarted: function()
+ {
+ this._hideRecordingHelpMessage();
+ this._model.startCollectingTraceEvents(true);
+
+ if (this._statusPane)
+ this._statusPane.hide();
+ this._statusPane = new WebInspector.TimelinePanel.StatusPane(false, this._cancelLoading.bind(this));
+ this._statusPane.showPane(this._statusPaneContainer);
+ this._statusPane.updateStatus(WebInspector.UIString("Loading timeline\u2026"));
+ this.loadingProgress(0);
+ },
+
+ /**
+ * @override
+ * @param {number=} progress
+ */
+ loadingProgress: function(progress)
+ {
+ if (typeof progress === "number")
+ this._statusPane.updateProgressBar(WebInspector.UIString("Received"), progress * 100);
+ },
+
+ /**
+ * @override
+ * @param {boolean} success
+ */
+ loadingComplete: function(success)
+ {
+ if (!success) {
+ this._onRecordingStopped();
+ this._clear();
+ } else {
+ this._model.tracingComplete();
+ }
+ delete this._loader;
+ },
+
+ _cancelLoading: function()
+ {
+ if (this._loader)
+ this._loader.cancel();
+ },
+
_setMarkers: function()
{
var markers = new Map();
@@ -1245,6 +1273,28 @@
}
/**
+ * @interface
+ */
+WebInspector.TimelineLifecycleDelegate = function()
+{
+}
+
+WebInspector.TimelineLifecycleDelegate.prototype = {
+ loadingStarted: function() {},
+
+ /**
+ * @param {number=} progress
+ */
+ loadingProgress: function(progress) {},
+
+ /**
+ * @param {boolean} success
+ */
+ loadingComplete: function(success) {},
+};
+
+
+/**
* @constructor
* @extends {WebInspector.VBox}
* @implements {WebInspector.TimelineModeView}
@@ -1740,8 +1790,10 @@
/**
* @constructor
* @extends {WebInspector.VBox}
+ * @param {boolean} showTimer
+ * @param {function()} stopCallback
*/
-WebInspector.TimelinePanel.StatusPane = function()
+WebInspector.TimelinePanel.StatusPane = function(showTimer, stopCallback)
{
WebInspector.VBox.call(this, true);
this.registerRequiredCSS("timeline/timelineStatusDialog.css");
@@ -1751,22 +1803,19 @@
statusLine.createChild("div", "label").textContent = WebInspector.UIString("Status");
this._status = statusLine.createChild("div", "content");
- var timeLine = this.contentElement.createChild("div", "status-dialog-line time");
- timeLine.createChild("div", "label").textContent = WebInspector.UIString("Time");
- this._time = timeLine.createChild("div", "content");
-
+ if (showTimer) {
+ var timeLine = this.contentElement.createChild("div", "status-dialog-line time");
+ timeLine.createChild("div", "label").textContent = WebInspector.UIString("Time");
+ this._time = timeLine.createChild("div", "content");
+ }
var progressLine = this.contentElement.createChild("div", "status-dialog-line progress");
this._progressLabel = progressLine.createChild("div", "label");
this._progressBar = progressLine.createChild("div", "indicator-container").createChild("div", "indicator");
- this._stopButton = createTextButton(WebInspector.UIString("Finish"), this._onFinish.bind(this));
+ this._stopButton = createTextButton(WebInspector.UIString("Stop"), stopCallback);
this.contentElement.createChild("div", "stop-button").appendChild(this._stopButton);
}
-WebInspector.TimelinePanel.StatusPane.Events = {
- Finish: "Finish"
-}
-
WebInspector.TimelinePanel.StatusPane.prototype = {
finish: function()
{
@@ -1808,11 +1857,6 @@
this._updateTimer();
},
- _onFinish: function()
- {
- this.dispatchEventToListeners(WebInspector.TimelinePanel.StatusPane.Events.Finish);
- },
-
startTimer: function()
{
this._startTime = Date.now();