initial import
[vuplus_webkit] / Source / WebCore / inspector / front-end / CallStackSidebarPane.js
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.CallStackSidebarPane = function(model)
27 {
28     WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
29     this._model = model;
30
31     this.bodyElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);
32 }
33
34 WebInspector.CallStackSidebarPane.prototype = {
35     update: function(callFrames, details)
36     {
37         this.bodyElement.removeChildren();
38
39         this.placards = [];
40
41         if (!callFrames) {
42             var infoElement = document.createElement("div");
43             infoElement.className = "info";
44             infoElement.textContent = WebInspector.UIString("Not Paused");
45             this.bodyElement.appendChild(infoElement);
46             return;
47         }
48
49         for (var i = 0; i < callFrames.length; ++i) {
50             var callFrame = callFrames[i];
51             var title = callFrame.functionName || WebInspector.UIString("(anonymous function)");
52
53             var subtitle;
54             if (!callFrame.isInternalScript)
55                 subtitle = WebInspector.displayNameForURL(callFrame.url);
56             else
57                 subtitle = WebInspector.UIString("(internal script)");
58
59             var placard = new WebInspector.Placard(title, subtitle);
60             placard.callFrame = callFrame;
61             placard.element.addEventListener("click", this._placardSelected.bind(this, placard), false);
62
63             function didGetSourceLine(placard, uiSourceCode, lineNumber)
64             {
65                 if (placard.subtitle)
66                     placard.subtitle += ":" + (lineNumber + 1);
67                 else
68                     placard.subtitle = WebInspector.UIString("line %d", lineNumber + 1);
69                 placard._text = WebInspector.UIString("%s() at %s", placard.title, placard.subtitle);
70             }
71             callFrame.sourceLine(didGetSourceLine.bind(this, placard));
72
73             this.placards.push(placard);
74             this.bodyElement.appendChild(placard.element);
75         }
76     },
77
78     set selectedCallFrame(x)
79     {
80         for (var i = 0; i < this.placards.length; ++i) {
81             var placard = this.placards[i];
82             placard.selected = (placard.callFrame === x);
83         }
84     },
85
86     _selectNextCallFrameOnStack: function()
87     {
88         var index = this._selectedCallFrameIndex();
89         if (index == -1)
90             return;
91         this._selectedPlacardByIndex(index + 1);
92     },
93
94     _selectPreviousCallFrameOnStack: function()
95     {
96         var index = this._selectedCallFrameIndex();
97         if (index == -1)
98             return;
99         this._selectedPlacardByIndex(index - 1);
100     },
101
102     _selectedPlacardByIndex: function(index)
103     {
104         if (index < 0 || index >= this.placards.length)
105             return;
106         this._placardSelected(this.placards[index])
107     },
108
109     _selectedCallFrameIndex: function()
110     {
111         if (!this._model.selectedCallFrame)
112             return -1;
113         for (var i = 0; i < this.placards.length; ++i) {
114             var placard = this.placards[i];
115             if (placard.callFrame === this._model.selectedCallFrame)
116                 return i;
117         }
118         return -1;
119     },
120
121     _placardSelected: function(placard, event)
122     {
123         this._model.selectedCallFrame = placard.callFrame;
124     },
125
126     _contextMenu: function(event)
127     {
128         if (!this.placards.length)
129             return;
130
131         var contextMenu = new WebInspector.ContextMenu();
132         contextMenu.appendItem(WebInspector.UIString("Copy Stack Trace"), this._copyStackTrace.bind(this));
133         contextMenu.show(event);
134     },
135
136     _copyStackTrace: function()
137     {
138         var text = "";
139         for (var i = 0; i < this.placards.length; ++i)
140             text += this.placards[i]._text;
141         InspectorFrontendHost.copyText(text);
142     },
143
144     registerShortcuts: function(section, registerShortcutDelegate)
145     {
146         var nextCallFrame = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period,
147             WebInspector.KeyboardShortcut.Modifiers.Ctrl);
148         registerShortcutDelegate(nextCallFrame.key, this._selectNextCallFrameOnStack.bind(this));
149
150         var prevCallFrame = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma,
151             WebInspector.KeyboardShortcut.Modifiers.Ctrl);
152         registerShortcutDelegate(prevCallFrame.key, this._selectPreviousCallFrameOnStack.bind(this));
153
154         section.addRelatedKeys([ nextCallFrame.name, prevCallFrame.name ], WebInspector.UIString("Next/previous call frame"));
155     },
156
157     setStatus: function(status)
158     {
159         var statusMessageElement = document.createElement("div");
160         statusMessageElement.className = "info";
161         if (typeof status === "string")
162             statusMessageElement.textContent = status;
163         else
164             statusMessageElement.appendChild(status);
165         this.bodyElement.appendChild(statusMessageElement);
166     }
167 }
168
169 WebInspector.CallStackSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;