diff --git a/front_end/timeline/TimelineLoader.js b/front_end/timeline/TimelineLoader.js index 8b786f8e9e..051bd61c0b 100644 --- a/front_end/timeline/TimelineLoader.js +++ b/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 @@ WebInspector.TimelineLoader = function(model, progress) } /** - * @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.loadFromURL = function(model, url, progress) */ 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.State = { } 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 @@ WebInspector.TimelineLoader.prototype = { 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 @@ WebInspector.TimelineLoader.prototype = { } 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 @@ WebInspector.TimelineLoader.prototype = { { 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 @@ WebInspector.TimelineLoader.prototype = { close: function() { this._model._loadedFromFile = true; - this._model.tracingComplete(); - this._progress.done(); + if (this._delegate) + this._delegate.loadingComplete(true); }, /** diff --git a/front_end/timeline/TimelineModel.js b/front_end/timeline/TimelineModel.js index 21905ea098..3f27d0cae4 100644 --- a/front_end/timeline/TimelineModel.js +++ b/front_end/timeline/TimelineModel.js @@ -261,8 +261,6 @@ WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba return processRecords(recordsArray, 0); } -WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; - WebInspector.TimelineModel.DevToolsMetadataEvent = { TracingStartedInBrowser: "TracingStartedInBrowser", TracingStartedInPage: "TracingStartedInPage", @@ -660,6 +658,7 @@ WebInspector.TimelineModel.prototype = { */ startCollectingTraceEvents: function(fromFile) { + this._loadedFromFile = fromFile; this._tracingModel.reset(); this.reset(); this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted, { fromFile: fromFile }); diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js index cb89855c97..e5274443bc 100644 --- a/front_end/timeline/TimelinePanel.js +++ b/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 @@ WebInspector.TimelinePanel.prototype = { 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 @@ WebInspector.TimelinePanel.prototype = { 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 @@ WebInspector.TimelinePanel.prototype = { { 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 @@ WebInspector.TimelinePanel.prototype = { { 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 @@ WebInspector.TimelinePanel.prototype = { { 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 @@ WebInspector.TimelinePanel.prototype = { targets[i].heapProfilerAgent().collectGarbage(); }, - _onClearButtonClick: function() + _clear: function() { this._tracingModel.reset(); this._model.reset(); @@ -816,6 +797,53 @@ WebInspector.TimelinePanel.prototype = { 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(); @@ -1244,6 +1272,28 @@ WebInspector.TimelinePanel.prototype = { __proto__: WebInspector.Panel.prototype } +/** + * @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} @@ -1740,8 +1790,10 @@ WebInspector.TimelineStaticFilter.prototype = { /** * @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 @@ WebInspector.TimelinePanel.StatusPane = function() 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 @@ WebInspector.TimelinePanel.StatusPane.prototype = { this._updateTimer(); }, - _onFinish: function() - { - this.dispatchEventToListeners(WebInspector.TimelinePanel.StatusPane.Events.Finish); - }, - startTimer: function() { this._startTime = Date.now();