Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/promises/PromisePane.js

Issue 1827993002: [DevTools] Remove promise inspector experiment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @constructor
7 * @extends {WebInspector.VBox}
8 * @implements {WebInspector.TargetManager.Observer}
9 */
10 WebInspector.PromisePane = function()
11 {
12 WebInspector.VBox.call(this);
13 this.registerRequiredCSS("promises/promisePane.css");
14 this.element.classList.add("promises");
15
16 var toolbar = new WebInspector.Toolbar("", this.element);
17 this._recordButton = new WebInspector.ToolbarToggle("", "record-toolbar-item ");
18 this._recordButton.addEventListener("click", this._recordButtonClicked.bind( this));
19 toolbar.appendToolbarItem(this._recordButton);
20
21 var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clea r"), "clear-toolbar-item");
22 clearButton.addEventListener("click", this._clearButtonClicked.bind(this));
23 toolbar.appendToolbarItem(clearButton);
24 toolbar.appendSeparator();
25
26 this._promiseStatusFiltersSetting = WebInspector.settings.createSetting("pro miseStatusFilters", {});
27 this._hideCollectedPromisesSetting = WebInspector.settings.createSetting("hi deCollectedPromises", false);
28
29 this._createFilterBar();
30 toolbar.appendToolbarItem(this._filterBar.filterButton());
31
32 var garbageCollectButton = new WebInspector.ToolbarButton(WebInspector.UIStr ing("Collect garbage"), "garbage-collect-toolbar-item");
33 garbageCollectButton.addEventListener("click", this._garbageCollectButtonCli cked, this);
34 toolbar.appendToolbarItem(garbageCollectButton);
35
36 toolbar.appendSeparator();
37 var asyncCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString(" Async"), WebInspector.UIString("Capture async stack traces"), WebInspector.modul eSetting("enableAsyncStackTraces"));
38 toolbar.appendToolbarItem(asyncCheckbox);
39
40 this._filterBar.show(this.element);
41
42 this._hiddenByFilterCount = 0;
43 this._filterStatusMessageElement = this.element.createChild("div", "promises -filter-status hidden");
44 this._filterStatusTextElement = this._filterStatusMessageElement.createChild ("span");
45 this._filterStatusMessageElement.createTextChild(" ");
46 var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "link");
47 resetFiltersLink.textContent = WebInspector.UIString("Show all promises.");
48 resetFiltersLink.addEventListener("click", this._resetFilters.bind(this), tr ue);
49
50 // FIXME: Make "status" column width fixed to ~16px.
51 var columns = [
52 { id: "status", weight: 1 },
53 { id: "function", title: WebInspector.UIString("Function"), disclosure: true, weight: 10 },
54 { id: "created", title: WebInspector.UIString("Created"), weight: 10 },
55 { id: "settled", title: WebInspector.UIString("Settled"), weight: 10 },
56 { id: "tts", title: WebInspector.UIString("Time to settle"), weight: 10 }
57 ];
58 this._dataGrid = new WebInspector.ViewportDataGrid(columns, undefined, undef ined, undefined, this._onContextMenu.bind(this));
59 this._dataGrid.setStickToBottom(true);
60 this._dataGrid.asWidget().show(this.element);
61
62 this._linkifier = new WebInspector.Linkifier();
63
64 /** @type {!Map.<!WebInspector.DebuggerModel, !Map.<number, !WebInspector.Pr omiseDetails>>} */
65 this._promiseDetailsByDebuggerModel = new Map();
66 /** @type {!Map.<number, !WebInspector.DataGridNode>} */
67 this._promiseIdToNode = new Map();
68
69 this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._get PopoverAnchor.bind(this), this._showPopover.bind(this));
70 this._popoverHelper.setTimeout(250, 250);
71
72 this.element.addEventListener("click", this._hidePopover.bind(this), true);
73
74 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI nspector.DebuggerModel.Events.PromiseUpdated, this._onPromiseUpdated, this);
75 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNav igated, this);
76 WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targ etChanged, this);
77
78 WebInspector.targetManager.observeTargets(this);
79 }
80
81 WebInspector.PromisePane._maxPromiseCount = 10000;
82
83
84 /**
85 * @constructor
86 * @param {!DebuggerAgent.PromiseDetails} details
87 */
88 WebInspector.PromiseDetails = function(details)
89 {
90 this.id = details.id;
91 this.isGarbageCollected = false;
92 this.update(details);
93 }
94
95 WebInspector.PromiseDetails.prototype = {
96 /**
97 * @param {!DebuggerAgent.PromiseDetails} details
98 */
99 update: function(details)
100 {
101 if (this.id !== details.id)
102 throw new Error("Invalid id, expected " + this.id + " was " + detail s.id);
103 if (details.status)
104 this.status = details.status;
105 if (details.parentId)
106 this.parentId = details.parentId;
107 if (details.creationTime)
108 this.creationTime = details.creationTime;
109 if (details.settlementTime)
110 this.settlementTime = details.settlementTime;
111 if (details.creationStack) {
112 this.creationStack = details.creationStack;
113 if (this.creationStack.callFrames.length)
114 this.callFrame = this.creationStack.callFrames[0];
115 }
116 if (details.asyncCreationStack)
117 this.asyncCreationStack = details.asyncCreationStack;
118 if (details.settlementStack)
119 this.settlementStack = details.settlementStack;
120 if (details.asyncSettlementStack)
121 this.asyncSettlementStack = details.asyncSettlementStack;
122 }
123 }
124
125
126 WebInspector.PromisePane.prototype = {
127 _createFilterBar: function()
128 {
129 this._filterBar = new WebInspector.FilterBar("promisePane");
130
131 this._textFilterUI = new WebInspector.TextFilterUI(true);
132 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterC hanged, this._onFilterChanged, this);
133 this._filterBar.addFilter(this._textFilterUI);
134
135 var statuses = [
136 { name: "pending", label: WebInspector.UIString("Pending") },
137 { name: "resolved", label: WebInspector.UIString("Fulfilled") },
138 { name: "rejected", label: WebInspector.UIString("Rejected") }
139 ];
140 this._statusFilterUI = new WebInspector.NamedBitSetFilterUI(statuses, th is._promiseStatusFiltersSetting);
141 this._statusFilterUI.addEventListener(WebInspector.FilterUI.Events.Filte rChanged, this._onFilterChanged, this);
142 this._filterBar.addFilter(this._statusFilterUI);
143
144 var hideCollectedCheckbox = new WebInspector.CheckboxFilterUI("hide-coll ected-promises", WebInspector.UIString("Hide collected promises"), true, this._h ideCollectedPromisesSetting);
145 hideCollectedCheckbox.addEventListener(WebInspector.FilterUI.Events.Filt erChanged, this._onFilterChanged, this);
146 this._filterBar.addFilter(hideCollectedCheckbox);
147 },
148
149 /**
150 * @param {!WebInspector.PromiseDetails} details
151 * @param {!WebInspector.DataGridNode} node
152 * @return {boolean}
153 */
154 _shouldBeVisible: function(details, node)
155 {
156 if (!this._statusFilterUI.accept(details.status))
157 return false;
158
159 if (this._hideCollectedPromisesSetting.get() && details.isGarbageCollect ed)
160 return false;
161
162 var regex = this._textFilterUI.regex();
163 if (!regex)
164 return true;
165
166 var text = node.dataTextForSearch();
167 regex.lastIndex = 0;
168 return regex.test(text);
169 },
170
171 _onFilterChanged: function()
172 {
173 if (this._filterChangedTimeout)
174 clearTimeout(this._filterChangedTimeout);
175 this._filterChangedTimeout = setTimeout(onTimerFired.bind(this), 100);
176
177 /**
178 * @this {WebInspector.PromisePane}
179 */
180 function onTimerFired()
181 {
182 delete this._filterChangedTimeout;
183 this._refresh();
184 }
185 },
186
187 /**
188 * @override
189 * @return {!Array.<!Element>}
190 */
191 elementsToRestoreScrollPositionsFor: function()
192 {
193 return [this._dataGrid.scrollContainer];
194 },
195
196 /**
197 * @override
198 * @param {!WebInspector.Target} target
199 */
200 targetAdded: function(target)
201 {
202 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
203 if (debuggerModel && this._enabled)
204 this._enablePromiseTracker(debuggerModel);
205 },
206
207 /**
208 * @override
209 * @param {!WebInspector.Target} target
210 */
211 targetRemoved: function(target)
212 {
213 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
214 if (!debuggerModel)
215 return;
216 this._promiseDetailsByDebuggerModel.delete(debuggerModel);
217 if (this._debuggerModel === debuggerModel) {
218 this._clear();
219 delete this._debuggerModel;
220 }
221 },
222
223 /**
224 * @param {!WebInspector.Event} event
225 */
226 _targetChanged: function(event)
227 {
228 if (!this._enabled)
229 return;
230 var target = /** @type {!WebInspector.Target} */ (event.data);
231 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
232 if (!debuggerModel || this._debuggerModel === debuggerModel)
233 return;
234 this._debuggerModel = debuggerModel;
235 this._refresh();
236 },
237
238 /**
239 * @param {!WebInspector.Event} event
240 */
241 _mainFrameNavigated: function(event)
242 {
243 var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
244 var target = frame.target();
245 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
246 if (!debuggerModel)
247 return;
248 this._promiseDetailsByDebuggerModel.delete(debuggerModel);
249 if (this._debuggerModel === debuggerModel)
250 this._clear();
251 },
252
253 /** @override */
254 wasShown: function()
255 {
256 // Auto enable upon the very first show.
257 if (typeof this._enabled === "undefined") {
258 var target = WebInspector.context.flavor(WebInspector.Target);
259 this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
260 this._updateRecordingState(true);
261 }
262 if (this._refreshIsNeeded)
263 this._refresh();
264 },
265
266 /**
267 * @param {!WebInspector.DebuggerModel} debuggerModel
268 */
269 _enablePromiseTracker: function(debuggerModel)
270 {
271 debuggerModel.enablePromiseTracker(true);
272 },
273
274 /**
275 * @param {!WebInspector.DebuggerModel} debuggerModel
276 */
277 _disablePromiseTracker: function(debuggerModel)
278 {
279 debuggerModel.disablePromiseTracker();
280 },
281
282 /** @override */
283 willHide: function()
284 {
285 this._hidePopover();
286 },
287
288 _hidePopover: function()
289 {
290 this._popoverHelper.hidePopover();
291 },
292
293 _recordButtonClicked: function()
294 {
295 this._updateRecordingState(!this._recordButton.toggled());
296 },
297
298 /**
299 * @param {boolean} enabled
300 */
301 _updateRecordingState: function(enabled)
302 {
303 this._enabled = enabled;
304 this._recordButton.setToggled(this._enabled);
305 this._recordButton.setTitle(this._enabled ? WebInspector.UIString("Stop Recording Promises Log") : WebInspector.UIString("Record Promises Log"));
306 WebInspector.DebuggerModel.instances().forEach(this._enabled ? this._ena blePromiseTracker : this._disablePromiseTracker, this);
307 },
308
309 _clearButtonClicked: function()
310 {
311 this._clear();
312 if (this._debuggerModel)
313 this._promiseDetailsByDebuggerModel.delete(this._debuggerModel);
314 },
315
316 _resetFilters: function()
317 {
318 this._hideCollectedPromisesSetting.set(false);
319 this._promiseStatusFiltersSetting.set({});
320 this._textFilterUI.setValue("");
321 },
322
323 _updateFilterStatus: function()
324 {
325 this._filterStatusTextElement.textContent = WebInspector.UIString(this._ hiddenByFilterCount === 1 ? "%d promise is hidden by filters." : "%d promises ar e hidden by filters.", this._hiddenByFilterCount);
326 this._filterStatusMessageElement.classList.toggle("hidden", !this._hidde nByFilterCount);
327 },
328
329 _garbageCollectButtonClicked: function()
330 {
331 var targets = WebInspector.targetManager.targets();
332 for (var i = 0; i < targets.length; ++i)
333 targets[i].heapProfilerAgent().collectGarbage();
334 },
335
336 /**
337 * @param {!WebInspector.DebuggerModel} debuggerModel
338 * @return {boolean}
339 */
340 _truncateLogIfNeeded: function(debuggerModel)
341 {
342 var promiseIdToDetails = this._promiseDetailsByDebuggerModel.get(debugge rModel);
343 if (!promiseIdToDetails || promiseIdToDetails.size <= WebInspector.Promi sePane._maxPromiseCount)
344 return false;
345
346 var elementsToTruncate = WebInspector.PromisePane._maxPromiseCount / 10;
347 var sortedDetails = promiseIdToDetails.valuesArray().sort(compare);
348 for (var i = 0; i < elementsToTruncate; ++i)
349 promiseIdToDetails.delete(sortedDetails[i].id);
350 return true;
351
352 /**
353 * @param {!WebInspector.PromiseDetails} x
354 * @param {!WebInspector.PromiseDetails} y
355 * @return {number}
356 */
357 function compare(x, y)
358 {
359 var t1 = x.creationTime || 0;
360 var t2 = y.creationTime || 0;
361 return t1 - t2 || x.id - y.id;
362 }
363 },
364
365 /**
366 * @param {!WebInspector.Event} event
367 */
368 _onPromiseUpdated: function(event)
369 {
370 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.ta rget);
371 var eventType = /** @type {string} */ (event.data.eventType);
372 var protocolDetails = /** @type {!DebuggerAgent.PromiseDetails} */ (even t.data.promise);
373
374 var promiseIdToDetails = this._promiseDetailsByDebuggerModel.get(debugge rModel);
375 if (!promiseIdToDetails) {
376 promiseIdToDetails = new Map();
377 this._promiseDetailsByDebuggerModel.set(debuggerModel, promiseIdToDe tails);
378 }
379
380 var details = promiseIdToDetails.get(protocolDetails.id);
381 if (!details && eventType === "gc")
382 return;
383
384 var truncated = this._truncateLogIfNeeded(debuggerModel);
385 if (details)
386 details.update(protocolDetails)
387 else
388 details = new WebInspector.PromiseDetails(protocolDetails);
389 promiseIdToDetails.set(details.id, details);
390
391 if (eventType === "gc")
392 details.isGarbageCollected = true;
393
394 if (debuggerModel === this._debuggerModel) {
395 if (!this.isShowing()) {
396 this._refreshIsNeeded = true;
397 return;
398 }
399 if (truncated || this._refreshIsNeeded) {
400 this._refresh();
401 return;
402 }
403
404 var node = /** @type {!WebInspector.DataGridNode} */ (this._promiseI dToNode.get(details.id));
405 var wasVisible = !node || !node._isPromiseHidden;
406
407 // Check for the fast path on GC events.
408 if (eventType === "gc" && node && node.parent && !this._hideCollecte dPromisesSetting.get())
409 node.update(details);
410 else
411 this._attachDataGridNode(details);
412
413 var isVisible = this._shouldBeVisible(details, /** @type {!WebInspec tor.DataGridNode} */(this._promiseIdToNode.get(details.id)));
414 if (wasVisible !== isVisible) {
415 this._hiddenByFilterCount += wasVisible ? 1 : -1;
416 this._updateFilterStatus();
417 }
418 }
419 },
420
421 /**
422 * @param {!WebInspector.PromiseDetails} details
423 */
424 _attachDataGridNode: function(details)
425 {
426 var node = this._createDataGridNode(details);
427 var parentNode = this._findVisibleParentNodeDetails(details);
428 if (parentNode !== node.parent)
429 parentNode.appendChild(node);
430 if (this._shouldBeVisible(details, node))
431 parentNode.expanded = true;
432 else
433 node.remove();
434 },
435
436 /**
437 * @param {!WebInspector.PromiseDetails} details
438 * @return {!WebInspector.DataGridNode}
439 */
440 _findVisibleParentNodeDetails: function(details)
441 {
442 var promiseIdToDetails = /** @type {!Map.<number, !WebInspector.PromiseD etails>} */ (this._promiseDetailsByDebuggerModel.get(this._debuggerModel));
443 var currentDetails = details;
444 while (currentDetails) {
445 var parentId = currentDetails.parentId;
446 if (typeof parentId !== "number")
447 break;
448 currentDetails = promiseIdToDetails.get(parentId);
449 if (!currentDetails)
450 break;
451 var node = this._promiseIdToNode.get(currentDetails.id);
452 if (node && this._shouldBeVisible(currentDetails, node))
453 return node;
454 }
455 return this._dataGrid.rootNode();
456 },
457
458 /**
459 * @param {!WebInspector.PromiseDetails} details
460 * @return {!WebInspector.DataGridNode}
461 */
462 _createDataGridNode: function(details)
463 {
464 var node = this._promiseIdToNode.get(details.id);
465 if (!node) {
466 node = new WebInspector.PromiseDataGridNode(details, this._debuggerM odel, this._linkifier, this._dataGrid);
467 this._promiseIdToNode.set(details.id, node);
468 } else {
469 node.update(details);
470 }
471 return node;
472 },
473
474 _refresh: function()
475 {
476 delete this._refreshIsNeeded;
477 this._clear();
478 if (!this._debuggerModel)
479 return;
480 if (!this._promiseDetailsByDebuggerModel.has(this._debuggerModel))
481 return;
482
483 var rootNode = this._dataGrid.rootNode();
484 var promiseIdToDetails = /** @type {!Map.<number, !WebInspector.PromiseD etails>} */ (this._promiseDetailsByDebuggerModel.get(this._debuggerModel));
485
486 var nodesToInsert = { __proto__: null };
487 // The for..of loop iterates in insertion order.
488 for (var pair of promiseIdToDetails) {
489 var id = /** @type {number} */ (pair[0]);
490 var details = /** @type {!WebInspector.PromiseDetails} */ (pair[1]);
491 var node = this._createDataGridNode(details);
492 node._isPromiseHidden = !this._shouldBeVisible(details, node);
493 if (node._isPromiseHidden) {
494 ++this._hiddenByFilterCount;
495 continue;
496 }
497 nodesToInsert[id] = { details: details, node: node };
498 }
499
500 for (var id in nodesToInsert) {
501 var node = nodesToInsert[id].node;
502 var details = nodesToInsert[id].details;
503 this._findVisibleParentNodeDetails(details).appendChild(node);
504 }
505
506 for (var id in nodesToInsert) {
507 var node = nodesToInsert[id].node;
508 var details = nodesToInsert[id].details;
509 node.expanded = true;
510 }
511
512 this._updateFilterStatus();
513 },
514
515 _clear: function()
516 {
517 this._hiddenByFilterCount = 0;
518 this._updateFilterStatus();
519 this._promiseIdToNode.clear();
520 this._hidePopover();
521 this._dataGrid.rootNode().removeChildren();
522 this._linkifier.reset();
523 },
524
525 /**
526 * @param {!WebInspector.ContextMenu} contextMenu
527 * @param {!WebInspector.DataGridNode} node
528 */
529 _onContextMenu: function(contextMenu, node)
530 {
531 var debuggerModel = this._debuggerModel;
532 if (!debuggerModel)
533 return;
534
535 var promiseId = node.promiseId();
536 if (this._promiseDetailsByDebuggerModel.has(debuggerModel)) {
537 var details = this._promiseDetailsByDebuggerModel.get(debuggerModel) .get(promiseId);
538 if (details.isGarbageCollected)
539 return;
540 }
541
542 contextMenu.appendItem(WebInspector.UIString.capitalize("Show in ^consol e"), showPromiseInConsole);
543 contextMenu.show();
544
545 function showPromiseInConsole()
546 {
547 debuggerModel.getPromiseById(promiseId, "console", didGetPromiseById );
548 }
549
550 /**
551 * @param {?RuntimeAgent.RemoteObject} promise
552 */
553 function didGetPromiseById(promise)
554 {
555 if (!promise)
556 return;
557 var object = debuggerModel.target().runtimeModel.createRemoteObject( promise);
558 object.callFunction(dumpIntoConsole);
559 object.release();
560 /**
561 * @suppressReceiverCheck
562 * @this {Object}
563 */
564 function dumpIntoConsole()
565 {
566 console.log(this);
567 }
568 WebInspector.console.show();
569 }
570 },
571
572 /**
573 * @param {!Element} element
574 * @param {!Event} event
575 * @return {!Element|!AnchorBox|undefined}
576 */
577 _getPopoverAnchor: function(element, event)
578 {
579 if (!this._debuggerModel || !this._promiseDetailsByDebuggerModel.has(thi s._debuggerModel))
580 return undefined;
581 var node = this._dataGrid.dataGridNodeFromNode(element);
582 if (!node)
583 return undefined;
584 var details = this._promiseDetailsByDebuggerModel.get(this._debuggerMode l).get(node.promiseId());
585 if (!details)
586 return undefined;
587 var anchor = element.enclosingNodeOrSelfWithClass("created-column");
588 if (anchor)
589 return details.creationStack ? anchor : undefined;
590 anchor = element.enclosingNodeOrSelfWithClass("settled-column");
591 return (anchor && details.settlementStack) ? anchor : undefined;
592 },
593
594 /**
595 * @param {!Element} anchor
596 * @param {!WebInspector.Popover} popover
597 */
598 _showPopover: function(anchor, popover)
599 {
600 var node = this._dataGrid.dataGridNodeFromNode(anchor);
601 var details = this._promiseDetailsByDebuggerModel.get(this._debuggerMode l).get(node.promiseId());
602
603 var stackTrace;
604 if (anchor.classList.contains("created-column"))
605 stackTrace = details.creationStack;
606 else
607 stackTrace = details.settlementStack;
608
609 var content = WebInspector.DOMPresentationUtils.buildStackTracePreviewCo ntents(this._debuggerModel.target(), this._linkifier, stackTrace);
610 popover.setCanShrink(true);
611 popover.showForAnchor(content, anchor);
612 },
613
614 __proto__: WebInspector.VBox.prototype
615 }
616
617 /**
618 * @constructor
619 * @extends {WebInspector.ViewportDataGridNode}
620 * @param {!WebInspector.PromiseDetails} details
621 * @param {!WebInspector.DebuggerModel} debuggerModel
622 * @param {!WebInspector.Linkifier} linkifier
623 * @param {!WebInspector.ViewportDataGrid} dataGrid
624 */
625 WebInspector.PromiseDataGridNode = function(details, debuggerModel, linkifier, d ataGrid)
626 {
627 WebInspector.ViewportDataGridNode.call(this, {});
628 this._details = details;
629 this._debuggerModel = debuggerModel;
630 this._linkifier = linkifier;
631 /** @type {!Array.<!Element>} */
632 this._linkifiedAnchors = [];
633 this.dataGrid = dataGrid;
634 }
635
636 WebInspector.PromiseDataGridNode.prototype = {
637 _disposeAnchors: function()
638 {
639 for (var i = 0; i < this._linkifiedAnchors.length; ++i)
640 this._linkifier.disposeAnchor(this._debuggerModel.target(), this._li nkifiedAnchors[i]);
641 this._linkifiedAnchors = [];
642 },
643
644 /**
645 * @param {!WebInspector.PromiseDetails} details
646 */
647 update: function(details)
648 {
649 this._disposeAnchors();
650 this._details = details;
651 this.refresh();
652 },
653
654 /**
655 * @override
656 */
657 wasDetached: function()
658 {
659 this._disposeAnchors();
660 },
661
662 /**
663 * @override
664 * @return {number}
665 */
666 nodeSelfHeight: function()
667 {
668 return 24;
669 },
670
671 /**
672 * @return {number}
673 */
674 promiseId: function()
675 {
676 return this._details.id;
677 },
678
679 /**
680 * @override
681 */
682 createCells: function()
683 {
684 this._element.classList.toggle("promise-gc", !!this._details.isGarbageCo llected);
685 WebInspector.ViewportDataGridNode.prototype.createCells.call(this);
686 },
687
688 /**
689 * @param {!Element} cell
690 * @param {?RuntimeAgent.CallFrame=} callFrame
691 */
692 _appendCallFrameAnchor: function(cell, callFrame)
693 {
694 if (!callFrame)
695 return;
696 var anchor = this._linkifier.linkifyConsoleCallFrame(this._debuggerModel .target(), callFrame);
697 this._linkifiedAnchors.push(anchor);
698 cell.appendChild(anchor);
699 },
700
701 /**
702 * @override
703 * @param {string} columnIdentifier
704 * @return {!Element}
705 */
706 createCell: function(columnIdentifier)
707 {
708 var cell = this.createTD(columnIdentifier);
709 var details = this._details;
710
711 switch (columnIdentifier) {
712 case "status":
713 var title = "";
714 switch (details.status) {
715 case "pending":
716 title = WebInspector.UIString("Pending");
717 break;
718 case "resolved":
719 title = WebInspector.UIString("Fulfilled");
720 break;
721 case "rejected":
722 title = WebInspector.UIString("Rejected");
723 break;
724 }
725 if (details.isGarbageCollected)
726 title += " " + WebInspector.UIString("(garbage collected)");
727 cell.createChild("div", "status " + details.status).title = title;
728 break;
729
730 case "function":
731 cell.createTextChild(WebInspector.beautifyFunctionName(details.callF rame ? details.callFrame.functionName : ""));
732 break;
733
734 case "created":
735 this._appendCallFrameAnchor(cell, details.callFrame);
736 break;
737
738 case "settled":
739 this._appendCallFrameAnchor(cell, details.settlementStack && details .settlementStack.callFrames.length ? details.settlementStack.callFrames[0] : nul l);
740 break;
741
742 case "tts":
743 cell.createTextChild(this._ttsCellText());
744 break;
745 }
746
747 return cell;
748 },
749
750 /**
751 * @return {string}
752 */
753 _ttsCellText: function()
754 {
755 var details = this._details;
756 if (details.creationTime && details.settlementTime && details.settlement Time >= details.creationTime)
757 return Number.millisToString(details.settlementTime - details.creati onTime);
758 return "";
759 },
760
761 /**
762 * @param {?RuntimeAgent.CallFrame=} callFrame
763 * @return {string}
764 */
765 _callFrameAnchorTextForSearch: function(callFrame)
766 {
767 if (!callFrame)
768 return "";
769 var script = callFrame.scriptId && this._debuggerModel ? this._debuggerM odel.scriptForId(callFrame.scriptId) : null;
770 var sourceURL = script ? script.sourceURL : callFrame.url;
771 var lineNumber = callFrame.lineNumber || 0;
772 return WebInspector.displayNameForURL(sourceURL) + ":" + lineNumber;
773 },
774
775 /**
776 * @return {string}
777 */
778 dataTextForSearch: function()
779 {
780 var details = this._details;
781 var texts = [
782 WebInspector.beautifyFunctionName(details.callFrame ? details.callFr ame.functionName : ""),
783 this._callFrameAnchorTextForSearch(details.callFrame),
784 this._callFrameAnchorTextForSearch(details.settlementStack && detail s.settlementStack.callFrames.length ? details.settlementStack.callFrames[0] : nu ll),
785 this._ttsCellText().replace(/\u2009/g, " ") // \u2009 is a thin spac e.
786 ];
787 return texts.join(" ");
788 },
789
790 __proto__: WebInspector.ViewportDataGridNode.prototype
791 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698