Changeset 55277 in webkit


Ignore:
Timestamp:
Feb 26, 2010 3:26:08 AM (14 years ago)
Author:
pfeldman@chromium.org
Message:

2010-02-26 Ilya Tikhonovsky <loislo@chromium.org>

Reviewed by Pavel Feldman.

WebInspector: While the current timeline view in DevTools provides a great overview of
things happening, we should make it easier to locate the cause of an event,
e.g., link to JS where relevant.
Caller info support for all kind of Timeline events and new Function Call event will be added.
JSC can be patched the same way as it will be done for V8.

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

  • bindings/js/ScriptCallStack.cpp: (WebCore::ScriptCallStack::callLocation):
  • bindings/js/ScriptCallStack.h:
  • bindings/v8/ScriptCallStack.cpp: (WebCore::ScriptCallStack::create): (WebCore::ScriptCallStack::callLocation):
  • bindings/v8/ScriptCallStack.h:
  • bindings/v8/V8Proxy.cpp: (WebCore::V8Proxy::callFunction):
  • inspector/InspectorTimelineAgent.cpp: (WebCore::InspectorTimelineAgent::InspectorTimelineAgent): (WebCore::InspectorTimelineAgent::~InspectorTimelineAgent): (WebCore::InspectorTimelineAgent::willCallFunction): (WebCore::InspectorTimelineAgent::didCallFunction): (WebCore::InspectorTimelineAgent::pushCurrentRecord):
  • inspector/InspectorTimelineAgent.h: (WebCore::): (WebCore::InspectorTimelineAgent::instanceCount):
  • inspector/TimelineRecordFactory.cpp: (WebCore::TimelineRecordFactory::createGenericRecord): (WebCore::TimelineRecordFactory::createFunctionCallData):
  • inspector/TimelineRecordFactory.h:
  • inspector/front-end/Popover.js: (WebInspector.Popover.prototype.hideWhenClicked): (WebInspector.Popover.prototype._positionElement):
  • inspector/front-end/TimelineAgent.js:
  • inspector/front-end/TimelinePanel.js: (WebInspector.TimelinePanel): (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline): (WebInspector.TimelinePanel.prototype._formatRecord): (WebInspector.TimelinePanel.prototype._getRecordDetails): (WebInspector.TimelinePanel.prototype.reset): (WebInspector.TimelinePanel.prototype._closeRecordDetails): (WebInspector.TimelinePanel.prototype._onScroll): (WebInspector.TimelinePanel.prototype._refresh): (WebInspector.TimelinePanel.prototype._refreshRecords): (WebInspector.TimelineRecordListRow): (WebInspector.TimelineRecordListRow.prototype.update): (WebInspector.TimelineRecordListRow.prototype._createCell): (WebInspector.TimelineRecordListRow.prototype._createRow): (WebInspector.TimelineRecordListRow.prototype._createLinkRow): (WebInspector.TimelineRecordListRow.prototype._generateBubbleContent): (WebInspector.TimelineRecordListRow.prototype._onClick):
  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/inspector.js: (WebInspector.linkifyResourceAsNode):
Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r55276 r55277  
     12010-02-26  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        WebInspector: While the current timeline view in DevTools provides a great overview of
     6        things happening, we should make it easier to locate the cause of an event,
     7        e.g., link to JS where relevant.
     8        Caller info support for all kind of Timeline events and new Function Call event will be added.
     9        https://bugs.webkit.org/show_bug.cgi?id=33995
     10
     11        * inspector/timeline-enum-stability-expected.txt:
     12        * inspector/timeline-test.js
     13
    1142010-02-26  Shinichiro Hamaji  <hamaji@chromium.org>
    215
  • trunk/LayoutTests/inspector/timeline-enum-stability-expected.txt

    r50758 r55277  
    1818WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse : 13
    1919WebInspector.TimelineAgent.RecordType.ResourceFinish : 14
     20WebInspector.TimelineAgent.RecordType.FunctionCall : 15
    2021
  • trunk/LayoutTests/inspector/timeline-test.js

    r51539 r55277  
    2525
    2626    evaluateInWebInspector("frontend_getTimelineResults", function(timelineRecords) {
    27         if (typeof(timelineRecords) === "string")
    28             output("Error fetching Timeline results: " + timelineRecords);
    29         else {
    30             for (var i = 0; i < timelineRecords.length; ++i) {
    31                 var record = timelineRecords[i];
    32                 if (typeName && record.type === timelineAgentRecordType[typeName])
    33                     printTimelineRecordProperties(record);
    34                 if (formatter)
    35                     formatter(record);
     27        try {
     28            if (typeof(timelineRecords) === "string")
     29                output("Error fetching Timeline results: " + timelineRecords);
     30            else {
     31                for (var i = 0; i < timelineRecords.length; ++i) {
     32                    var record = timelineRecords[i];
     33                    if (typeName && record.type === timelineAgentRecordType[typeName])
     34                        printTimelineRecordProperties(record);
     35                    if (formatter)
     36                        formatter(record);
     37                }
    3638            }
     39            if (window.layoutTestController)
     40                layoutTestController.setTimelineProfilingEnabled(false);
     41            notifyDone();
     42        } catch (e) {
     43            console.log("An exception was caught: " + e.toString());
     44            notifyDone(e.toString());
    3745        }
    38         if (window.layoutTestController)
    39             layoutTestController.setTimelineProfilingEnabled(false);
    40         notifyDone();
    4146    });
    4247}
     
    126131            return;
    127132        for (var i = 0; i < records.length; ++i) {
    128             result.push(records[i].record);
     133            result.push(records[i].originalRecordForTests);
    129134            addRecords(records[i].children);
    130135        }
  • trunk/WebCore/ChangeLog

    r55271 r55277  
     12010-02-26  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        WebInspector: While the current timeline view in DevTools provides a great overview of
     6        things happening, we should make it easier to locate the cause of an event,
     7        e.g., link to JS where relevant.
     8        Caller info support for all kind of Timeline events and new Function Call event will be added.
     9        JSC can be patched the same way as it will be done for V8.
     10
     11        https://bugs.webkit.org/show_bug.cgi?id=33995
     12
     13        * bindings/js/ScriptCallStack.cpp:
     14        (WebCore::ScriptCallStack::callLocation):
     15        * bindings/js/ScriptCallStack.h:
     16        * bindings/v8/ScriptCallStack.cpp:
     17        (WebCore::ScriptCallStack::create):
     18        (WebCore::ScriptCallStack::callLocation):
     19        * bindings/v8/ScriptCallStack.h:
     20        * bindings/v8/V8Proxy.cpp:
     21        (WebCore::V8Proxy::callFunction):
     22        * inspector/InspectorTimelineAgent.cpp:
     23        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
     24        (WebCore::InspectorTimelineAgent::~InspectorTimelineAgent):
     25        (WebCore::InspectorTimelineAgent::willCallFunction):
     26        (WebCore::InspectorTimelineAgent::didCallFunction):
     27        (WebCore::InspectorTimelineAgent::pushCurrentRecord):
     28        * inspector/InspectorTimelineAgent.h:
     29        (WebCore::):
     30        (WebCore::InspectorTimelineAgent::instanceCount):
     31        * inspector/TimelineRecordFactory.cpp:
     32        (WebCore::TimelineRecordFactory::createGenericRecord):
     33        (WebCore::TimelineRecordFactory::createFunctionCallData):
     34        * inspector/TimelineRecordFactory.h:
     35        * inspector/front-end/Popover.js:
     36        (WebInspector.Popover.prototype.hideWhenClicked):
     37        (WebInspector.Popover.prototype._positionElement):
     38        * inspector/front-end/TimelineAgent.js:
     39        * inspector/front-end/TimelinePanel.js:
     40        (WebInspector.TimelinePanel):
     41        (WebInspector.TimelinePanel.prototype._innerAddRecordToTimeline):
     42        (WebInspector.TimelinePanel.prototype._formatRecord):
     43        (WebInspector.TimelinePanel.prototype._getRecordDetails):
     44        (WebInspector.TimelinePanel.prototype.reset):
     45        (WebInspector.TimelinePanel.prototype._closeRecordDetails):
     46        (WebInspector.TimelinePanel.prototype._onScroll):
     47        (WebInspector.TimelinePanel.prototype._refresh):
     48        (WebInspector.TimelinePanel.prototype._refreshRecords):
     49        (WebInspector.TimelineRecordListRow):
     50        (WebInspector.TimelineRecordListRow.prototype.update):
     51        (WebInspector.TimelineRecordListRow.prototype._createCell):
     52        (WebInspector.TimelineRecordListRow.prototype._createRow):
     53        (WebInspector.TimelineRecordListRow.prototype._createLinkRow):
     54        (WebInspector.TimelineRecordListRow.prototype._generateBubbleContent):
     55        (WebInspector.TimelineRecordListRow.prototype._onClick):
     56        * inspector/front-end/WebKit.qrc:
     57        * inspector/front-end/inspector.js:
     58        (WebInspector.linkifyResourceAsNode):
     59
    1602010-02-26  Csaba Osztrogonác  <ossy@webkit.org>
    261
  • trunk/WebCore/bindings/js/ScriptCallStack.cpp

    r54138 r55277  
    102102}
    103103
     104bool ScriptCallStack::callLocation(String*, int*)
     105{
     106    return false;
     107}
     108
    104109} // namespace WebCore
  • trunk/WebCore/bindings/js/ScriptCallStack.h

    r53766 r55277  
    5454        const ScriptCallFrame &at(unsigned);
    5555        unsigned size();
     56        static bool callLocation(String*, int*);
    5657
    5758    private:
  • trunk/WebCore/bindings/v8/ScriptCallStack.cpp

    r54051 r55277  
    4444    String sourceName;
    4545    int sourceLineNumber;
    46     if (!V8Proxy::sourceName(sourceName)) {
    47         return 0;
    48     }
    49     if (!V8Proxy::sourceLineNumber(sourceLineNumber)) {
    50         return 0;
    51     }
    52     sourceLineNumber += 1;
     46    if (!callLocation(&sourceName, &sourceLineNumber))
     47      return 0;
    5348    return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber);
     49}
     50
     51bool ScriptCallStack::callLocation(String* sourceName, int* sourceLineNumber)
     52{
     53    if (!V8Proxy::sourceName(*sourceName) || !V8Proxy::sourceLineNumber(*sourceLineNumber))
     54        return false;
     55    *sourceLineNumber += 1;
     56    return true;
    5457}
    5558
  • trunk/WebCore/bindings/v8/ScriptCallStack.h

    r53766 r55277  
    4848        ~ScriptCallStack();
    4949
     50        static bool callLocation(String* sourceName, int* sourceLineNumber);
     51
    5052        const ScriptCallFrame& at(unsigned) const;
    5153        // FIXME: implement retrieving and storing call stack trace
  • trunk/WebCore/bindings/v8/V8Proxy.cpp

    r55217 r55277  
    474474        m_frame->keepAlive();
    475475
     476#if ENABLE(INSPECTOR)
     477        InspectorTimelineAgent* timelineAgent = 0;
     478        if (InspectorTimelineAgent::instanceCount()) {
     479            timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
     480            if (timelineAgent) {
     481                v8::ScriptOrigin origin = function->GetScriptOrigin();
     482                if (!origin.ResourceName().IsEmpty())
     483                    timelineAgent->willCallFunction(v8ValueToWebCoreString(origin.ResourceName()), function->GetScriptLineNumber() + 1);
     484                else
     485                    timelineAgent = 0;
     486            }
     487        }
     488#endif // !ENABLE(INSPECTOR)
     489
    476490        m_recursion++;
    477491        result = function->Call(receiver, argc, args);
    478492        m_recursion--;
     493
     494#if ENABLE(INSPECTOR)
     495        if (timelineAgent && m_frame->page() && timelineAgent == m_frame->page()->inspectorTimelineAgent())
     496            timelineAgent->didCallFunction();
     497#endif // !ENABLE(INSPECTOR)
     498
    479499    }
    480500
  • trunk/WebCore/inspector/InspectorTimelineAgent.cpp

    r53488 r55277  
    4545namespace WebCore {
    4646
     47int InspectorTimelineAgent::s_instanceCount = 0;
     48
    4749InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
    4850    : m_frontend(frontend)
    4951{
     52    ++s_instanceCount;
    5053    ASSERT(m_frontend);
    5154}
     
    5356InspectorTimelineAgent::~InspectorTimelineAgent()
    5457{
     58    ASSERT(s_instanceCount);
     59    --s_instanceCount;
     60}
     61
     62void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine)
     63{
     64    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(m_frontend, scriptName, scriptLine), FunctionCallTimelineRecordType);
     65}
     66
     67void InspectorTimelineAgent::didCallFunction()
     68{
     69    didCompleteCurrentRecord(FunctionCallTimelineRecordType);
    5570}
    5671
     
    109124    }
    110125}
    111    
     126
    112127void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot)
    113128{
     
    241256void InspectorTimelineAgent::pushCurrentRecord(ScriptObject data, TimelineRecordType type)
    242257{
    243     m_recordStack.append(TimelineRecordEntry(TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds()), data, m_frontend->newScriptArray(), type));
    244 }
    245 
     258    ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
     259    m_recordStack.append(TimelineRecordEntry(record, data, m_frontend->newScriptArray(), type));
     260}
    246261} // namespace WebCore
    247262
  • trunk/WebCore/inspector/InspectorTimelineAgent.h

    r53852 r55277  
    6464        ResourceReceiveResponseTimelineRecordType = 13,
    6565        ResourceFinishTimelineRecordType = 14,
     66        FunctionCallTimelineRecordType = 15,
    6667    };
    6768
     
    7576
    7677        // Methods called from WebCore.
     78        void willCallFunction(const String& scriptName, int scriptLine);
     79        void didCallFunction();
     80
    7781        void willDispatchEvent(const Event&);
    7882        void didDispatchEvent();
     
    109113        void didFinishLoadingResource(unsigned long, bool didFail);
    110114
     115        static int instanceCount() { return s_instanceCount; }
    111116        static InspectorTimelineAgent* retrieve(ScriptExecutionContext*);
     117
    112118    private:
    113119        struct TimelineRecordEntry {
     
    128134
    129135        InspectorFrontend* m_frontend;
    130        
     136
    131137        Vector< TimelineRecordEntry > m_recordStack;
     138        static int s_instanceCount;
    132139    };
    133140
  • trunk/WebCore/inspector/TimelineRecordFactory.cpp

    r53488 r55277  
    4040#include "ResourceResponse.h"
    4141#include "ScriptArray.h"
     42#include "ScriptCallStack.h"
    4243#include "ScriptObject.h"
    4344
     
    4849    ScriptObject record = frontend->newScriptObject();
    4950    record.set("startTime", startTime);
     51
     52    String sourceName;
     53    int sourceLineNumber;
     54    if (ScriptCallStack::callLocation(&sourceName, &sourceLineNumber) && sourceName != "undefined") {
     55        record.set("callerScriptName", sourceName);
     56        record.set("callerScriptLine", sourceLineNumber);
     57    }
    5058    return record;
     59}
     60
     61ScriptObject TimelineRecordFactory::createFunctionCallData(InspectorFrontend* frontend, const String& scriptName, int scriptLine)
     62{
     63    ScriptObject data = frontend->newScriptObject();
     64    data.set("scriptName", scriptName);
     65    data.set("scriptLine", scriptLine);
     66    return data;
    5167}
    5268
  • trunk/WebCore/inspector/TimelineRecordFactory.h

    r53488 r55277  
    4747        static ScriptObject createGenericRecord(InspectorFrontend*, double startTime);
    4848
     49        static ScriptObject createFunctionCallData(InspectorFrontend*, const String& scriptName, int scriptLine);
     50
    4951        static ScriptObject createEventDispatchData(InspectorFrontend*, const Event&);
    5052
  • trunk/WebCore/inspector/front-end/Popover.js

    r54974 r55277  
    5555        var preferredHeight = preferredHeight || this.contentElement.offsetHeight;
    5656
    57         this.contentElement.addStyleClass("content");
    58         this.element.appendChild(this.contentElement);
     57        var contentDiv = document.createElement("div");
     58        contentDiv.className = "content";
     59        contentDiv.appendChild(this.contentElement);
     60        this.element.appendChild(contentDiv);
    5961        document.body.appendChild(this.element);
    6062        this._positionElement(anchor, preferredWidth, preferredHeight);
     
    6769    },
    6870
     71    hideWhenClicked: function()
     72    {
     73        this.element.addEventListener("click", this.hide.bind(this));
     74    },
     75
    6976    _positionElement: function(anchorElement, preferredWidth, preferredHeight)
    7077    {
    7178        const borderWidth = 25;
    7279        const scrollerWidth = 11;
    73         const arrowHeight = 10;
     80        const arrowHeight = 15;
    7481        const arrowOffset = 15;
     82        const borderRadius = 10;
    7583       
    7684        // Skinny tooltips are not pretty, their arrow location is not nice.
     
    8896        }
    8997
    90         var newElementPosition = { x: 0, y: 0, width: preferredWidth + borderWidth * 2, height: preferredHeight + borderWidth * 2 };
     98        var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
    9199
    92100        var verticalAlignment;
     
    96104        if (roomAbove > roomBelow) {
    97105            // Positioning above the anchor.
    98             if (anchorBox.y > newElementPosition.height)
    99                 newElementPosition.y = anchorBox.y - newElementPosition.height;
     106            if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
     107                newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
    100108            else {
    101                 newElementPosition.y = 0;
    102                 newElementPosition.height = anchorBox.y - newElementPosition.y;
    103                 // Reserve room for vertical scroller anyways.
    104                 newElementPosition.width += scrollerWidth;
     109                newElementPosition.y = borderRadius * 2;
     110                newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
    105111            }
    106112            verticalAlignment = "bottom";
    107113        } else {
    108114            // Positioning below the anchor.
    109             newElementPosition.y = anchorBox.y + anchorBox.height;
    110             if (newElementPosition.y + newElementPosition.height >= totalHeight) {
    111                 newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height;
    112                 // Reserve room for vertical scroller.
    113                 newElementPosition.width += scrollerWidth;
    114             }
     115            newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
     116            if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight)
     117                newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
    115118            // Align arrow.
    116             newElementPosition.y -= arrowHeight;
    117119            verticalAlignment = "top";
    118120        }
     
    120122        var horizontalAlignment;
    121123        if (anchorBox.x + newElementPosition.width < totalWidth) {
    122             newElementPosition.x = Math.max(0, anchorBox.x) - borderWidth - arrowOffset;
     124            newElementPosition.x = Math.max(borderRadius, anchorBox.x - arrowOffset);
    123125            horizontalAlignment = "left";
    124         } else if (newElementPosition.width < totalWidth) {
    125             newElementPosition.x = totalWidth - newElementPosition.width;
     126        } else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
     127            newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
    126128            horizontalAlignment = "right";
    127129            // Position arrow accurately.
    128             this._popupArrowElement.style.right = totalWidth - anchorBox.x - borderWidth - anchorBox.width + "px";
     130            this._popupArrowElement.style.right = totalWidth - anchorBox.x - anchorBox.width - borderRadius + "px";
    129131        } else {
    130             newElementPosition.x = 0;
    131             newElementPosition.width = totalWidth;
     132            newElementPosition.x = borderRadius;
     133            newElementPosition.width = totalWidth - scrollerWidth - borderRadius * 2;
     134            newElementPosition.height += scrollerWidth;
    132135            horizontalAlignment = "left";
    133136            if (verticalAlignment === "bottom")
    134137                newElementPosition.y -= scrollerWidth;
    135138            // Position arrow accurately.
    136             this._popupArrowElement.style.left = anchorBox.x - borderWidth + "px";
     139            this._popupArrowElement.style.left = anchorBox.x + "px";
    137140        }
    138141
    139         // Reserve room for horizontal scroller.
    140         newElementPosition.height += scrollerWidth;
    141 
    142142        this.element.className = "popover " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
    143         this.element.positionAt(newElementPosition.x, newElementPosition.y);
    144         this.element.style.width = newElementPosition.width + "px";
    145         this.element.style.height = newElementPosition.height + "px";
     143        this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
     144        this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
     145        this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
    146146    }
    147147}
  • trunk/WebCore/inspector/front-end/TimelineAgent.js

    r50515 r55277  
    4949    ResourceSendRequest : 12,
    5050    ResourceReceiveResponse : 13,
    51     ResourceFinish : 14
     51    ResourceFinish : 14,
     52    FunctionCall : 15
    5253};
    5354
  • trunk/WebCore/inspector/front-end/TimelinePanel.js

    r53588 r55277  
    8080    this._records = [];
    8181    this._sendRequestRecords = {};
     82    this._timerRecords = {};
     83
    8284    this._calculator = new WebInspector.TimelineCalculator();
    8385    this._boundariesAreValid = true;
     86    this._scrollTop = 0;
    8487}
    8588
     
    151154                this._lastRecord.title == formattedRecord.title &&
    152155                this._lastRecord.details == formattedRecord.details &&
     156                this._lastRecord.callerScriptName == formattedRecord.callerScriptName &&
     157                this._lastRecord.callerScriptLine == formattedRecord.callerScriptLine &&
    153158                formattedRecord.startTime - this._lastRecord.endTime < 0.1) {
    154159            this._lastRecord.endTime = formattedRecord.endTime;
     
    187192            this._recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
    188193            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 };
    189195        }
    190196
     
    201207        formattedRecord.type = record.type;
    202208        formattedRecord.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : formattedRecord.startTime;
    203         formattedRecord.record = record;
     209        formattedRecord.originalRecordForTests = record;
     210        formattedRecord.callerScriptName = record.callerScriptName;
     211        formattedRecord.callerScriptLine = record.callerScriptLine;
    204212
    205213        // Make resource receive record last since request was sent; make finish record last since response received.
     
    211219                sendRequestRecord._responseReceivedFormattedTime = formattedRecord.startTime;
    212220                formattedRecord.startTime = sendRequestRecord.startTime;
    213                 sendRequestRecord.details = this._getRecordDetails(record);
     221                formattedRecord.details = this._getRecordDetails(sendRequestRecord);
     222                formattedRecord.callerScriptName = sendRequestRecord.callerScriptName;
     223                formattedRecord.callerScriptLine = sendRequestRecord.callerScriptLine;
    214224            }
    215225        } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceFinish) {
    216226            var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
    217             if (sendRequestRecord) // False for main resource.
     227            if (sendRequestRecord) {// False for main resource.
    218228                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            }
    219245        }
    220246        formattedRecord.details = this._getRecordDetails(record);
     
    226252    {
    227253        switch (record.type) {
     254        case WebInspector.TimelineAgent.RecordType.FunctionCall:
     255            return WebInspector.displayNameForURL(record.data.scriptName + ":" + record.data.scriptLine);
    228256        case WebInspector.TimelineAgent.RecordType.EventDispatch:
    229257            return record.data ? record.data.type : "";
     
    265293
    266294    resize: function() {
     295        this._closeRecordDetails();
    267296        this._scheduleRefresh();
    268297    },
     
    272301        this._lastRecord = null;
    273302        this._sendRequestRecords = {};
     303        this._timerRecords = {};
    274304        this._records = [];
    275305        this._boundariesAreValid = false;
     
    277307        this._adjustScrollPosition(0);
    278308        this._refresh();
     309        this._closeRecordDetails();
     310    },
     311
     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        }
    279320    },
    280321
     
    289330    _onScroll: function(event)
    290331    {
     332        this._closeRecordDetails();
    291333        var scrollTop = this._containerElement.scrollTop;
    292334        var dividersTop = Math.max(0, scrollTop);
     
    297339    _windowChanged: function()
    298340    {
     341        this._closeRecordDetails();
    299342        this._scheduleRefresh();
    300343    },
     
    322365            delete this._refreshTimeout;
    323366        }
    324      
     367
    325368        if (!this._boundariesAreValid)
    326369            this._overviewPane.update(this._records);
     
    392435            }
    393436
    394             listRowElement.listRow.update(record, isEven);
     437            listRowElement.listRow.update(record, isEven, this._calculator, visibleTop);
    395438            graphRowElement.graphRow.update(record, isEven, this._calculator, width, expandOffset, i);
    396439
     
    500543    this.element = document.createElement("div");
    501544    this.element.listRow = this;
     545    this.element.style.cursor = "pointer";
    502546    var iconElement = document.createElement("span");
    503547    iconElement.className = "timeline-tree-icon";
     
    521565    this.element.appendChild(this._dataElement);
    522566    this.element.appendChild(this._repeatCountElement);
     567    this.element.addEventListener("click", this._onClick.bind(this));
    523568}
    524569
    525570WebInspector.TimelineRecordListRow.prototype = {
    526     update: function(record, isEven)
    527     {
     571    update: function(record, isEven, calculator, offset)
     572    {
     573        this._record = record;
     574        this._calculator = calculator;
     575        this._offset = offset;
     576
    528577        this.element.className = "timeline-tree-item timeline-category-" + record.category.name + (isEven ? " even" : "");
    529578        this._typeElement.textContent = record.title;
     
    543592    },
    544593
     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
    545674    dispose: function()
    546675    {
     
    548677    }
    549678}
    550 
    551679
    552680WebInspector.TimelineRecordGraphRow = function(graphContainer, refreshCallback, rowHeight)
  • trunk/WebCore/inspector/front-end/inspector.css

    r55233 r55277  
    38483848    background-color: rgb(255, 255, 194);
    38493849}
     3850
     3851.timeline-details-row-title {
     3852    font-weight: bold;
     3853    text-align: right;
     3854    white-space: nowrap;
     3855}
     3856
     3857.timeline-details-row-data {
     3858    white-space: nowrap;
     3859}
     3860
     3861.timeline-details-title {
     3862    font-weight: bold;
     3863    white-space: nowrap;
     3864}
  • trunk/WebCore/inspector/front-end/inspector.js

    r55231 r55277  
    15491549    // FIXME:  Get rid of linkifyURL entirely.
    15501550    return WebInspector.linkifyURLAsNode(url, linkText, classes, isExternal, tooltipText).outerHTML;
     1551}
     1552
     1553WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, classes, tooltipText)
     1554{
     1555    var linkText = WebInspector.displayNameForURL(url);
     1556    if (lineNumber)
     1557        linkText += ":" + lineNumber;
     1558    var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
     1559    node.lineNumber = lineNumber;
     1560    node.preferredPanel = preferredPanel;
     1561    return node;
    15511562}
    15521563
  • trunk/WebKit/chromium/DEPS

    r55011 r55277  
    4444  'ots_rev': '26',
    4545  'skia_rev': '490',
    46   'v8_rev': '3781',
     46  'v8_rev': '3963',
    4747
    4848  # Windows:
Note: See TracChangeset for help on using the changeset viewer.