Changeset 55530 in webkit


Ignore:
Timestamp:
Mar 4, 2010 9:35:58 AM (14 years ago)
Author:
pfeldman@chromium.org
Message:

2010-03-04 Pavel Feldman <pfeldman@chromium.org>

Reviewed by Timothy Hatcher.

Web Inspector: Popup for Timeline panel will work in a tooltip mode

https://bugs.webkit.org/show_bug.cgi?id=35680

Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r55528 r55530  
     12010-03-04  Pavel Feldman  <pfeldman@chromium.org>
     2
     3        Reviewed by Timothy Hatcher.
     4
     5        Web Inspector: Popup for Timeline panel will work in a tooltip mode
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=35680
     8
     9        * inspector/front-end/Popover.js:
     10        (WebInspector.Popover):
     11        (WebInspector.Popover.prototype.show):
     12        (WebInspector.Popover.prototype.hide):
     13        (WebInspector.Popover.prototype._positionElement):
     14        (WebInspector.PopoverHelper):
     15        (WebInspector.PopoverHelper.prototype._mouseDown):
     16        (WebInspector.PopoverHelper.prototype._mouseMove.doHide):
     17        (WebInspector.PopoverHelper.prototype._mouseMove):
     18        (WebInspector.PopoverHelper.prototype._resetHoverTimer):
     19        (WebInspector.PopoverHelper.prototype.hidePopup):
     20        (WebInspector.PopoverHelper.prototype._mouseHover):
     21        (WebInspector.PopoverHelper.prototype._killHidePopupTimer):
     22        * inspector/front-end/TimelineOverviewPane.js:
     23        (WebInspector.TimelineOverviewPane.prototype.reset):
     24        * inspector/front-end/TimelinePanel.js:
     25        (WebInspector.TimelinePanel):
     26        (WebInspector.TimelinePanel.prototype.get _recordStyles):
     27        (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
     28        (WebInspector.TimelinePanel.prototype._scheduleRefresh):
     29        (WebInspector.TimelinePanel.prototype._refreshRecords):
     30        (WebInspector.TimelinePanel.prototype._adjustScrollPosition):
     31        (WebInspector.TimelinePanel.prototype._getPopoverAnchor):
     32        (WebInspector.TimelinePanel.prototype._showPopover):
     33        (WebInspector.TimelinePanel.prototype._closeRecordDetails):
     34        (WebInspector.TimelineRecordListRow):
     35        (WebInspector.TimelineRecordListRow.prototype.update):
     36        (WebInspector.TimelineRecordGraphRow):
     37        (WebInspector.TimelineRecordGraphRow.prototype._onClick):
     38        (WebInspector.TimelinePanel.FormattedRecord):
     39        (WebInspector.TimelinePanel.FormattedRecord.prototype._createCell):
     40        (WebInspector.TimelinePanel.FormattedRecord.prototype._createRow):
     41        (WebInspector.TimelinePanel.FormattedRecord.prototype._createLinkRow):
     42        (WebInspector.TimelinePanel.FormattedRecord.prototype._generatePopupContent):
     43        (WebInspector.TimelinePanel.FormattedRecord.prototype._getRecordDetails):
     44        * inspector/front-end/inspector.css:
     45
    1462010-03-04  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
    247
  • trunk/WebCore/inspector/front-end/Popover.js

    r55277 r55530  
    3939
    4040    this.contentElement = contentElement;
     41    this._contentDiv = document.createElement("div");
     42    this._contentDiv.className = "content";
    4143}
    4244
     
    5557        var preferredHeight = preferredHeight || this.contentElement.offsetHeight;
    5658
    57         var contentDiv = document.createElement("div");
    58         contentDiv.className = "content";
    59         contentDiv.appendChild(this.contentElement);
    60         this.element.appendChild(contentDiv);
     59        this._contentDiv.appendChild(this.contentElement);
     60        this.element.appendChild(this._contentDiv);
    6161        document.body.appendChild(this.element);
    6262        this._positionElement(anchor, preferredWidth, preferredHeight);
     
    6565    hide: function()
    6666    {
    67         delete WebInspector.Popover._popoverElement;
    68         document.body.removeChild(this.element);
    69     },
    70 
    71     hideWhenClicked: function()
    72     {
    73         this.element.addEventListener("click", this.hide.bind(this));
     67        if (WebInspector.Popover._popoverElement) {
     68            delete WebInspector.Popover._popoverElement;
     69            document.body.removeChild(this.element);
     70        }
    7471    },
    7572
     
    7976        const scrollerWidth = 11;
    8077        const arrowHeight = 15;
    81         const arrowOffset = 15;
     78        const arrowOffset = 10;
    8279        const borderRadius = 10;
    83        
     80
    8481        // Skinny tooltips are not pretty, their arrow location is not nice.
    8582        preferredWidth = Math.max(preferredWidth, 50);
     
    122119        var horizontalAlignment;
    123120        if (anchorBox.x + newElementPosition.width < totalWidth) {
    124             newElementPosition.x = Math.max(borderRadius, anchorBox.x - arrowOffset);
     121            newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
    125122            horizontalAlignment = "left";
    126123        } else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
     
    128125            horizontalAlignment = "right";
    129126            // Position arrow accurately.
    130             this._popupArrowElement.style.right = totalWidth - anchorBox.x - anchorBox.width - borderRadius + "px";
     127            var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
     128            arrowRightPosition += anchorBox.width / 2;
     129            this._popupArrowElement.style.right = arrowRightPosition + "px";
    131130        } else {
    132131            newElementPosition.x = borderRadius;
    133             newElementPosition.width = totalWidth - scrollerWidth - borderRadius * 2;
     132            newElementPosition.width = totalWidth - borderRadius * 2;
    134133            newElementPosition.height += scrollerWidth;
    135134            horizontalAlignment = "left";
     
    137136                newElementPosition.y -= scrollerWidth;
    138137            // Position arrow accurately.
    139             this._popupArrowElement.style.left = anchorBox.x + "px";
     138            this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
     139            this._popupArrowElement.style.left += anchorBox.width / 2;
    140140        }
    141141
     
    146146    }
    147147}
     148
     149WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopup, showOnClick, onHide)
     150{
     151    this._panelElement = panelElement;
     152    this._getAnchor = getAnchor;
     153    this._showPopup = showPopup;
     154    this._showOnClick = showOnClick;
     155    this._onHide = onHide;
     156    panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
     157    panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
     158}
     159
     160WebInspector.PopoverHelper.prototype = {
     161    _mouseDown: function(event)
     162    {
     163        this._resetHoverTimer();
     164        if (this._showOnClick) {
     165            var anchor = this._getAnchor(event.target);
     166            if (anchor) {
     167                this._popup = this._showPopup(anchor);
     168                this._killHidePopupTimer();
     169            }
     170        }
     171    },
     172
     173    _mouseMove: function(event)
     174    {
     175        // Pretend that nothing has happened.
     176        if (this._hoverElement === event.target || (this._hoverElement && this._hoverElement.isAncestor(event.target)))
     177            return;
     178
     179        this._resetHoverTimer();
     180        // User has 500ms to reach the popup.
     181        if (this._popup) {
     182            var self = this;
     183            function doHide()
     184            {
     185                self.hidePopup();
     186                delete self._hidePopupTimer;
     187            }
     188            this._hidePopupTimer = setTimeout(doHide, 500);
     189        }
     190
     191        this._hoverElement = this._getAnchor(event.target);
     192        if (!this._hoverElement)
     193            return;
     194
     195        const toolTipDelay = this._popup ? 600 : 1000;
     196        this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
     197    },
     198
     199    _resetHoverTimer: function()
     200    {
     201        if (this._hoverTimer) {
     202            clearTimeout(this._hoverTimer);
     203            delete this._hoverTimer;
     204        }
     205    },
     206
     207    hidePopup: function()
     208    {
     209        if (!this._popup)
     210            return;
     211
     212        if (this._onHide)
     213            this._onHide();
     214
     215        this._popup.hide();
     216        delete this._popup;
     217    },
     218
     219    _mouseHover: function(element)
     220    {
     221        delete this._hoverTimer;
     222
     223        this._popup = this._showPopup(element);
     224        this._popup.contentElement.addEventListener("mousemove", this._killHidePopupTimer.bind(this), true);
     225    },
     226
     227    _killHidePopupTimer: function()
     228    {
     229        if (this._hidePopupTimer) {
     230            clearTimeout(this._hidePopupTimer);
     231            delete this._hidePopupTimer;
     232
     233            // We know that we reached the popup, but we might have moved over other elements.
     234            // Discard pending command.
     235            this._resetHoverTimer();
     236        }
     237    }
     238}
  • trunk/WebCore/inspector/front-end/TimelineOverviewPane.js

    r53588 r55530  
    176176        this.windowLeft = 0.0;
    177177        this.windowRight = 1.0;
    178         this._setWindowPosition(0, this._overviewGrid.element.clientWidth);
     178        this._overviewWindowElement.style.left = "0%";
     179        this._overviewWindowElement.style.width = "100%";
     180        this._leftResizeElement.style.left = "0%";
     181        this._rightResizeElement.style.left = "100%";
    179182        this._overviewCalculator.reset();
    180183        this._overviewGrid.updateDividers(true, this._overviewCalculator);
  • trunk/WebCore/inspector/front-end/TimelinePanel.js

    r55277 r55530  
    8585    this._boundariesAreValid = true;
    8686    this._scrollTop = 0;
     87
     88    this._popoverHelper = new WebInspector.PopoverHelper(this._containerElement, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true);
    8789}
    8890
     
    112114    },
    113115
     116    get _recordStyles()
     117    {
     118        if (!this._recordStylesArray) {
     119            var recordTypes = WebInspector.TimelineAgent.RecordType;
     120            var recordStyles = {};
     121            recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: this.categories.scripting };
     122            recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: this.categories.rendering };
     123            recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: this.categories.rendering };
     124            recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: this.categories.rendering };
     125            recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse"), category: this.categories.loading };
     126            recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: this.categories.scripting };
     127            recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: this.categories.scripting };
     128            recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: this.categories.scripting };
     129            recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: this.categories.scripting };
     130            recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: this.categories.scripting };
     131            recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: this.categories.scripting };
     132            recordStyles[recordTypes.MarkTimeline] = { title: WebInspector.UIString("Mark"), category: this.categories.scripting };
     133            recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: this.categories.loading };
     134            recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
     135            recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: this.categories.loading };
     136            recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: this.categories.scripting };
     137            this._recordStylesArray = recordStyles;
     138        }
     139        return this._recordStylesArray;
     140    },
     141
    114142    _createStatusbarButtons: function()
    115143    {
     
    147175    _innerAddRecordToTimeline: function(record, collection)
    148176    {
    149         var formattedRecord = this._formatRecord(record);
     177        var formattedRecord = new WebInspector.TimelinePanel.FormattedRecord(record, this._recordStyles, this._sendRequestRecords, this._timerRecords);
    150178
    151179        // Glue subsequent records with same category and title together if they are closer than 100ms to each other.
     
    172200    },
    173201
    174     _formatRecord: function(record)
    175     {
    176         var recordTypes = WebInspector.TimelineAgent.RecordType;
    177         if (!this._recordStyles) {
    178             this._recordStyles = {};
    179             this._recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: this.categories.scripting };
    180             this._recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: this.categories.rendering };
    181             this._recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: this.categories.rendering };
    182             this._recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: this.categories.rendering };
    183             this._recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse"), category: this.categories.loading };
    184             this._recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: this.categories.scripting };
    185             this._recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: this.categories.scripting };
    186             this._recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: this.categories.scripting };
    187             this._recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: this.categories.scripting };
    188             this._recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: this.categories.scripting };
    189             this._recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: this.categories.scripting };
    190             this._recordStyles[recordTypes.MarkTimeline] = { title: WebInspector.UIString("Mark"), category: this.categories.scripting };
    191             this._recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: this.categories.loading };
    192             this._recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
    193             this._recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: this.categories.loading };
    194             this._recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: this.categories.scripting };
    195         }
    196 
    197         var style = this._recordStyles[record.type];
    198         if (!style)
    199             style = this._recordStyles[recordTypes.EventDispatch];
    200 
    201         var formattedRecord = {};
    202         formattedRecord.category = style.category;
    203         formattedRecord.title = style.title;
    204         formattedRecord.startTime = record.startTime / 1000;
    205         formattedRecord.data = record.data;
    206         formattedRecord.count = 1;
    207         formattedRecord.type = record.type;
    208         formattedRecord.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : formattedRecord.startTime;
    209         formattedRecord.originalRecordForTests = record;
    210         formattedRecord.callerScriptName = record.callerScriptName;
    211         formattedRecord.callerScriptLine = record.callerScriptLine;
    212 
    213         // Make resource receive record last since request was sent; make finish record last since response received.
    214         if (record.type === WebInspector.TimelineAgent.RecordType.ResourceSendRequest) {
    215             this._sendRequestRecords[record.data.identifier] = formattedRecord;
    216         } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse) {
    217             var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
    218             if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
    219                 sendRequestRecord._responseReceivedFormattedTime = formattedRecord.startTime;
    220                 formattedRecord.startTime = sendRequestRecord.startTime;
    221                 formattedRecord.details = this._getRecordDetails(sendRequestRecord);
    222                 formattedRecord.callerScriptName = sendRequestRecord.callerScriptName;
    223                 formattedRecord.callerScriptLine = sendRequestRecord.callerScriptLine;
    224             }
    225         } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceFinish) {
    226             var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
    227             if (sendRequestRecord) {// False for main resource.
    228                 formattedRecord.startTime = sendRequestRecord._responseReceivedFormattedTime;
    229                 formattedRecord.callerScriptName = sendRequestRecord.callerScriptName;
    230                 formattedRecord.callerScriptLine = sendRequestRecord.callerScriptLine;
    231             }
    232         } else if (record.type === WebInspector.TimelineAgent.RecordType.TimerInstall) {
    233             formattedRecord.timeout = record.data.timeout;
    234             formattedRecord.singleShot = record.data.singleShot;
    235             this._timerRecords[record.data.timerId] = formattedRecord;
    236         } else if (record.type === WebInspector.TimelineAgent.RecordType.TimerFire ||
    237                    record.type === WebInspector.TimelineAgent.RecordType.TimerRemove) {
    238             var timerInstalledRecord = this._timerRecords[record.data.timerId];
    239             if (timerInstalledRecord) {
    240                 formattedRecord.callSiteScriptName = timerInstalledRecord.callerScriptName;
    241                 formattedRecord.callSiteScriptLine = timerInstalledRecord.callerScriptLine;
    242                 formattedRecord.timeout = timerInstalledRecord.timeout;
    243                 formattedRecord.singleShot = timerInstalledRecord.singleShot;
    244             }
    245         }
    246         formattedRecord.details = this._getRecordDetails(record);
    247 
    248         return formattedRecord;
    249     },
    250 
    251     _getRecordDetails: function(record)
    252     {
    253         switch (record.type) {
    254         case WebInspector.TimelineAgent.RecordType.FunctionCall:
    255             return WebInspector.displayNameForURL(record.data.scriptName + ":" + record.data.scriptLine);
    256         case WebInspector.TimelineAgent.RecordType.EventDispatch:
    257             return record.data ? record.data.type : "";
    258         case WebInspector.TimelineAgent.RecordType.Paint:
    259             return record.data.width + "\u2009\u00d7\u2009" + record.data.height;
    260         case WebInspector.TimelineAgent.RecordType.TimerInstall:
    261         case WebInspector.TimelineAgent.RecordType.TimerRemove:
    262         case WebInspector.TimelineAgent.RecordType.TimerFire:
    263             return record.data.timerId;
    264         case WebInspector.TimelineAgent.RecordType.XHRReadyStateChange:
    265         case WebInspector.TimelineAgent.RecordType.XHRLoad:
    266         case WebInspector.TimelineAgent.RecordType.EvaluateScript:
    267         case WebInspector.TimelineAgent.RecordType.ResourceSendRequest:
    268             return WebInspector.displayNameForURL(record.data.url);
    269         case WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse:
    270         case WebInspector.TimelineAgent.RecordType.ResourceFinish:
    271             var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
    272             return sendRequestRecord ? WebInspector.displayNameForURL(sendRequestRecord.data.url) : "";
    273         case WebInspector.TimelineAgent.RecordType.MarkTimeline:
    274             return record.data.message;
    275         default:
    276             return "";
    277         }
    278     },
    279 
    280202    setSidebarWidth: function(width)
    281203    {
     
    310232    },
    311233
    312     _closeRecordDetails: function()
    313     {
    314         var details = WebInspector.TimelinePanel.recordDetails;
    315         if (details) {
    316             details.hide();
    317             delete details;
    318             WebInspector.TimelinePanel.recordDetails = null;
    319         }
    320     },
    321 
    322234    show: function()
    323235    {
     
    345257    _scheduleRefresh: function(preserveBoundaries)
    346258    {
     259        if (preserveBoundaries)
     260            this._closeRecordDetails();
    347261        this._boundariesAreValid &= preserveBoundaries;
    348262        if (this._needsRefresh)
     
    422336        var graphRowElement = this._graphRowsElement.firstChild;
    423337        var scheduleRefreshCallback = this._scheduleRefresh.bind(this, true);
     338
    424339        for (var i = startIndex; i < endIndex; ++i) {
    425340            var record = recordsInWindow[i];
     
    435350            }
    436351
    437             listRowElement.listRow.update(record, isEven, this._calculator, visibleTop);
    438             graphRowElement.graphRow.update(record, isEven, this._calculator, width, expandOffset, i);
     352            listRowElement.row.update(record, isEven, this._calculator, visibleTop);
     353            graphRowElement.row.update(record, isEven, this._calculator, width, expandOffset, i);
    439354
    440355            listRowElement = listRowElement.nextSibling;
     
    445360        while (listRowElement) {
    446361            var nextElement = listRowElement.nextSibling;
    447             listRowElement.listRow.dispose();
     362            listRowElement.row.dispose();
    448363            listRowElement = nextElement;
    449364        }
    450365        while (graphRowElement) {
    451366            var nextElement = graphRowElement.nextSibling;
    452             graphRowElement.graphRow.dispose();
     367            graphRowElement.row.dispose();
    453368            graphRowElement = nextElement;
    454369        }
     
    478393        if ((this._containerElement.scrollTop + this._containerElement.offsetHeight) > totalHeight + 1)
    479394            this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
     395    },
     396
     397    _getPopoverAnchor: function(element)
     398    {
     399        return element.enclosingNodeOrSelfWithClass("timeline-graph-bar") || element.enclosingNodeOrSelfWithClass("timeline-tree-item");
     400    },
     401
     402    _showPopover: function(anchor)
     403    {
     404        var record = anchor.row._record;
     405        var popover = new WebInspector.Popover(record._generatePopupContent(this._calculator));
     406        popover.show(anchor);
     407        return popover;
     408    },
     409
     410    _closeRecordDetails: function()
     411    {
     412        this._popoverHelper.hidePopup();
    480413    }
    481414}
    482415
    483416WebInspector.TimelinePanel.prototype.__proto__ = WebInspector.Panel.prototype;
    484 
    485417
    486418WebInspector.TimelineCategory = function(name, title, color)
     
    490422    this.color = color;
    491423}
    492 
    493424
    494425WebInspector.TimelineCalculator = function()
     
    542473{
    543474    this.element = document.createElement("div");
    544     this.element.listRow = this;
     475    this.element.row = this;
    545476    this.element.style.cursor = "pointer";
    546477    var iconElement = document.createElement("span");
     
    565496    this.element.appendChild(this._dataElement);
    566497    this.element.appendChild(this._repeatCountElement);
    567     this.element.addEventListener("click", this._onClick.bind(this));
    568498}
    569499
     
    578508        this._typeElement.textContent = record.title;
    579509
    580         if (record.details) {
     510        if (record.details)
    581511            this._dataElement.textContent = "(" + record.details + ")";
    582             this._dataElement.title = record.details;
    583         } else {
     512        else
    584513            this._dataElement.textContent = "";
    585             this._dataElement.title = "";
    586         }
    587514
    588515        if (record.count > 1)
     
    592519    },
    593520
    594     _createCell: function(content, styleName)
    595     {
    596         var text = document.createElement("label");
    597         text.appendChild(document.createTextNode(content));
    598         var cell = document.createElement("td");
    599         cell.className = "timeline-details";
    600         if (styleName)
    601              cell.className += " " + styleName;
    602         cell.textContent = content;
    603         return cell;
    604     },
    605 
    606     _createRow: function(title, content)
    607     {
    608         var row = document.createElement("tr");
    609         row.appendChild(this._createCell(title, "timeline-details-row-title"));
    610         row.appendChild(this._createCell(content, "timeline-details-row-data"));
    611         return row;
    612     },
    613 
    614     _createLinkRow: function(title, content)
    615     {
    616         var row = document.createElement("tr");
    617         row.appendChild(this._createCell(title, "timeline-details-row-title"));
    618         var cell = document.createElement("td");
    619         cell.appendChild(content);
    620         row.appendChild(cell);
    621         return row;
    622     },
    623 
    624     _generateBubbleContent: function()
    625     {
    626         var bubbleContentTable = document.createElement("table");
    627         var titleCell = this._createCell(WebInspector.UIString("%s - Details", this._record.title), "timeline-details-title");
    628         titleCell.colSpan = 2;
    629         titleCell.appendChild(document.createElement("hr"));
    630         var titleRow = document.createElement("tr");
    631         titleRow.appendChild(titleCell);
    632         bubbleContentTable.appendChild(titleRow);
    633         var text = Number.secondsToString(this._record.endTime - this._record.startTime) + " (@" +
    634             this._calculator.formatValue(this._record.startTime - this._calculator.minimumBoundary) + ")";
    635         bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Duration"), text));
    636 
    637         if (this._record.details) {
    638             if ( this._record.type == WebInspector.TimelineAgent.RecordType.TimerInstall ||
    639                  this._record.type == WebInspector.TimelineAgent.RecordType.TimerFire ||
    640                  this._record.type == WebInspector.TimelineAgent.RecordType.TimerRemove) {
    641                 bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("TimerId"), this._record.data.timerId));
    642                 if (this._record.timeout) {
    643                     bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Timeout"), this._record.timeout));
    644                     bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Repeats"), !this._record.singleShot));
    645                 }
    646                 if (this._record.callSiteScriptLine) {
    647                     var link = WebInspector.linkifyResourceAsNode(this._record.callSiteScriptName, "scripts", this._record.callSiteScriptLine);
    648                     bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Call Site"), link));
    649                 }
    650             } else if ( this._record.type == WebInspector.TimelineAgent.RecordType.FunctionCall ) {
    651                 var link = WebInspector.linkifyResourceAsNode(this._record.data.scriptName, "scripts", this._record.data.scriptLine);
    652                 bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Location"), link));
    653             } else
    654                 bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Details"), this._record.details));
    655         }
    656 
    657         if (this._record.callerScriptName) {
    658             var link = WebInspector.linkifyResourceAsNode(this._record.callerScriptName, "scripts", this._record.callerScriptLine);
    659             bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Caller"), link));
    660         }
    661         return bubbleContentTable;
    662     },
    663 
    664     _onClick: function(event)
    665     {
    666         if (this._record) {
    667             var details = new WebInspector.Popover(this._generateBubbleContent());
    668             details.hideWhenClicked();
    669             details.show(this.element);
    670             WebInspector.TimelinePanel.recordDetails = details;
    671         }
    672     },
    673 
    674521    dispose: function()
    675522    {
     
    678525}
    679526
    680 WebInspector.TimelineRecordGraphRow = function(graphContainer, refreshCallback, rowHeight)
     527WebInspector.TimelineRecordGraphRow = function(graphContainer, scheduleRefresh, rowHeight)
    681528{
    682529    this.element = document.createElement("div");
    683     this.element.graphRow = this;
     530    this.element.row = this;
    684531
    685532    this._barAreaElement = document.createElement("div");
     
    689536    this._barElement = document.createElement("div");
    690537    this._barElement.className = "timeline-graph-bar";
     538    this._barElement.row = this;
    691539    this._barAreaElement.appendChild(this._barElement);
    692540
     
    700548
    701549    this._expandElement.addEventListener("click", this._onClick.bind(this));
    702     this._refreshCallback = refreshCallback;
    703550    this._rowHeight = rowHeight;
     551
     552    this._scheduleRefresh = scheduleRefresh;
    704553}
    705554
     
    737586    {
    738587        this._record.collapsed = !this._record.collapsed;
    739         this._refreshCallback();
     588        this._scheduleRefresh();
    740589    },
    741590
     
    746595    }
    747596}
     597
     598WebInspector.TimelinePanel.FormattedRecord = function(record, recordStyles, sendRequestRecords, timerRecords)
     599{
     600    var recordTypes = WebInspector.TimelineAgent.RecordType;
     601    var style = recordStyles[record.type];
     602
     603    this.category = style.category;
     604    this.title = style.title;
     605    this.startTime = record.startTime / 1000;
     606    this.data = record.data;
     607    this.count = 1;
     608    this.type = record.type;
     609    this.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : this.startTime;
     610    this.originalRecordForTests = record;
     611    this.callerScriptName = record.callerScriptName;
     612    this.callerScriptLine = record.callerScriptLine;
     613
     614    // Make resource receive record last since request was sent; make finish record last since response received.
     615    if (record.type === recordTypes.ResourceSendRequest) {
     616        sendRequestRecords[record.data.identifier] = this;
     617    } else if (record.type === recordTypes.ResourceReceiveResponse) {
     618        var sendRequestRecord = sendRequestRecords[record.data.identifier];
     619        if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
     620            sendRequestRecord._responseReceivedFormattedTime = this.startTime;
     621            this.startTime = sendRequestRecord.startTime;
     622            this.details = this._getRecordDetails(sendRequestRecord, sendRequestRecords);
     623            this.callerScriptName = sendRequestRecord.callerScriptName;
     624            this.callerScriptLine = sendRequestRecord.callerScriptLine;
     625        }
     626    } else if (record.type === recordTypes.ResourceFinish) {
     627        var sendRequestRecord = sendRequestRecords[record.data.identifier];
     628        if (sendRequestRecord) {// False for main resource.
     629            this.startTime = sendRequestRecord._responseReceivedFormattedTime;
     630            this.callerScriptName = sendRequestRecord.callerScriptName;
     631            this.callerScriptLine = sendRequestRecord.callerScriptLine;
     632        }
     633    } else if (record.type === recordTypes.TimerInstall) {
     634        this.timeout = record.data.timeout;
     635        this.singleShot = record.data.singleShot;
     636        timerRecords[record.data.timerId] = this;
     637    } else if (record.type === recordTypes.TimerFire) {
     638        var timerInstalledRecord = timerRecords[record.data.timerId];
     639        if (timerInstalledRecord) {
     640            this.callSiteScriptName = timerInstalledRecord.callerScriptName;
     641            this.callSiteScriptLine = timerInstalledRecord.callerScriptLine;
     642            this.timeout = timerInstalledRecord.timeout;
     643            this.singleShot = timerInstalledRecord.singleShot;
     644        }
     645    }
     646    this.details = this._getRecordDetails(record, sendRequestRecords);
     647}
     648
     649WebInspector.TimelinePanel.FormattedRecord.prototype = {
     650    _createCell: function(content, styleName)
     651    {
     652        var text = document.createElement("label");
     653        text.appendChild(document.createTextNode(content));
     654        var cell = document.createElement("td");
     655        cell.className = "timeline-details";
     656        if (styleName)
     657            cell.className += " " + styleName;
     658        cell.textContent = content;
     659        return cell;
     660    },
     661
     662    _createRow: function(title, content)
     663    {
     664        var row = document.createElement("tr");
     665        row.appendChild(this._createCell(title, "timeline-details-row-title"));
     666        row.appendChild(this._createCell(content, "timeline-details-row-data"));
     667        return row;
     668    },
     669
     670    _createLinkRow: function(title, content)
     671    {
     672        var row = document.createElement("tr");
     673        row.appendChild(this._createCell(title, "timeline-details-row-title"));
     674        var cell = document.createElement("td");
     675        cell.appendChild(content);
     676        row.appendChild(cell);
     677        return row;
     678    },
     679
     680    _generatePopupContent: function(calculator)
     681    {
     682        var recordContentTable = document.createElement("table");
     683        var titleCell = this._createCell(WebInspector.UIString("%s - Details", this.title), "timeline-details-title");
     684        titleCell.colSpan = 2;
     685        var titleRow = document.createElement("tr");
     686        titleRow.appendChild(titleCell);
     687        recordContentTable.appendChild(titleRow);
     688        var text = Number.secondsToString(this.endTime - this.startTime) + " (@" +
     689        calculator.formatValue(this.startTime - calculator.minimumBoundary) + ")";
     690        recordContentTable.appendChild(this._createRow(WebInspector.UIString("Duration"), text));
     691
     692        if (this.details) {
     693            if ( this.type == WebInspector.TimelineAgent.RecordType.TimerInstall ||
     694                this.type == WebInspector.TimelineAgent.RecordType.TimerFire ||
     695                this.type == WebInspector.TimelineAgent.RecordType.TimerRemove) {
     696                recordContentTable.appendChild(this._createRow(WebInspector.UIString("Timer Id"), this.data.timerId));
     697                if (this.timeout) {
     698                    recordContentTable.appendChild(this._createRow(WebInspector.UIString("Timeout"), this.timeout));
     699                    recordContentTable.appendChild(this._createRow(WebInspector.UIString("Repeats"), !this.singleShot));
     700                }
     701                if (this.callSiteScriptLine) {
     702                    var link = WebInspector.linkifyResourceAsNode(this.callSiteScriptName, "scripts", this.callSiteScriptLine, "timeline-details");
     703                    recordContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Call Site"), link));
     704                }
     705            } else if ( this.type == WebInspector.TimelineAgent.RecordType.FunctionCall ) {
     706                var link = WebInspector.linkifyResourceAsNode(this.data.scriptName, "scripts", this.data.scriptLine, "timeline-details");
     707                recordContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Location"), link));
     708            } else
     709                recordContentTable.appendChild(this._createRow(WebInspector.UIString("Details"), this.details));
     710        }
     711
     712        if (this.callerScriptName) {
     713            var link = WebInspector.linkifyResourceAsNode(this.callerScriptName, "scripts", this.callerScriptLine);
     714            recordContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Caller"), link));
     715        }
     716        return recordContentTable;
     717    },
     718
     719    _getRecordDetails: function(record, sendRequestRecords)
     720    {
     721        switch (record.type) {
     722            case WebInspector.TimelineAgent.RecordType.FunctionCall:
     723                return WebInspector.displayNameForURL(record.data.scriptName + ":" + record.data.scriptLine);
     724            case WebInspector.TimelineAgent.RecordType.EventDispatch:
     725                return record.data ? record.data.type : "";
     726            case WebInspector.TimelineAgent.RecordType.Paint:
     727                return record.data.width + "\u2009\u00d7\u2009" + record.data.height;
     728            case WebInspector.TimelineAgent.RecordType.TimerInstall:
     729            case WebInspector.TimelineAgent.RecordType.TimerRemove:
     730            case WebInspector.TimelineAgent.RecordType.TimerFire:
     731                return record.data.timerId;
     732            case WebInspector.TimelineAgent.RecordType.XHRReadyStateChange:
     733            case WebInspector.TimelineAgent.RecordType.XHRLoad:
     734            case WebInspector.TimelineAgent.RecordType.EvaluateScript:
     735            case WebInspector.TimelineAgent.RecordType.ResourceSendRequest:
     736                return WebInspector.displayNameForURL(record.data.url);
     737            case WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse:
     738            case WebInspector.TimelineAgent.RecordType.ResourceFinish:
     739                var sendRequestRecord = sendRequestRecords[record.data.identifier];
     740                return sendRequestRecord ? WebInspector.displayNameForURL(sendRequestRecord.data.url) : "";
     741            case WebInspector.TimelineAgent.RecordType.MarkTimeline:
     742                return record.data.message;
     743            default:
     744                return "";
     745        }
     746    }
     747}
     748
  • trunk/WebCore/inspector/front-end/inspector.css

    r55522 r55530  
    35893589    opacity: 0.8;
    35903590    -webkit-border-image: url(Images/timelineBarGray.png) 4 4 5 4;
    3591     pointer-events: none;
     3591    z-index: 180;
     3592    pointer-events: visibleFill;
    35923593}
    35933594
     
    38703871}
    38713872
     3873.timeline-details {
     3874    -webkit-user-select: text;
     3875}
     3876
    38723877.timeline-details-row-title {
    38733878    font-weight: bold;
     
    38833888    font-weight: bold;
    38843889    white-space: nowrap;
     3890    text-overflow: ellipsis;
     3891    overflow: hidden;
     3892    font-size: 11px;
     3893    padding-left: 10px;
     3894    padding-bottom: 5px;
     3895    border-bottom: 1px solid rgb(194,194,147);
    38853896}
    38863897
Note: See TracChangeset for help on using the changeset viewer.