OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | 3 * Copyright (C) 2012 Intel Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 ".timeline-details-view .timeline-" + category.name + ", " + | 425 ".timeline-details-view .timeline-" + category.name + ", " + |
426 ".timeline-category-" + category.name + " .timeline-tree-icon" | 426 ".timeline-category-" + category.name + " .timeline-tree-icon" |
427 | 427 |
428 return selector + " { background-image: linear-gradient(" + | 428 return selector + " { background-image: linear-gradient(" + |
429 category.fillColorStop0 + ", " + category.fillColorStop1 + " 25%, " + cat
egory.fillColorStop1 + " 25%, " + category.fillColorStop1 + ");" + | 429 category.fillColorStop0 + ", " + category.fillColorStop1 + " 25%, " + cat
egory.fillColorStop1 + " 25%, " + category.fillColorStop1 + ");" + |
430 " border-color: " + category.borderColor + | 430 " border-color: " + category.borderColor + |
431 "}"; | 431 "}"; |
432 } | 432 } |
433 | 433 |
434 /** | 434 /** |
| 435 * @param {!WebInspector.TimelinePresentationModel.Record} record |
| 436 * @param {!WebInspector.Linkifier} linkifier |
| 437 * @param {function(!DocumentFragment)} callback |
| 438 */ |
| 439 WebInspector.TimelineUIUtils.generatePopupContent = function(record, linkifier,
callback) |
| 440 { |
| 441 var imageElement = /** @type {?Element} */ (record.getUserObject("TimelinePr
esentationModel::preview-element") || null); |
| 442 var relatedNode = /** @type {?WebInspector.DOMNode} */ (record.getUserObject
("TimelinePresentationModel::related-node") || null); |
| 443 |
| 444 var barrier = new CallbackBarrier(); |
| 445 if (!imageElement && WebInspector.TimelineUIUtils.needsPreviewElement(record
.type)) |
| 446 WebInspector.DOMPresentationUtils.buildImagePreviewContents(record.url,
false, barrier.createCallback(saveImage)); |
| 447 if (!relatedNode && record.relatedBackendNodeId()) |
| 448 WebInspector.domAgent.pushNodeByBackendIdToFrontend(record.relatedBacken
dNodeId(), barrier.createCallback(saveNode)); |
| 449 barrier.callWhenDone(callbackWrapper); |
| 450 |
| 451 /** |
| 452 * @param {!Element=} element |
| 453 */ |
| 454 function saveImage(element) |
| 455 { |
| 456 imageElement = element || null; |
| 457 record.setUserObject("TimelinePresentationModel::preview-element", eleme
nt); |
| 458 } |
| 459 |
| 460 /** |
| 461 * @param {?DOMAgent.NodeId} nodeId |
| 462 */ |
| 463 function saveNode(nodeId) |
| 464 { |
| 465 if (nodeId !== null) { |
| 466 relatedNode = WebInspector.domAgent.nodeForId(nodeId); |
| 467 record.setUserObject("TimelinePresentationModel::related-node", rela
tedNode); |
| 468 } |
| 469 } |
| 470 |
| 471 /** |
| 472 * @this {WebInspector.TimelinePresentationModel.Record} |
| 473 */ |
| 474 function callbackWrapper() |
| 475 { |
| 476 callback(WebInspector.TimelineUIUtils._generatePopupContentSynchronously
(record, linkifier, imageElement, relatedNode)); |
| 477 } |
| 478 } |
| 479 |
| 480 /** |
| 481 * @param {!WebInspector.TimelinePresentationModel.Record} record |
| 482 * @param {!WebInspector.Linkifier} linkifier |
| 483 * @param {?Element} imagePreviewElement |
| 484 * @param {?WebInspector.DOMNode} relatedNode |
| 485 * @return {!DocumentFragment} |
| 486 */ |
| 487 WebInspector.TimelineUIUtils._generatePopupContentSynchronously = function(recor
d, linkifier, imagePreviewElement, relatedNode) |
| 488 { |
| 489 var fragment = document.createDocumentFragment(); |
| 490 if (!record.coalesced && record.children.length) |
| 491 fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(recor
d.aggregatedStats, record.category, record.selfTime)); |
| 492 else |
| 493 fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(recor
d.aggregatedStats)); |
| 494 |
| 495 if (record.coalesced) |
| 496 return fragment; |
| 497 |
| 498 const recordTypes = WebInspector.TimelineModel.RecordType; |
| 499 |
| 500 // The messages may vary per record type; |
| 501 var callSiteStackTraceLabel; |
| 502 var callStackLabel; |
| 503 var relatedNodeLabel; |
| 504 |
| 505 var contentHelper = new WebInspector.TimelineDetailsContentHelper(linkifier,
true); |
| 506 contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.milli
sToString(record.selfTime, true)); |
| 507 contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.mill
isToString(record.startTimeOffset)); |
| 508 |
| 509 switch (record.type) { |
| 510 case recordTypes.GCEvent: |
| 511 contentHelper.appendTextRow(WebInspector.UIString("Collected"), Numb
er.bytesToString(record.data["usedHeapSizeDelta"])); |
| 512 break; |
| 513 case recordTypes.TimerFire: |
| 514 callSiteStackTraceLabel = WebInspector.UIString("Timer installed"); |
| 515 // Fall-through intended. |
| 516 |
| 517 case recordTypes.TimerInstall: |
| 518 case recordTypes.TimerRemove: |
| 519 contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), recor
d.data["timerId"]); |
| 520 if (typeof record.timeout === "number") { |
| 521 contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Nu
mber.millisToString(record.timeout)); |
| 522 contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !r
ecord.singleShot); |
| 523 } |
| 524 break; |
| 525 case recordTypes.FireAnimationFrame: |
| 526 callSiteStackTraceLabel = WebInspector.UIString("Animation frame req
uested"); |
| 527 contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), re
cord.data["id"]); |
| 528 break; |
| 529 case recordTypes.FunctionCall: |
| 530 if (record.scriptName) |
| 531 contentHelper.appendLocationRow(WebInspector.UIString("Location"
), record.scriptName, record.scriptLine); |
| 532 break; |
| 533 case recordTypes.ScheduleResourceRequest: |
| 534 case recordTypes.ResourceSendRequest: |
| 535 case recordTypes.ResourceReceiveResponse: |
| 536 case recordTypes.ResourceReceivedData: |
| 537 case recordTypes.ResourceFinish: |
| 538 contentHelper.appendElementRow(WebInspector.UIString("Resource"), We
bInspector.linkifyResourceAsNode(record.url)); |
| 539 if (imagePreviewElement) |
| 540 contentHelper.appendElementRow(WebInspector.UIString("Preview"),
imagePreviewElement); |
| 541 if (record.data["requestMethod"]) |
| 542 contentHelper.appendTextRow(WebInspector.UIString("Request Metho
d"), record.data["requestMethod"]); |
| 543 if (typeof record.data["statusCode"] === "number") |
| 544 contentHelper.appendTextRow(WebInspector.UIString("Status Code")
, record.data["statusCode"]); |
| 545 if (record.data["mimeType"]) |
| 546 contentHelper.appendTextRow(WebInspector.UIString("MIME Type"),
record.data["mimeType"]); |
| 547 if (record.data["encodedDataLength"]) |
| 548 contentHelper.appendTextRow(WebInspector.UIString("Encoded Data
Length"), WebInspector.UIString("%d Bytes", record.data["encodedDataLength"])); |
| 549 break; |
| 550 case recordTypes.EvaluateScript: |
| 551 if (record.data && record.url) |
| 552 contentHelper.appendLocationRow(WebInspector.UIString("Script"),
record.url, record.data["lineNumber"]); |
| 553 break; |
| 554 case recordTypes.Paint: |
| 555 var clip = record.data["clip"]; |
| 556 if (clip) { |
| 557 contentHelper.appendTextRow(WebInspector.UIString("Location"), W
ebInspector.UIString("(%d, %d)", clip[0], clip[1])); |
| 558 var clipWidth = WebInspector.TimelinePresentationModel.quadWidth
(clip); |
| 559 var clipHeight = WebInspector.TimelinePresentationModel.quadHeig
ht(clip); |
| 560 contentHelper.appendTextRow(WebInspector.UIString("Dimensions"),
WebInspector.UIString("%d × %d", clipWidth, clipHeight)); |
| 561 } else { |
| 562 // Backward compatibility: older version used x, y, width, heigh
t fields directly in data. |
| 563 if (typeof record.data["x"] !== "undefined" && typeof record.dat
a["y"] !== "undefined") |
| 564 contentHelper.appendTextRow(WebInspector.UIString("Location"
), WebInspector.UIString("(%d, %d)", record.data["x"], record.data["y"])); |
| 565 if (typeof record.data["width"] !== "undefined" && typeof record
.data["height"] !== "undefined") |
| 566 contentHelper.appendTextRow(WebInspector.UIString("Dimension
s"), WebInspector.UIString("%d\u2009\u00d7\u2009%d", record.data["width"], recor
d.data["height"])); |
| 567 } |
| 568 // Fall-through intended. |
| 569 |
| 570 case recordTypes.PaintSetup: |
| 571 case recordTypes.Rasterize: |
| 572 case recordTypes.ScrollLayer: |
| 573 relatedNodeLabel = WebInspector.UIString("Layer root"); |
| 574 break; |
| 575 case recordTypes.AutosizeText: |
| 576 relatedNodeLabel = WebInspector.UIString("Root node"); |
| 577 break; |
| 578 case recordTypes.DecodeImage: |
| 579 case recordTypes.ResizeImage: |
| 580 relatedNodeLabel = WebInspector.UIString("Image element"); |
| 581 if (record.url) |
| 582 contentHelper.appendElementRow(WebInspector.UIString("Image URL"
), WebInspector.linkifyResourceAsNode(record.url)); |
| 583 break; |
| 584 case recordTypes.RecalculateStyles: // We don't want to see default deta
ils. |
| 585 if (record.data["elementCount"]) |
| 586 contentHelper.appendTextRow(WebInspector.UIString("Elements affe
cted"), record.data["elementCount"]); |
| 587 callStackLabel = WebInspector.UIString("Styles recalculation forced"
); |
| 588 break; |
| 589 case recordTypes.Layout: |
| 590 if (record.data["dirtyObjects"]) |
| 591 contentHelper.appendTextRow(WebInspector.UIString("Nodes that ne
ed layout"), record.data["dirtyObjects"]); |
| 592 if (record.data["totalObjects"]) |
| 593 contentHelper.appendTextRow(WebInspector.UIString("Layout tree s
ize"), record.data["totalObjects"]); |
| 594 if (typeof record.data["partialLayout"] === "boolean") { |
| 595 contentHelper.appendTextRow(WebInspector.UIString("Layout scope"
), |
| 596 record.data["partialLayout"] ? WebInspector.UIString("Partial
") : WebInspector.UIString("Whole document")); |
| 597 } |
| 598 callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated"
); |
| 599 callStackLabel = WebInspector.UIString("Layout forced"); |
| 600 relatedNodeLabel = WebInspector.UIString("Layout root"); |
| 601 break; |
| 602 case recordTypes.ConsoleTime: |
| 603 contentHelper.appendTextRow(WebInspector.UIString("Message"), record
.data["message"]); |
| 604 break; |
| 605 case recordTypes.WebSocketCreate: |
| 606 case recordTypes.WebSocketSendHandshakeRequest: |
| 607 case recordTypes.WebSocketReceiveHandshakeResponse: |
| 608 case recordTypes.WebSocketDestroy: |
| 609 if (typeof record.webSocketURL !== "undefined") |
| 610 contentHelper.appendTextRow(WebInspector.UIString("URL"), record
.webSocketURL); |
| 611 if (typeof record.webSocketProtocol !== "undefined") |
| 612 contentHelper.appendTextRow(WebInspector.UIString("WebSocket Pro
tocol"), record.webSocketProtocol); |
| 613 if (typeof record.data["message"] !== "undefined") |
| 614 contentHelper.appendTextRow(WebInspector.UIString("Message"), re
cord.data["message"]); |
| 615 break; |
| 616 case recordTypes.EmbedderCallback: |
| 617 contentHelper.appendTextRow(WebInspector.UIString("Callback Function
"), record.embedderCallbackName); |
| 618 break; |
| 619 default: |
| 620 var detailsNode = WebInspector.TimelineUIUtils.buildDetailsNode(reco
rd, linkifier); |
| 621 if (detailsNode) |
| 622 contentHelper.appendElementRow(WebInspector.UIString("Details"),
detailsNode); |
| 623 break; |
| 624 } |
| 625 |
| 626 /** |
| 627 * @param {!WebInspector.DOMNode} node |
| 628 */ |
| 629 function createNodeAnchor(node) |
| 630 { |
| 631 var span = document.createElement("span"); |
| 632 span.classList.add("node-link"); |
| 633 span.addEventListener("click", WebInspector.Revealer.reveal.bind(WebInsp
ector.Revealer, node, undefined), false); |
| 634 WebInspector.DOMPresentationUtils.decorateNodeLabel(node, span); |
| 635 return span; |
| 636 } |
| 637 |
| 638 if (relatedNode) |
| 639 contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString
("Related node"), createNodeAnchor(relatedNode)); |
| 640 |
| 641 if (record.scriptName && record.type !== recordTypes.FunctionCall) |
| 642 contentHelper.appendLocationRow(WebInspector.UIString("Function Call"),
record.scriptName, record.scriptLine); |
| 643 |
| 644 if (record.jsHeapSizeUsed) { |
| 645 if (record.usedHeapSizeDelta) { |
| 646 var sign = record.usedHeapSizeDelta > 0 ? "+" : "-"; |
| 647 contentHelper.appendTextRow(WebInspector.UIString("Used JavaScript H
eap Size"), |
| 648 WebInspector.UIString("%s (%s%s)", Number.bytesToString(record.j
sHeapSizeUsed), sign, Number.bytesToString(Math.abs(record.usedHeapSizeDelta))))
; |
| 649 } else if (record.category === WebInspector.TimelineUIUtils.categories()
.scripting) |
| 650 contentHelper.appendTextRow(WebInspector.UIString("Used JavaScript H
eap Size"), Number.bytesToString(record.jsHeapSizeUsed)); |
| 651 } |
| 652 |
| 653 if (record.callSiteStackTrace) |
| 654 contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.U
IString("Call Site stack"), record.callSiteStackTrace); |
| 655 |
| 656 if (record.stackTrace) |
| 657 contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("
Call Stack"), record.stackTrace); |
| 658 |
| 659 if (record.warnings) { |
| 660 var ul = document.createElement("ul"); |
| 661 for (var i = 0; i < record.warnings.length; ++i) |
| 662 ul.createChild("li").textContent = record.warnings[i]; |
| 663 contentHelper.appendElementRow(WebInspector.UIString("Warning"), ul); |
| 664 } |
| 665 fragment.appendChild(contentHelper.element); |
| 666 return fragment; |
| 667 } |
| 668 |
| 669 /** |
| 670 * @param {!WebInspector.TimelinePresentationModel.Record} record |
| 671 * @param {!WebInspector.Linkifier} linkifier |
| 672 * @return {?Node} |
| 673 */ |
| 674 WebInspector.TimelineUIUtils.buildDetailsNode = function(record, linkifier) |
| 675 { |
| 676 var details; |
| 677 var detailsText; |
| 678 if (record.coalesced) { |
| 679 var node = document.createElement("span"); |
| 680 node.textContent = WebInspector.UIString("× %d", record.children.length)
; |
| 681 return node; |
| 682 } |
| 683 |
| 684 switch (record.type) { |
| 685 case WebInspector.TimelineModel.RecordType.GCEvent: |
| 686 detailsText = WebInspector.UIString("%s collected", Number.bytesToString
(record.data["usedHeapSizeDelta"])); |
| 687 break; |
| 688 case WebInspector.TimelineModel.RecordType.TimerFire: |
| 689 details = linkifyScriptLocation(); |
| 690 detailsText = record.data["timerId"]; |
| 691 break; |
| 692 case WebInspector.TimelineModel.RecordType.FunctionCall: |
| 693 if (record.scriptName) |
| 694 details = linkifyLocation(record.scriptName, record.scriptLine, 0); |
| 695 break; |
| 696 case WebInspector.TimelineModel.RecordType.FireAnimationFrame: |
| 697 details = linkifyScriptLocation(); |
| 698 detailsText = record.data["id"]; |
| 699 break; |
| 700 case WebInspector.TimelineModel.RecordType.EventDispatch: |
| 701 detailsText = record.data ? record.data["type"] : null; |
| 702 break; |
| 703 case WebInspector.TimelineModel.RecordType.Paint: |
| 704 var width = record.data.clip ? WebInspector.TimelinePresentationModel.qu
adWidth(record.data.clip) : record.data.width; |
| 705 var height = record.data.clip ? WebInspector.TimelinePresentationModel.q
uadHeight(record.data.clip) : record.data.height; |
| 706 if (width && height) |
| 707 detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width,
height); |
| 708 break; |
| 709 case WebInspector.TimelineModel.RecordType.TimerInstall: |
| 710 case WebInspector.TimelineModel.RecordType.TimerRemove: |
| 711 details = linkifyTopCallFrame(); |
| 712 detailsText = record.data["timerId"]; |
| 713 break; |
| 714 case WebInspector.TimelineModel.RecordType.RequestAnimationFrame: |
| 715 case WebInspector.TimelineModel.RecordType.CancelAnimationFrame: |
| 716 details = linkifyTopCallFrame(); |
| 717 detailsText = record.data["id"]; |
| 718 break; |
| 719 case WebInspector.TimelineModel.RecordType.ParseHTML: |
| 720 case WebInspector.TimelineModel.RecordType.RecalculateStyles: |
| 721 details = linkifyTopCallFrame(); |
| 722 break; |
| 723 case WebInspector.TimelineModel.RecordType.EvaluateScript: |
| 724 details = record.url ? linkifyLocation(record.url, record.data["lineNumb
er"], 0) : null; |
| 725 break; |
| 726 case WebInspector.TimelineModel.RecordType.XHRReadyStateChange: |
| 727 case WebInspector.TimelineModel.RecordType.XHRLoad: |
| 728 case WebInspector.TimelineModel.RecordType.ScheduleResourceRequest: |
| 729 case WebInspector.TimelineModel.RecordType.ResourceSendRequest: |
| 730 case WebInspector.TimelineModel.RecordType.ResourceReceivedData: |
| 731 case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse: |
| 732 case WebInspector.TimelineModel.RecordType.ResourceFinish: |
| 733 case WebInspector.TimelineModel.RecordType.DecodeImage: |
| 734 case WebInspector.TimelineModel.RecordType.ResizeImage: |
| 735 detailsText = WebInspector.displayNameForURL(record.url); |
| 736 break; |
| 737 case WebInspector.TimelineModel.RecordType.ConsoleTime: |
| 738 detailsText = record.data["message"]; |
| 739 break; |
| 740 case WebInspector.TimelineModel.RecordType.EmbedderCallback: |
| 741 detailsText = record.data["callbackName"]; |
| 742 break; |
| 743 default: |
| 744 details = record.scriptName ? linkifyLocation(record.scriptName, record.
scriptLine, 0) : linkifyTopCallFrame(); |
| 745 break; |
| 746 } |
| 747 |
| 748 if (!details && detailsText) |
| 749 details = document.createTextNode(detailsText); |
| 750 return details; |
| 751 |
| 752 /** |
| 753 * @param {string} url |
| 754 * @param {number} lineNumber |
| 755 * @param {number=} columnNumber |
| 756 */ |
| 757 function linkifyLocation(url, lineNumber, columnNumber) |
| 758 { |
| 759 // FIXME(62725): stack trace line/column numbers are one-based. |
| 760 columnNumber = columnNumber ? columnNumber - 1 : 0; |
| 761 return linkifier.linkifyLocation(url, lineNumber - 1, columnNumber, "tim
eline-details"); |
| 762 } |
| 763 |
| 764 /** |
| 765 * @param {!ConsoleAgent.CallFrame} callFrame |
| 766 */ |
| 767 function linkifyCallFrame(callFrame) |
| 768 { |
| 769 return linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.co
lumnNumber); |
| 770 } |
| 771 |
| 772 /** |
| 773 * @return {?Element} |
| 774 */ |
| 775 function linkifyTopCallFrame() |
| 776 { |
| 777 if (record.stackTrace) |
| 778 return linkifyCallFrame(record.stackTrace[0]); |
| 779 if (record.callSiteStackTrace) |
| 780 return linkifyCallFrame(record.callSiteStackTrace[0]); |
| 781 return null; |
| 782 } |
| 783 |
| 784 /** |
| 785 * @return {?Element} |
| 786 */ |
| 787 function linkifyScriptLocation() |
| 788 { |
| 789 return record.scriptName ? linkifyLocation(record.scriptName, record.scr
iptLine, 0) : null; |
| 790 } |
| 791 } |
| 792 |
| 793 /** |
435 * @constructor | 794 * @constructor |
436 * @extends {WebInspector.Object} | 795 * @extends {WebInspector.Object} |
437 * @param {string} name | 796 * @param {string} name |
438 * @param {string} title | 797 * @param {string} title |
439 * @param {number} overviewStripGroupIndex | 798 * @param {number} overviewStripGroupIndex |
440 * @param {string} borderColor | 799 * @param {string} borderColor |
441 * @param {string} fillColorStop0 | 800 * @param {string} fillColorStop0 |
442 * @param {string} fillColorStop1 | 801 * @param {string} fillColorStop1 |
443 */ | 802 */ |
444 WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, b
orderColor, fillColorStop0, fillColorStop1) | 803 WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, b
orderColor, fillColorStop0, fillColorStop1) |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 for (var i = 0; i < stackTrace.length; ++i) { | 966 for (var i = 0; i < stackTrace.length; ++i) { |
608 var stackFrame = stackTrace[i]; | 967 var stackFrame = stackTrace[i]; |
609 var row = stackTraceElement.createChild("div"); | 968 var row = stackTraceElement.createChild("div"); |
610 row.createTextChild(stackFrame.functionName || WebInspector.UIString
("(anonymous function)")); | 969 row.createTextChild(stackFrame.functionName || WebInspector.UIString
("(anonymous function)")); |
611 row.createTextChild(" @ "); | 970 row.createTextChild(" @ "); |
612 var urlElement = this._linkifier.linkifyLocation(stackFrame.url, sta
ckFrame.lineNumber - 1); | 971 var urlElement = this._linkifier.linkifyLocation(stackFrame.url, sta
ckFrame.lineNumber - 1); |
613 row.appendChild(urlElement); | 972 row.appendChild(urlElement); |
614 } | 973 } |
615 } | 974 } |
616 } | 975 } |
OLD | NEW |