123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946 |
- /*
- * Copyright (C) 2012 Google 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.View}
- * @param {!WebInspector.CanvasProfileHeader} profile
- */
- WebInspector.CanvasProfileView = function(profile)
- {
- WebInspector.View.call(this);
- this.registerRequiredCSS("canvasProfiler.css");
- this._profile = profile;
- this._traceLogId = profile.traceLogId();
- this.element.addStyleClass("canvas-profile-view");
- this._linkifier = new WebInspector.Linkifier();
- this._splitView = new WebInspector.SplitView(false, "canvasProfileViewSplitLocation", 300);
- var replayImageContainer = this._splitView.firstElement();
- replayImageContainer.id = "canvas-replay-image-container";
- this._replayImageElement = replayImageContainer.createChild("image", "canvas-replay-image");
- this._debugInfoElement = replayImageContainer.createChild("div", "canvas-debug-info hidden");
- this._spinnerIcon = replayImageContainer.createChild("img", "canvas-spinner-icon hidden");
- var replayInfoContainer = this._splitView.secondElement();
- var controlsContainer = replayInfoContainer.createChild("div", "status-bar");
- var logGridContainer = replayInfoContainer.createChild("div", "canvas-replay-log");
- this._createControlButton(controlsContainer, "canvas-replay-first-step", WebInspector.UIString("First call."), this._onReplayFirstStepClick.bind(this));
- this._createControlButton(controlsContainer, "canvas-replay-prev-step", WebInspector.UIString("Previous call."), this._onReplayStepClick.bind(this, false));
- this._createControlButton(controlsContainer, "canvas-replay-next-step", WebInspector.UIString("Next call."), this._onReplayStepClick.bind(this, true));
- this._createControlButton(controlsContainer, "canvas-replay-prev-draw", WebInspector.UIString("Previous drawing call."), this._onReplayDrawingCallClick.bind(this, false));
- this._createControlButton(controlsContainer, "canvas-replay-next-draw", WebInspector.UIString("Next drawing call."), this._onReplayDrawingCallClick.bind(this, true));
- this._createControlButton(controlsContainer, "canvas-replay-last-step", WebInspector.UIString("Last call."), this._onReplayLastStepClick.bind(this));
- this._replayContextSelector = new WebInspector.StatusBarComboBox(this._onReplayContextChanged.bind(this));
- this._replayContextSelector.createOption("<screenshot auto>", WebInspector.UIString("Show screenshot of the last replayed resource."), "");
- controlsContainer.appendChild(this._replayContextSelector.element);
- /** @type {!Object.<string, boolean>} */
- this._replayContexts = {};
- /** @type {!Object.<string, CanvasAgent.ResourceState>} */
- this._currentResourceStates = {};
- var columns = [
- {title: "#", sortable: true, width: "5%"},
- {title: WebInspector.UIString("Call"), sortable: true, width: "75%", disclosure: true},
- {title: WebInspector.UIString("Location"), sortable: true, width: "20%"}
- ];
- this._logGrid = new WebInspector.DataGrid(columns);
- this._logGrid.element.addStyleClass("fill");
- this._logGrid.show(logGridContainer);
- this._logGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._replayTraceLog.bind(this));
- this._splitView.show(this.element);
- this._requestTraceLog(0);
- }
- /**
- * @const
- * @type {number}
- */
- WebInspector.CanvasProfileView.TraceLogPollingInterval = 500;
- WebInspector.CanvasProfileView.prototype = {
- dispose: function()
- {
- this._linkifier.reset();
- },
- statusBarItems: function()
- {
- return [];
- },
- get profile()
- {
- return this._profile;
- },
- /**
- * @override
- * @return {Array.<Element>}
- */
- elementsToRestoreScrollPositionsFor: function()
- {
- return [this._logGrid.scrollContainer];
- },
- /**
- * @param {Element} parent
- * @param {string} className
- * @param {string} title
- * @param {function(this:WebInspector.CanvasProfileView)} clickCallback
- */
- _createControlButton: function(parent, className, title, clickCallback)
- {
- var button = parent.createChild("button", "status-bar-item");
- button.addStyleClass(className);
- button.title = title;
- button.createChild("img");
- button.addEventListener("click", clickCallback, false);
- },
- _onReplayContextChanged: function()
- {
- /**
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.ResourceState} resourceState
- */
- function didReceiveResourceState(error, resourceState)
- {
- this._enableWaitIcon(false);
- if (error)
- return;
- this._currentResourceStates[resourceState.id] = resourceState;
- var selectedContextId = this._replayContextSelector.selectedOption().value;
- if (selectedContextId === resourceState.id)
- this._replayImageElement.src = resourceState.imageURL;
- }
- var selectedContextId = this._replayContextSelector.selectedOption().value || "auto";
- var resourceState = this._currentResourceStates[selectedContextId];
- if (resourceState)
- this._replayImageElement.src = resourceState.imageURL;
- else {
- this._enableWaitIcon(true);
- this._replayImageElement.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; // Empty transparent image.
- CanvasAgent.getResourceState(this._traceLogId, selectedContextId, didReceiveResourceState.bind(this));
- }
- },
- /**
- * @param {boolean} forward
- */
- _onReplayStepClick: function(forward)
- {
- var selectedNode = this._logGrid.selectedNode;
- if (!selectedNode)
- return;
- var nextNode = forward ? selectedNode.traverseNextNode(false) : selectedNode.traversePreviousNode(false);
- (nextNode || selectedNode).revealAndSelect();
- },
- /**
- * @param {boolean} forward
- */
- _onReplayDrawingCallClick: function(forward)
- {
- var selectedNode = this._logGrid.selectedNode;
- if (!selectedNode)
- return;
- var nextNode = selectedNode;
- while (nextNode) {
- var sibling = forward ? nextNode.nextSibling : nextNode.previousSibling;
- if (sibling) {
- nextNode = sibling;
- if (nextNode.hasChildren || nextNode.call.isDrawingCall)
- break;
- } else {
- nextNode = nextNode.parent;
- if (!forward)
- break;
- }
- }
- if (!nextNode && forward)
- this._onReplayLastStepClick();
- else
- (nextNode || selectedNode).revealAndSelect();
- },
- _onReplayFirstStepClick: function()
- {
- var firstNode = this._logGrid.rootNode().children[0];
- if (firstNode)
- firstNode.revealAndSelect();
- },
- _onReplayLastStepClick: function()
- {
- var lastNode = this._logGrid.rootNode().children.peekLast();
- if (!lastNode)
- return;
- while (lastNode.expanded) {
- var lastChild = lastNode.children.peekLast();
- if (!lastChild)
- break;
- lastNode = lastChild;
- }
- lastNode.revealAndSelect();
- },
- /**
- * @param {boolean} enable
- */
- _enableWaitIcon: function(enable)
- {
- this._spinnerIcon.enableStyleClass("hidden", !enable);
- this._debugInfoElement.enableStyleClass("hidden", enable);
- },
- _replayTraceLog: function()
- {
- if (this._pendingReplayTraceLogEvent)
- return;
- var index = this._selectedCallIndex();
- if (index === -1 || index === this._lastReplayCallIndex)
- return;
- this._lastReplayCallIndex = index;
- this._pendingReplayTraceLogEvent = true;
- var time = Date.now();
- /**
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.ResourceState} resourceState
- */
- function didReplayTraceLog(error, resourceState)
- {
- delete this._pendingReplayTraceLogEvent;
- if (index !== this._selectedCallIndex()) {
- this._replayTraceLog();
- return;
- }
- this._enableWaitIcon(false);
- if (error)
- return;
- this._currentResourceStates = {};
- this._currentResourceStates["auto"] = resourceState;
- this._currentResourceStates[resourceState.id] = resourceState;
- this._debugInfoElement.textContent = "Replay time: " + (Date.now() - time) + "ms";
- this._onReplayContextChanged();
- }
- this._enableWaitIcon(true);
- CanvasAgent.replayTraceLog(this._traceLogId, index, didReplayTraceLog.bind(this));
- },
- /**
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.TraceLog} traceLog
- */
- _didReceiveTraceLog: function(error, traceLog)
- {
- this._enableWaitIcon(false);
- if (error || !traceLog)
- return;
- var callNodes = [];
- var calls = traceLog.calls;
- var index = traceLog.startOffset;
- for (var i = 0, n = calls.length; i < n; ++i) {
- var call = calls[i];
- this._requestReplayContextInfo(call.contextId);
- var gridNode = this._createCallNode(index++, call);
- callNodes.push(gridNode);
- }
- this._appendCallNodes(callNodes);
- if (traceLog.alive)
- setTimeout(this._requestTraceLog.bind(this, index), WebInspector.CanvasProfileView.TraceLogPollingInterval);
- else
- this._flattenSingleFrameNode();
- this._profile._updateCapturingStatus(traceLog);
- this._onReplayLastStepClick(); // Automatically replay the last step.
- },
- /**
- * @param {number} offset
- */
- _requestTraceLog: function(offset)
- {
- this._enableWaitIcon(true);
- CanvasAgent.getTraceLog(this._traceLogId, offset, undefined, this._didReceiveTraceLog.bind(this));
- },
- /**
- * @param {string} contextId
- */
- _requestReplayContextInfo: function(contextId)
- {
- if (this._replayContexts[contextId])
- return;
- this._replayContexts[contextId] = true;
- /**
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.ResourceInfo} resourceInfo
- */
- function didReceiveResourceInfo(error, resourceInfo)
- {
- if (error) {
- delete this._replayContexts[contextId];
- return;
- }
- this._replayContextSelector.createOption(resourceInfo.description, WebInspector.UIString("Show screenshot of this context's canvas."), contextId);
- }
- CanvasAgent.getResourceInfo(contextId, didReceiveResourceInfo.bind(this));
- },
- /**
- * @return {number}
- */
- _selectedCallIndex: function()
- {
- var node = this._logGrid.selectedNode;
- return node ? this._peekLastRecursively(node).index : -1;
- },
- /**
- * @param {!WebInspector.DataGridNode} node
- * @return {!WebInspector.DataGridNode}
- */
- _peekLastRecursively: function(node)
- {
- var lastChild;
- while ((lastChild = node.children.peekLast()))
- node = /** @type {!WebInspector.DataGridNode} */ (lastChild);
- return node;
- },
- /**
- * @param {!Array.<!WebInspector.DataGridNode>} callNodes
- */
- _appendCallNodes: function(callNodes)
- {
- var rootNode = this._logGrid.rootNode();
- var frameNode = /** @type {WebInspector.DataGridNode} */ (rootNode.children.peekLast());
- if (frameNode && this._peekLastRecursively(frameNode).call.isFrameEndCall)
- frameNode = null;
- for (var i = 0, n = callNodes.length; i < n; ++i) {
- if (!frameNode) {
- var index = rootNode.children.length;
- var data = {};
- data[0] = "";
- data[1] = "Frame #" + (index + 1);
- data[2] = "";
- frameNode = new WebInspector.DataGridNode(data);
- frameNode.selectable = true;
- rootNode.appendChild(frameNode);
- }
- var nextFrameCallIndex = i + 1;
- while (nextFrameCallIndex < n && !callNodes[nextFrameCallIndex - 1].call.isFrameEndCall)
- ++nextFrameCallIndex;
- this._appendCallNodesToFrameNode(frameNode, callNodes, i, nextFrameCallIndex);
- i = nextFrameCallIndex - 1;
- frameNode = null;
- }
- },
- /**
- * @param {!WebInspector.DataGridNode} frameNode
- * @param {!Array.<!WebInspector.DataGridNode>} callNodes
- * @param {number} fromIndex
- * @param {number} toIndex not inclusive
- */
- _appendCallNodesToFrameNode: function(frameNode, callNodes, fromIndex, toIndex)
- {
- var self = this;
- function appendDrawCallGroup()
- {
- var index = self._drawCallGroupsCount || 0;
- var data = {};
- data[0] = "";
- data[1] = "Draw call group #" + (index + 1);
- data[2] = "";
- var node = new WebInspector.DataGridNode(data);
- node.selectable = true;
- self._drawCallGroupsCount = index + 1;
- frameNode.appendChild(node);
- return node;
- }
- function splitDrawCallGroup(drawCallGroup)
- {
- var splitIndex = 0;
- var splitNode;
- while ((splitNode = drawCallGroup.children[splitIndex])) {
- if (splitNode.call.isDrawingCall)
- break;
- ++splitIndex;
- }
- var newDrawCallGroup = appendDrawCallGroup();
- var lastNode;
- while ((lastNode = drawCallGroup.children[splitIndex + 1]))
- newDrawCallGroup.appendChild(lastNode);
- return newDrawCallGroup;
- }
- var drawCallGroup = frameNode.children.peekLast();
- var groupHasDrawCall = false;
- if (drawCallGroup) {
- for (var i = 0, n = drawCallGroup.children.length; i < n; ++i) {
- if (drawCallGroup.children[i].call.isDrawingCall) {
- groupHasDrawCall = true;
- break;
- }
- }
- } else
- drawCallGroup = appendDrawCallGroup();
- for (var i = fromIndex; i < toIndex; ++i) {
- var node = callNodes[i];
- drawCallGroup.appendChild(node);
- if (node.call.isDrawingCall) {
- if (groupHasDrawCall)
- drawCallGroup = splitDrawCallGroup(drawCallGroup);
- else
- groupHasDrawCall = true;
- }
- }
- },
- /**
- * @param {number} index
- * @param {CanvasAgent.Call} call
- * @return {!WebInspector.DataGridNode}
- */
- _createCallNode: function(index, call)
- {
- var data = {};
- data[0] = index + 1;
- data[1] = call.functionName || "context." + call.property;
- data[2] = "";
- if (call.sourceURL) {
- // FIXME(62725): stack trace line/column numbers are one-based.
- var lineNumber = Math.max(0, call.lineNumber - 1) || 0;
- var columnNumber = Math.max(0, call.columnNumber - 1) || 0;
- data[2] = this._linkifier.linkifyLocation(call.sourceURL, lineNumber, columnNumber);
- }
- if (call.arguments) {
- var args = call.arguments.map(function(argument) {
- return argument.description;
- });
- data[1] += "(" + args.join(", ") + ")";
- } else
- data[1] += " = " + call.value.description;
- if (typeof call.result !== "undefined")
- data[1] += " => " + call.result.description;
- var node = new WebInspector.DataGridNode(data);
- node.index = index;
- node.selectable = true;
- node.call = call;
- return node;
- },
- _flattenSingleFrameNode: function()
- {
- var rootNode = this._logGrid.rootNode();
- if (rootNode.children.length !== 1)
- return;
- var frameNode = rootNode.children[0];
- while (frameNode.children[0])
- rootNode.appendChild(frameNode.children[0]);
- rootNode.removeChild(frameNode);
- },
- __proto__: WebInspector.View.prototype
- }
- /**
- * @constructor
- * @extends {WebInspector.ProfileType}
- */
- WebInspector.CanvasProfileType = function()
- {
- WebInspector.ProfileType.call(this, WebInspector.CanvasProfileType.TypeId, WebInspector.UIString("Capture Canvas Frame"));
- this._nextProfileUid = 1;
- this._recording = false;
- this._lastProfileHeader = null;
- this._capturingModeSelector = new WebInspector.StatusBarComboBox(this._dispatchViewUpdatedEvent.bind(this));
- this._capturingModeSelector.element.title = WebInspector.UIString("Canvas capture mode.");
- this._capturingModeSelector.createOption(WebInspector.UIString("Single Frame"), WebInspector.UIString("Capture a single canvas frame."), "");
- this._capturingModeSelector.createOption(WebInspector.UIString("Consecutive Frames"), WebInspector.UIString("Capture consecutive canvas frames."), "1");
- /** @type {!Object.<string, Element>} */
- this._frameOptions = {};
- /** @type {!Object.<string, boolean>} */
- this._framesWithCanvases = {};
- this._frameSelector = new WebInspector.StatusBarComboBox(this._dispatchViewUpdatedEvent.bind(this));
- this._frameSelector.element.title = WebInspector.UIString("Frame containing the canvases to capture.");
- this._frameSelector.element.addStyleClass("hidden");
- WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
- this._decorationElement = document.createElement("div");
- this._decorationElement.addStyleClass("profile-canvas-decoration");
- this._decorationElement.addStyleClass("hidden");
- this._decorationElement.textContent = WebInspector.UIString("There is an uninstrumented canvas on the page. Reload the page to instrument it.");
- var reloadPageButton = this._decorationElement.createChild("button");
- reloadPageButton.type = "button";
- reloadPageButton.textContent = WebInspector.UIString("Reload");
- reloadPageButton.addEventListener("click", this._onReloadPageButtonClick.bind(this), false);
- this._dispatcher = new WebInspector.CanvasDispatcher(this);
- // FIXME: enable/disable by a UI action?
- CanvasAgent.enable(this._updateDecorationElement.bind(this));
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._updateDecorationElement, this);
- }
- WebInspector.CanvasProfileType.TypeId = "CANVAS_PROFILE";
- WebInspector.CanvasProfileType.prototype = {
- statusBarItems: function()
- {
- return [this._capturingModeSelector.element, this._frameSelector.element];
- },
- get buttonTooltip()
- {
- if (this._isSingleFrameMode())
- return WebInspector.UIString("Capture next canvas frame.");
- else
- return this._recording ? WebInspector.UIString("Stop capturing canvas frames.") : WebInspector.UIString("Start capturing canvas frames.");
- },
- /**
- * @override
- * @return {boolean}
- */
- buttonClicked: function()
- {
- if (this._recording) {
- this._recording = false;
- this._stopFrameCapturing();
- } else if (this._isSingleFrameMode()) {
- this._recording = false;
- this._runSingleFrameCapturing();
- } else {
- this._recording = true;
- this._startFrameCapturing();
- }
- return this._recording;
- },
- _runSingleFrameCapturing: function()
- {
- var frameId = this._selectedFrameId();
- CanvasAgent.captureFrame(frameId, this._didStartCapturingFrame.bind(this, frameId));
- },
- _startFrameCapturing: function()
- {
- var frameId = this._selectedFrameId();
- CanvasAgent.startCapturing(frameId, this._didStartCapturingFrame.bind(this, frameId));
- },
- _stopFrameCapturing: function()
- {
- if (!this._lastProfileHeader)
- return;
- var profileHeader = this._lastProfileHeader;
- var traceLogId = profileHeader.traceLogId();
- this._lastProfileHeader = null;
- function didStopCapturing()
- {
- profileHeader._updateCapturingStatus();
- }
- CanvasAgent.stopCapturing(traceLogId, didStopCapturing.bind(this));
- },
- /**
- * @param {string|undefined} frameId
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.TraceLogId} traceLogId
- */
- _didStartCapturingFrame: function(frameId, error, traceLogId)
- {
- if (error || this._lastProfileHeader && this._lastProfileHeader.traceLogId() === traceLogId)
- return;
- var profileHeader = new WebInspector.CanvasProfileHeader(this, WebInspector.UIString("Trace Log %d", this._nextProfileUid), this._nextProfileUid, traceLogId, frameId);
- ++this._nextProfileUid;
- this._lastProfileHeader = profileHeader;
- this.addProfile(profileHeader);
- profileHeader._updateCapturingStatus();
- },
- get treeItemTitle()
- {
- return WebInspector.UIString("CANVAS PROFILE");
- },
- get description()
- {
- return WebInspector.UIString("Canvas calls instrumentation");
- },
- /**
- * @override
- * @return {Element}
- */
- decorationElement: function()
- {
- return this._decorationElement;
- },
- /**
- * @override
- */
- _reset: function()
- {
- WebInspector.ProfileType.prototype._reset.call(this);
- this._nextProfileUid = 1;
- },
- /**
- * @override
- * @param {!WebInspector.ProfileHeader} profile
- */
- removeProfile: function(profile)
- {
- WebInspector.ProfileType.prototype.removeProfile.call(this, profile);
- if (this._recording && profile === this._lastProfileHeader)
- this._recording = false;
- },
- setRecordingProfile: function(isProfiling)
- {
- this._recording = isProfiling;
- },
- /**
- * @override
- * @param {string=} title
- * @return {!WebInspector.ProfileHeader}
- */
- createTemporaryProfile: function(title)
- {
- title = title || WebInspector.UIString("Capturing\u2026");
- return new WebInspector.CanvasProfileHeader(this, title);
- },
- /**
- * @override
- * @param {ProfilerAgent.ProfileHeader} profile
- * @return {!WebInspector.ProfileHeader}
- */
- createProfile: function(profile)
- {
- return new WebInspector.CanvasProfileHeader(this, profile.title, -1);
- },
- _updateDecorationElement: function()
- {
- /**
- * @param {?Protocol.Error} error
- * @param {boolean} result
- */
- function callback(error, result)
- {
- var hideWarning = (error || !result);
- this._decorationElement.enableStyleClass("hidden", hideWarning);
- }
- CanvasAgent.hasUninstrumentedCanvases(callback.bind(this));
- },
- /**
- * @param {MouseEvent} event
- */
- _onReloadPageButtonClick: function(event)
- {
- PageAgent.reload(event.shiftKey);
- },
- /**
- * @return {boolean}
- */
- _isSingleFrameMode: function()
- {
- return !this._capturingModeSelector.selectedOption().value;
- },
- /**
- * @param {WebInspector.Event} event
- */
- _frameAdded: function(event)
- {
- var contextList = /** @type {WebInspector.FrameExecutionContextList} */ (event.data);
- this._addFrame(contextList);
- },
- /**
- * @param {WebInspector.FrameExecutionContextList} contextList
- */
- _addFrame: function(contextList)
- {
- var frameId = contextList.frameId;
- var option = document.createElement("option");
- option.text = contextList.displayName;
- option.title = contextList.url;
- option.value = frameId;
- this._frameOptions[frameId] = option;
- if (this._framesWithCanvases[frameId]) {
- this._frameSelector.addOption(option);
- this._dispatchViewUpdatedEvent();
- }
- },
- /**
- * @param {WebInspector.Event} event
- */
- _frameRemoved: function(event)
- {
- var contextList = /** @type {WebInspector.FrameExecutionContextList} */ (event.data);
- var frameId = contextList.frameId;
- var option = this._frameOptions[frameId];
- if (option && this._framesWithCanvases[frameId]) {
- this._frameSelector.removeOption(option);
- this._dispatchViewUpdatedEvent();
- }
- delete this._frameOptions[frameId];
- delete this._framesWithCanvases[frameId];
- },
- /**
- * @param {string} frameId
- */
- _contextCreated: function(frameId)
- {
- if (this._framesWithCanvases[frameId])
- return;
- this._framesWithCanvases[frameId] = true;
- var option = this._frameOptions[frameId];
- if (option) {
- this._frameSelector.addOption(option);
- this._dispatchViewUpdatedEvent();
- }
- },
- /**
- * @param {NetworkAgent.FrameId=} frameId
- * @param {CanvasAgent.TraceLogId=} traceLogId
- */
- _traceLogsRemoved: function(frameId, traceLogId)
- {
- var sidebarElementsToDelete = [];
- var sidebarElements = /** @type {!Array.<WebInspector.ProfileSidebarTreeElement>} */ ((this.treeElement && this.treeElement.children) || []);
- for (var i = 0, n = sidebarElements.length; i < n; ++i) {
- var header = /** @type {WebInspector.CanvasProfileHeader} */ (sidebarElements[i].profile);
- if (!header)
- continue;
- if (frameId && frameId !== header.frameId())
- continue;
- if (traceLogId && traceLogId !== header.traceLogId())
- continue;
- sidebarElementsToDelete.push(sidebarElements[i]);
- }
- for (var i = 0, n = sidebarElementsToDelete.length; i < n; ++i)
- sidebarElementsToDelete[i].ondelete();
- },
- /**
- * @return {string|undefined}
- */
- _selectedFrameId: function()
- {
- var option = this._frameSelector.selectedOption();
- return option ? option.value : undefined;
- },
- _dispatchViewUpdatedEvent: function()
- {
- this._frameSelector.element.enableStyleClass("hidden", this._frameSelector.size() <= 1);
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.ViewUpdated);
- },
- __proto__: WebInspector.ProfileType.prototype
- }
- /**
- * @constructor
- * @implements {CanvasAgent.Dispatcher}
- * @param {WebInspector.CanvasProfileType} profileType
- */
- WebInspector.CanvasDispatcher = function(profileType)
- {
- this._profileType = profileType;
- InspectorBackend.registerCanvasDispatcher(this);
- }
- WebInspector.CanvasDispatcher.prototype = {
- /**
- * @param {string} frameId
- */
- contextCreated: function(frameId)
- {
- this._profileType._contextCreated(frameId);
- },
- /**
- * @param {NetworkAgent.FrameId=} frameId
- * @param {CanvasAgent.TraceLogId=} traceLogId
- */
- traceLogsRemoved: function(frameId, traceLogId)
- {
- this._profileType._traceLogsRemoved(frameId, traceLogId);
- }
- }
- /**
- * @constructor
- * @extends {WebInspector.ProfileHeader}
- * @param {!WebInspector.CanvasProfileType} type
- * @param {string} title
- * @param {number=} uid
- * @param {CanvasAgent.TraceLogId=} traceLogId
- * @param {NetworkAgent.FrameId=} frameId
- */
- WebInspector.CanvasProfileHeader = function(type, title, uid, traceLogId, frameId)
- {
- WebInspector.ProfileHeader.call(this, type, title, uid);
- /** @type {CanvasAgent.TraceLogId} */
- this._traceLogId = traceLogId || "";
- this._frameId = frameId;
- this._alive = true;
- this._traceLogSize = 0;
- }
- WebInspector.CanvasProfileHeader.prototype = {
- /**
- * @return {CanvasAgent.TraceLogId}
- */
- traceLogId: function()
- {
- return this._traceLogId;
- },
- /**
- * @return {NetworkAgent.FrameId|undefined}
- */
- frameId: function()
- {
- return this._frameId;
- },
- /**
- * @override
- * @return {WebInspector.ProfileSidebarTreeElement}
- */
- createSidebarTreeElement: function()
- {
- return new WebInspector.ProfileSidebarTreeElement(this, WebInspector.UIString("Trace Log %d"), "profile-sidebar-tree-item");
- },
- /**
- * @override
- * @param {WebInspector.ProfilesPanel} profilesPanel
- */
- createView: function(profilesPanel)
- {
- return new WebInspector.CanvasProfileView(this);
- },
- /**
- * @override
- */
- dispose: function()
- {
- if (this._traceLogId) {
- CanvasAgent.dropTraceLog(this._traceLogId);
- clearTimeout(this._requestStatusTimer);
- this._alive = false;
- }
- },
- /**
- * @param {CanvasAgent.TraceLog=} traceLog
- */
- _updateCapturingStatus: function(traceLog)
- {
- if (!this.sidebarElement || !this._traceLogId)
- return;
- if (traceLog) {
- this._alive = traceLog.alive;
- this._traceLogSize = traceLog.totalAvailableCalls;
- }
- this.sidebarElement.subtitle = this._alive ? WebInspector.UIString("Capturing\u2026 %d calls", this._traceLogSize) : WebInspector.UIString("Captured %d calls", this._traceLogSize);
- this.sidebarElement.wait = this._alive;
- if (this._alive) {
- clearTimeout(this._requestStatusTimer);
- this._requestStatusTimer = setTimeout(this._requestCapturingStatus.bind(this), WebInspector.CanvasProfileView.TraceLogPollingInterval);
- }
- },
- _requestCapturingStatus: function()
- {
- /**
- * @param {?Protocol.Error} error
- * @param {CanvasAgent.TraceLog} traceLog
- */
- function didReceiveTraceLog(error, traceLog)
- {
- if (error)
- return;
- this._alive = traceLog.alive;
- this._traceLogSize = traceLog.totalAvailableCalls;
- this._updateCapturingStatus();
- }
- CanvasAgent.getTraceLog(this._traceLogId, 0, 0, didReceiveTraceLog.bind(this));
- },
- __proto__: WebInspector.ProfileHeader.prototype
- }
|