[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

pfeldman at chromium.org pfeldman at chromium.org
Thu Apr 8 01:59:58 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 3b207dc834b63feb17879c861437a5265e90645b
Author: pfeldman at chromium.org <pfeldman at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Feb 26 11:26:08 2010 +0000

    2010-02-26  Ilya Tikhonovsky  <loislo at 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):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55277 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1742f90..1bba428 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2010-02-26  Ilya Tikhonovsky  <loislo at 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.
+        https://bugs.webkit.org/show_bug.cgi?id=33995
+
+        * inspector/timeline-enum-stability-expected.txt:
+        * inspector/timeline-test.js
+
 2010-02-26  Shinichiro Hamaji  <hamaji at chromium.org>
 
         Unreviewed. Skip failing tests.
diff --git a/LayoutTests/inspector/timeline-enum-stability-expected.txt b/LayoutTests/inspector/timeline-enum-stability-expected.txt
index 6ec8883..20510d9 100644
--- a/LayoutTests/inspector/timeline-enum-stability-expected.txt
+++ b/LayoutTests/inspector/timeline-enum-stability-expected.txt
@@ -17,4 +17,5 @@ WebInspector.TimelineAgent.RecordType.MarkTimeline : 11
 WebInspector.TimelineAgent.RecordType.ResourceSendRequest : 12
 WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse : 13
 WebInspector.TimelineAgent.RecordType.ResourceFinish : 14
+WebInspector.TimelineAgent.RecordType.FunctionCall : 15
 
diff --git a/LayoutTests/inspector/timeline-test.js b/LayoutTests/inspector/timeline-test.js
index bf159ce..d9b2fec 100644
--- a/LayoutTests/inspector/timeline-test.js
+++ b/LayoutTests/inspector/timeline-test.js
@@ -24,20 +24,25 @@ function printTimelineRecords(performActions, typeName, formatter)
     });
 
     evaluateInWebInspector("frontend_getTimelineResults", function(timelineRecords) {
-        if (typeof(timelineRecords) === "string")
-            output("Error fetching Timeline results: " + timelineRecords);
-        else {
-            for (var i = 0; i < timelineRecords.length; ++i) {
-                var record = timelineRecords[i];
-                if (typeName && record.type === timelineAgentRecordType[typeName])
-                    printTimelineRecordProperties(record);
-                if (formatter)
-                    formatter(record);
+        try {
+            if (typeof(timelineRecords) === "string")
+                output("Error fetching Timeline results: " + timelineRecords);
+            else {
+                for (var i = 0; i < timelineRecords.length; ++i) {
+                    var record = timelineRecords[i];
+                    if (typeName && record.type === timelineAgentRecordType[typeName])
+                        printTimelineRecordProperties(record);
+                    if (formatter)
+                        formatter(record);
+                }
             }
+            if (window.layoutTestController)
+                layoutTestController.setTimelineProfilingEnabled(false);
+            notifyDone();
+        } catch (e) {
+            console.log("An exception was caught: " + e.toString());
+            notifyDone(e.toString());
         }
-        if (window.layoutTestController)
-            layoutTestController.setTimelineProfilingEnabled(false);
-        notifyDone();
     });
 }
 
@@ -125,7 +130,7 @@ function frontend_getTimelineResults() {
         if (!records)
             return;
         for (var i = 0; i < records.length; ++i) {
-            result.push(records[i].record);
+            result.push(records[i].originalRecordForTests);
             addRecords(records[i].children);
         }
     }
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 841287d..4b209e2 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,62 @@
+2010-02-26  Ilya Tikhonovsky  <loislo at 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):
+
 2010-02-26  Csaba Osztrogonác  <ossy at webkit.org>
 
         Unreviewed. Roll-out r55263 because it broke fast/forms/textarea-type-spaces-pretty-diff.html.
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index 12666f8..ccae1dd 100644
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
diff --git a/WebCore/bindings/js/ScriptCallStack.cpp b/WebCore/bindings/js/ScriptCallStack.cpp
index a435588..c8eadd1 100644
--- a/WebCore/bindings/js/ScriptCallStack.cpp
+++ b/WebCore/bindings/js/ScriptCallStack.cpp
@@ -101,4 +101,9 @@ void ScriptCallStack::initialize()
     m_initialized = true;
 }
 
+bool ScriptCallStack::callLocation(String*, int*)
+{
+    return false;
+}
+
 } // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptCallStack.h b/WebCore/bindings/js/ScriptCallStack.h
index 52362ea..f5f8ae0 100644
--- a/WebCore/bindings/js/ScriptCallStack.h
+++ b/WebCore/bindings/js/ScriptCallStack.h
@@ -53,6 +53,7 @@ namespace WebCore {
         // frame retrieval methods
         const ScriptCallFrame &at(unsigned);
         unsigned size();
+        static bool callLocation(String*, int*);
 
     private:
         void initialize();
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
index 21063ed..d563d42 100644
--- a/WebCore/bindings/v8/ScriptCallStack.cpp
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -43,16 +43,19 @@ namespace WebCore {
 ScriptCallStack* ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) {
     String sourceName;
     int sourceLineNumber;
-    if (!V8Proxy::sourceName(sourceName)) {
-        return 0;
-    }
-    if (!V8Proxy::sourceLineNumber(sourceLineNumber)) {
-        return 0;
-    }
-    sourceLineNumber += 1;
+    if (!callLocation(&sourceName, &sourceLineNumber))
+      return 0;
     return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber);
 }
 
+bool ScriptCallStack::callLocation(String* sourceName, int* sourceLineNumber)
+{
+    if (!V8Proxy::sourceName(*sourceName) || !V8Proxy::sourceLineNumber(*sourceLineNumber))
+        return false;
+    *sourceLineNumber += 1;
+    return true;
+}
+
 ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber)
     : m_lastCaller(String(), sourceName, sourceLineNumber, arguments, skipArgumentCount)
     , m_scriptState(ScriptState::current())
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
index 8ac394c..db27f15 100644
--- a/WebCore/bindings/v8/ScriptCallStack.h
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -47,6 +47,8 @@ namespace WebCore {
         static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0);
         ~ScriptCallStack();
 
+        static bool callLocation(String* sourceName, int* sourceLineNumber);
+
         const ScriptCallFrame& at(unsigned) const;
         // FIXME: implement retrieving and storing call stack trace
         unsigned size() const { return 1; }
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index fade001..9baaf3c 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -473,9 +473,29 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
         // execution finishs before firing the timer.
         m_frame->keepAlive();
 
+#if ENABLE(INSPECTOR)
+        InspectorTimelineAgent* timelineAgent = 0;
+        if (InspectorTimelineAgent::instanceCount()) {
+            timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+            if (timelineAgent) {
+                v8::ScriptOrigin origin = function->GetScriptOrigin();
+                if (!origin.ResourceName().IsEmpty())
+                    timelineAgent->willCallFunction(v8ValueToWebCoreString(origin.ResourceName()), function->GetScriptLineNumber() + 1);
+                else
+                    timelineAgent = 0;
+            }
+        }
+#endif // !ENABLE(INSPECTOR)
+
         m_recursion++;
         result = function->Call(receiver, argc, args);
         m_recursion--;
+
+#if ENABLE(INSPECTOR)
+        if (timelineAgent && m_frame->page() && timelineAgent == m_frame->page()->inspectorTimelineAgent())
+            timelineAgent->didCallFunction();
+#endif // !ENABLE(INSPECTOR)
+
     }
 
     // Release the storage mutex if applicable.
diff --git a/WebCore/inspector/InspectorTimelineAgent.cpp b/WebCore/inspector/InspectorTimelineAgent.cpp
index cbf6ee1..0624c87 100644
--- a/WebCore/inspector/InspectorTimelineAgent.cpp
+++ b/WebCore/inspector/InspectorTimelineAgent.cpp
@@ -44,14 +44,29 @@
 
 namespace WebCore {
 
+int InspectorTimelineAgent::s_instanceCount = 0;
+
 InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
     : m_frontend(frontend)
 {
+    ++s_instanceCount;
     ASSERT(m_frontend);
 }
 
 InspectorTimelineAgent::~InspectorTimelineAgent()
 {
+    ASSERT(s_instanceCount);
+    --s_instanceCount;
+}
+
+void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine)
+{
+    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(m_frontend, scriptName, scriptLine), FunctionCallTimelineRecordType);
+}
+
+void InspectorTimelineAgent::didCallFunction()
+{
+    didCompleteCurrentRecord(FunctionCallTimelineRecordType);
 }
 
 void InspectorTimelineAgent::willDispatchEvent(const Event& event)
@@ -108,7 +123,7 @@ void InspectorTimelineAgent::didWriteHTML(unsigned int endLine)
         didCompleteCurrentRecord(ParseHTMLTimelineRecordType);
     }
 }
-   
+
 void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot)
 {
     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
@@ -240,9 +255,9 @@ double InspectorTimelineAgent::currentTimeInMilliseconds()
 
 void InspectorTimelineAgent::pushCurrentRecord(ScriptObject data, TimelineRecordType type)
 {
-    m_recordStack.append(TimelineRecordEntry(TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds()), data, m_frontend->newScriptArray(), type));
+    ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
+    m_recordStack.append(TimelineRecordEntry(record, data, m_frontend->newScriptArray(), type));
 }
-
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
diff --git a/WebCore/inspector/InspectorTimelineAgent.h b/WebCore/inspector/InspectorTimelineAgent.h
index fd86ba7..7f6646c 100644
--- a/WebCore/inspector/InspectorTimelineAgent.h
+++ b/WebCore/inspector/InspectorTimelineAgent.h
@@ -63,6 +63,7 @@ namespace WebCore {
         ResourceSendRequestTimelineRecordType = 12,
         ResourceReceiveResponseTimelineRecordType = 13,
         ResourceFinishTimelineRecordType = 14,
+        FunctionCallTimelineRecordType = 15,
     };
 
     class InspectorTimelineAgent : public Noncopyable {
@@ -74,6 +75,9 @@ namespace WebCore {
         void resetFrontendProxyObject(InspectorFrontend*);
 
         // Methods called from WebCore.
+        void willCallFunction(const String& scriptName, int scriptLine);
+        void didCallFunction();
+
         void willDispatchEvent(const Event&);
         void didDispatchEvent();
 
@@ -108,7 +112,9 @@ namespace WebCore {
         void didReceiveResourceResponse(unsigned long, const ResourceResponse&);
         void didFinishLoadingResource(unsigned long, bool didFail);
 
+        static int instanceCount() { return s_instanceCount; }
         static InspectorTimelineAgent* retrieve(ScriptExecutionContext*);
+
     private:
         struct TimelineRecordEntry {
             TimelineRecordEntry(ScriptObject record, ScriptObject data, ScriptArray children, TimelineRecordType type) : record(record), data(data), children(children), type(type) { }
@@ -127,8 +133,9 @@ namespace WebCore {
         void addRecordToTimeline(ScriptObject, TimelineRecordType);
 
         InspectorFrontend* m_frontend;
-        
+
         Vector< TimelineRecordEntry > m_recordStack;
+        static int s_instanceCount;
     };
 
 inline InspectorTimelineAgent* InspectorTimelineAgent::retrieve(ScriptExecutionContext* context)
diff --git a/WebCore/inspector/TimelineRecordFactory.cpp b/WebCore/inspector/TimelineRecordFactory.cpp
index 525e61d..73981a2 100644
--- a/WebCore/inspector/TimelineRecordFactory.cpp
+++ b/WebCore/inspector/TimelineRecordFactory.cpp
@@ -39,6 +39,7 @@
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
 #include "ScriptArray.h"
+#include "ScriptCallStack.h"
 #include "ScriptObject.h"
 
 namespace WebCore {
@@ -47,9 +48,24 @@ ScriptObject TimelineRecordFactory::createGenericRecord(InspectorFrontend* front
 {
     ScriptObject record = frontend->newScriptObject();
     record.set("startTime", startTime);
+
+    String sourceName;
+    int sourceLineNumber;
+    if (ScriptCallStack::callLocation(&sourceName, &sourceLineNumber) && sourceName != "undefined") {
+        record.set("callerScriptName", sourceName);
+        record.set("callerScriptLine", sourceLineNumber);
+    }
     return record;
 }
 
+ScriptObject TimelineRecordFactory::createFunctionCallData(InspectorFrontend* frontend, const String& scriptName, int scriptLine)
+{
+    ScriptObject data = frontend->newScriptObject();
+    data.set("scriptName", scriptName);
+    data.set("scriptLine", scriptLine);
+    return data;
+}
+
 ScriptObject TimelineRecordFactory::createEventDispatchData(InspectorFrontend* frontend, const Event& event)
 {
     ScriptObject data = frontend->newScriptObject();
diff --git a/WebCore/inspector/TimelineRecordFactory.h b/WebCore/inspector/TimelineRecordFactory.h
index b7437f5..910c295 100644
--- a/WebCore/inspector/TimelineRecordFactory.h
+++ b/WebCore/inspector/TimelineRecordFactory.h
@@ -46,6 +46,8 @@ namespace WebCore {
     public:
         static ScriptObject createGenericRecord(InspectorFrontend*, double startTime);
 
+        static ScriptObject createFunctionCallData(InspectorFrontend*, const String& scriptName, int scriptLine);
+
         static ScriptObject createEventDispatchData(InspectorFrontend*, const Event&);
 
         static ScriptObject createGenericTimerData(InspectorFrontend*, int timerId);
diff --git a/WebCore/inspector/front-end/Popover.js b/WebCore/inspector/front-end/Popover.js
index 70e4ac9..866cb24 100644
--- a/WebCore/inspector/front-end/Popover.js
+++ b/WebCore/inspector/front-end/Popover.js
@@ -54,8 +54,10 @@ WebInspector.Popover.prototype = {
         var preferredWidth = preferredWidth || this.contentElement.offsetWidth;
         var preferredHeight = preferredHeight || this.contentElement.offsetHeight;
 
-        this.contentElement.addStyleClass("content");
-        this.element.appendChild(this.contentElement);
+        var contentDiv = document.createElement("div");
+        contentDiv.className = "content";
+        contentDiv.appendChild(this.contentElement);
+        this.element.appendChild(contentDiv);
         document.body.appendChild(this.element);
         this._positionElement(anchor, preferredWidth, preferredHeight);
     },
@@ -66,12 +68,18 @@ WebInspector.Popover.prototype = {
         document.body.removeChild(this.element);
     },
 
+    hideWhenClicked: function()
+    {
+        this.element.addEventListener("click", this.hide.bind(this));
+    },
+
     _positionElement: function(anchorElement, preferredWidth, preferredHeight)
     {
         const borderWidth = 25;
         const scrollerWidth = 11;
-        const arrowHeight = 10;
+        const arrowHeight = 15;
         const arrowOffset = 15;
+        const borderRadius = 10;
         
         // Skinny tooltips are not pretty, their arrow location is not nice.
         preferredWidth = Math.max(preferredWidth, 50);
@@ -87,7 +95,7 @@ WebInspector.Popover.prototype = {
             anchorElement = anchorElement.parentElement;
         }
 
-        var newElementPosition = { x: 0, y: 0, width: preferredWidth + borderWidth * 2, height: preferredHeight + borderWidth * 2 };
+        var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
 
         var verticalAlignment;
         var roomAbove = anchorBox.y;
@@ -95,53 +103,45 @@ WebInspector.Popover.prototype = {
 
         if (roomAbove > roomBelow) {
             // Positioning above the anchor.
-            if (anchorBox.y > newElementPosition.height)
-                newElementPosition.y = anchorBox.y - newElementPosition.height;
+            if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
+                newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
             else {
-                newElementPosition.y = 0;
-                newElementPosition.height = anchorBox.y - newElementPosition.y;
-                // Reserve room for vertical scroller anyways.
-                newElementPosition.width += scrollerWidth;
+                newElementPosition.y = borderRadius * 2;
+                newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
             }
             verticalAlignment = "bottom";
         } else {
             // Positioning below the anchor.
-            newElementPosition.y = anchorBox.y + anchorBox.height;
-            if (newElementPosition.y + newElementPosition.height >= totalHeight) {
-                newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height;
-                // Reserve room for vertical scroller.
-                newElementPosition.width += scrollerWidth;
-            }
+            newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
+            if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight)
+                newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
             // Align arrow.
-            newElementPosition.y -= arrowHeight;
             verticalAlignment = "top";
         }
 
         var horizontalAlignment;
         if (anchorBox.x + newElementPosition.width < totalWidth) {
-            newElementPosition.x = Math.max(0, anchorBox.x) - borderWidth - arrowOffset;
+            newElementPosition.x = Math.max(borderRadius, anchorBox.x - arrowOffset);
             horizontalAlignment = "left";
-        } else if (newElementPosition.width < totalWidth) {
-            newElementPosition.x = totalWidth - newElementPosition.width;
+        } else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
+            newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
             horizontalAlignment = "right";
             // Position arrow accurately.
-            this._popupArrowElement.style.right = totalWidth - anchorBox.x - borderWidth - anchorBox.width + "px";
+            this._popupArrowElement.style.right = totalWidth - anchorBox.x - anchorBox.width - borderRadius + "px";
         } else {
-            newElementPosition.x = 0;
-            newElementPosition.width = totalWidth;
+            newElementPosition.x = borderRadius;
+            newElementPosition.width = totalWidth - scrollerWidth - borderRadius * 2;
+            newElementPosition.height += scrollerWidth;
             horizontalAlignment = "left";
             if (verticalAlignment === "bottom")
                 newElementPosition.y -= scrollerWidth;
             // Position arrow accurately.
-            this._popupArrowElement.style.left = anchorBox.x - borderWidth + "px";
+            this._popupArrowElement.style.left = anchorBox.x + "px";
         }
 
-        // Reserve room for horizontal scroller.
-        newElementPosition.height += scrollerWidth;
-
         this.element.className = "popover " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
-        this.element.positionAt(newElementPosition.x, newElementPosition.y);
-        this.element.style.width = newElementPosition.width  + "px";
-        this.element.style.height = newElementPosition.height  + "px";
+        this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
+        this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
+        this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
     }
 }
diff --git a/WebCore/inspector/front-end/TimelineAgent.js b/WebCore/inspector/front-end/TimelineAgent.js
index c9e9d64..50dce10 100644
--- a/WebCore/inspector/front-end/TimelineAgent.js
+++ b/WebCore/inspector/front-end/TimelineAgent.js
@@ -48,7 +48,8 @@ WebInspector.TimelineAgent.RecordType = {
     MarkTimeline : 11,
     ResourceSendRequest : 12,
     ResourceReceiveResponse : 13,
-    ResourceFinish : 14
+    ResourceFinish : 14,
+    FunctionCall : 15
 };
 
 WebInspector.addRecordToTimeline = function(record) {
diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js
index b6d5fde..21a76af 100644
--- a/WebCore/inspector/front-end/TimelinePanel.js
+++ b/WebCore/inspector/front-end/TimelinePanel.js
@@ -79,8 +79,11 @@ WebInspector.TimelinePanel = function()
 
     this._records = [];
     this._sendRequestRecords = {};
+    this._timerRecords = {};
+
     this._calculator = new WebInspector.TimelineCalculator();
     this._boundariesAreValid = true;
+    this._scrollTop = 0;
 }
 
 WebInspector.TimelinePanel.prototype = {
@@ -150,6 +153,8 @@ WebInspector.TimelinePanel.prototype = {
                 this._lastRecord.category == formattedRecord.category &&
                 this._lastRecord.title == formattedRecord.title &&
                 this._lastRecord.details == formattedRecord.details &&
+                this._lastRecord.callerScriptName == formattedRecord.callerScriptName &&
+                this._lastRecord.callerScriptLine == formattedRecord.callerScriptLine &&
                 formattedRecord.startTime - this._lastRecord.endTime < 0.1) {
             this._lastRecord.endTime = formattedRecord.endTime;
             this._lastRecord.count++;
@@ -186,6 +191,7 @@ WebInspector.TimelinePanel.prototype = {
             this._recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: this.categories.loading };
             this._recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
             this._recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: this.categories.loading };
+            this._recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: this.categories.scripting };
         }
 
         var style = this._recordStyles[record.type];
@@ -200,7 +206,9 @@ WebInspector.TimelinePanel.prototype = {
         formattedRecord.count = 1;
         formattedRecord.type = record.type;
         formattedRecord.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : formattedRecord.startTime;
-        formattedRecord.record = record;
+        formattedRecord.originalRecordForTests = record;
+        formattedRecord.callerScriptName = record.callerScriptName;
+        formattedRecord.callerScriptLine = record.callerScriptLine;
 
         // Make resource receive record last since request was sent; make finish record last since response received.
         if (record.type === WebInspector.TimelineAgent.RecordType.ResourceSendRequest) {
@@ -210,12 +218,30 @@ WebInspector.TimelinePanel.prototype = {
             if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
                 sendRequestRecord._responseReceivedFormattedTime = formattedRecord.startTime;
                 formattedRecord.startTime = sendRequestRecord.startTime;
-                sendRequestRecord.details = this._getRecordDetails(record);
+                formattedRecord.details = this._getRecordDetails(sendRequestRecord);
+                formattedRecord.callerScriptName = sendRequestRecord.callerScriptName;
+                formattedRecord.callerScriptLine = sendRequestRecord.callerScriptLine;
             }
         } else if (record.type === WebInspector.TimelineAgent.RecordType.ResourceFinish) {
             var sendRequestRecord = this._sendRequestRecords[record.data.identifier];
-            if (sendRequestRecord) // False for main resource.
+            if (sendRequestRecord) {// False for main resource.
                 formattedRecord.startTime = sendRequestRecord._responseReceivedFormattedTime;
+                formattedRecord.callerScriptName = sendRequestRecord.callerScriptName;
+                formattedRecord.callerScriptLine = sendRequestRecord.callerScriptLine;
+            }
+        } else if (record.type === WebInspector.TimelineAgent.RecordType.TimerInstall) {
+            formattedRecord.timeout = record.data.timeout;
+            formattedRecord.singleShot = record.data.singleShot;
+            this._timerRecords[record.data.timerId] = formattedRecord;
+        } else if (record.type === WebInspector.TimelineAgent.RecordType.TimerFire ||
+                   record.type === WebInspector.TimelineAgent.RecordType.TimerRemove) {
+            var timerInstalledRecord = this._timerRecords[record.data.timerId];
+            if (timerInstalledRecord) {
+                formattedRecord.callSiteScriptName = timerInstalledRecord.callerScriptName;
+                formattedRecord.callSiteScriptLine = timerInstalledRecord.callerScriptLine;
+                formattedRecord.timeout = timerInstalledRecord.timeout;
+                formattedRecord.singleShot = timerInstalledRecord.singleShot;
+            }
         }
         formattedRecord.details = this._getRecordDetails(record);
 
@@ -225,6 +251,8 @@ WebInspector.TimelinePanel.prototype = {
     _getRecordDetails: function(record)
     {
         switch (record.type) {
+        case WebInspector.TimelineAgent.RecordType.FunctionCall:
+            return WebInspector.displayNameForURL(record.data.scriptName + ":" + record.data.scriptLine);
         case WebInspector.TimelineAgent.RecordType.EventDispatch:
             return record.data ? record.data.type : "";
         case WebInspector.TimelineAgent.RecordType.Paint:
@@ -264,6 +292,7 @@ WebInspector.TimelinePanel.prototype = {
     },
 
     resize: function() {
+        this._closeRecordDetails();
         this._scheduleRefresh();
     },
 
@@ -271,11 +300,23 @@ WebInspector.TimelinePanel.prototype = {
     {
         this._lastRecord = null;
         this._sendRequestRecords = {};
+        this._timerRecords = {};
         this._records = [];
         this._boundariesAreValid = false;
         this._overviewPane.reset();
         this._adjustScrollPosition(0);
         this._refresh();
+        this._closeRecordDetails();
+    },
+
+    _closeRecordDetails: function()
+    {
+        var details = WebInspector.TimelinePanel.recordDetails;
+        if (details) {
+            details.hide();
+            delete details;
+            WebInspector.TimelinePanel.recordDetails = null;
+        }
     },
 
     show: function()
@@ -288,6 +329,7 @@ WebInspector.TimelinePanel.prototype = {
 
     _onScroll: function(event)
     {
+        this._closeRecordDetails();
         var scrollTop = this._containerElement.scrollTop;
         var dividersTop = Math.max(0, scrollTop);
         this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop);
@@ -296,6 +338,7 @@ WebInspector.TimelinePanel.prototype = {
 
     _windowChanged: function()
     {
+        this._closeRecordDetails();
         this._scheduleRefresh();
     },
 
@@ -321,7 +364,7 @@ WebInspector.TimelinePanel.prototype = {
             clearTimeout(this._refreshTimeout);
             delete this._refreshTimeout;
         }
-      
+
         if (!this._boundariesAreValid)
             this._overviewPane.update(this._records);
         this._refreshRecords(!this._boundariesAreValid);
@@ -391,7 +434,7 @@ WebInspector.TimelinePanel.prototype = {
                 this._graphRowsElement.appendChild(graphRowElement);
             }
 
-            listRowElement.listRow.update(record, isEven);
+            listRowElement.listRow.update(record, isEven, this._calculator, visibleTop);
             graphRowElement.graphRow.update(record, isEven, this._calculator, width, expandOffset, i);
 
             listRowElement = listRowElement.nextSibling;
@@ -499,6 +542,7 @@ WebInspector.TimelineRecordListRow = function()
 {
     this.element = document.createElement("div");
     this.element.listRow = this;
+    this.element.style.cursor = "pointer";
     var iconElement = document.createElement("span");
     iconElement.className = "timeline-tree-icon";
     this.element.appendChild(iconElement);
@@ -520,11 +564,16 @@ WebInspector.TimelineRecordListRow = function()
     this.element.appendChild(separatorElement);
     this.element.appendChild(this._dataElement);
     this.element.appendChild(this._repeatCountElement);
+    this.element.addEventListener("click", this._onClick.bind(this));
 }
 
 WebInspector.TimelineRecordListRow.prototype = {
-    update: function(record, isEven)
+    update: function(record, isEven, calculator, offset)
     {
+        this._record = record;
+        this._calculator = calculator;
+        this._offset = offset;
+
         this.element.className = "timeline-tree-item timeline-category-" + record.category.name + (isEven ? " even" : "");
         this._typeElement.textContent = record.title;
 
@@ -542,13 +591,92 @@ WebInspector.TimelineRecordListRow.prototype = {
             this._repeatCountElement.textContent = "";
     },
 
+    _createCell: function(content, styleName)
+    {
+        var text = document.createElement("label");
+        text.appendChild(document.createTextNode(content));
+        var cell = document.createElement("td");
+        cell.className = "timeline-details";
+        if (styleName)
+             cell.className += " " + styleName;
+        cell.textContent = content;
+        return cell;
+    },
+
+    _createRow: function(title, content)
+    {
+        var row = document.createElement("tr");
+        row.appendChild(this._createCell(title, "timeline-details-row-title"));
+        row.appendChild(this._createCell(content, "timeline-details-row-data"));
+        return row;
+    },
+
+    _createLinkRow: function(title, content)
+    {
+        var row = document.createElement("tr");
+        row.appendChild(this._createCell(title, "timeline-details-row-title"));
+        var cell = document.createElement("td");
+        cell.appendChild(content);
+        row.appendChild(cell);
+        return row;
+    },
+
+    _generateBubbleContent: function()
+    {
+        var bubbleContentTable = document.createElement("table");
+        var titleCell = this._createCell(WebInspector.UIString("%s - Details", this._record.title), "timeline-details-title");
+        titleCell.colSpan = 2;
+        titleCell.appendChild(document.createElement("hr"));
+        var titleRow = document.createElement("tr");
+        titleRow.appendChild(titleCell);
+        bubbleContentTable.appendChild(titleRow);
+        var text = Number.secondsToString(this._record.endTime - this._record.startTime) + " (@" +
+            this._calculator.formatValue(this._record.startTime - this._calculator.minimumBoundary) + ")";
+        bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Duration"), text));
+
+        if (this._record.details) {
+            if ( this._record.type == WebInspector.TimelineAgent.RecordType.TimerInstall ||
+                 this._record.type == WebInspector.TimelineAgent.RecordType.TimerFire ||
+                 this._record.type == WebInspector.TimelineAgent.RecordType.TimerRemove) {
+                bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("TimerId"), this._record.data.timerId));
+                if (this._record.timeout) {
+                    bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Timeout"), this._record.timeout));
+                    bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Repeats"), !this._record.singleShot));
+                }
+                if (this._record.callSiteScriptLine) {
+                    var link = WebInspector.linkifyResourceAsNode(this._record.callSiteScriptName, "scripts", this._record.callSiteScriptLine);
+                    bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Call Site"), link));
+                }
+            } else if ( this._record.type == WebInspector.TimelineAgent.RecordType.FunctionCall ) {
+                var link = WebInspector.linkifyResourceAsNode(this._record.data.scriptName, "scripts", this._record.data.scriptLine);
+                bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Location"), link));
+            } else
+                bubbleContentTable.appendChild(this._createRow(WebInspector.UIString("Details"), this._record.details));
+        }
+
+        if (this._record.callerScriptName) {
+            var link = WebInspector.linkifyResourceAsNode(this._record.callerScriptName, "scripts", this._record.callerScriptLine);
+            bubbleContentTable.appendChild(this._createLinkRow(WebInspector.UIString("Caller"), link));
+        }
+        return bubbleContentTable;
+    },
+
+    _onClick: function(event)
+    {
+        if (this._record) {
+            var details = new WebInspector.Popover(this._generateBubbleContent());
+            details.hideWhenClicked();
+            details.show(this.element);
+            WebInspector.TimelinePanel.recordDetails = details;
+        }
+    },
+
     dispose: function()
     {
         this.element.parentElement.removeChild(this.element);
     }
 }
 
-
 WebInspector.TimelineRecordGraphRow = function(graphContainer, refreshCallback, rowHeight)
 {
     this.element = document.createElement("div");
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 606dfed..cf51bd8 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -3847,3 +3847,18 @@ ol.breakpoint-list {
     margin: -1px;
     background-color: rgb(255, 255, 194);
 }
+
+.timeline-details-row-title {
+    font-weight: bold;
+    text-align: right;
+    white-space: nowrap;
+}
+
+.timeline-details-row-data {
+    white-space: nowrap;
+}
+
+.timeline-details-title {
+    font-weight: bold;
+    white-space: nowrap;
+}
\ No newline at end of file
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 9b36cd3..6c903e8 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -1550,6 +1550,17 @@ WebInspector.linkifyURL = function(url, linkText, classes, isExternal, tooltipTe
     return WebInspector.linkifyURLAsNode(url, linkText, classes, isExternal, tooltipText).outerHTML;
 }
 
+WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, classes, tooltipText)
+{
+    var linkText = WebInspector.displayNameForURL(url);
+    if (lineNumber)
+        linkText += ":" + lineNumber;
+    var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
+    node.lineNumber = lineNumber;
+    node.preferredPanel = preferredPanel;
+    return node;
+}
+
 WebInspector.completeURL = function(baseURL, href)
 {
     var match = baseURL.match(WebInspector.URLRegExp);
diff --git a/WebKit/chromium/DEPS b/WebKit/chromium/DEPS
index 9c45b83..91601c7 100644
--- a/WebKit/chromium/DEPS
+++ b/WebKit/chromium/DEPS
@@ -43,7 +43,7 @@ vars = {
   'openvcdiff_rev': '28',
   'ots_rev': '26',
   'skia_rev': '490',
-  'v8_rev': '3781',
+  'v8_rev': '3963',
 
   # Windows:
   'cygwin_rev': '11984',

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list