23f365df73a495333cebe5fa64a6fad3ebb4b107
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / BreakpointActionView.js
1 /*
2  * Copyright (C) 2013 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.BreakpointActionView = function(action, delegate, omitFocus)
27 {
28     WebInspector.Object.call(this);
29
30     console.assert(action);
31     console.assert(delegate);
32     console.assert(DebuggerAgent.BreakpointActionType);
33
34     this._action = action;
35     this._delegate = delegate;
36
37     this._element = document.createElement("div");
38     this._element.className = "breakpoint-action-block";
39
40     var header = this._element.appendChild(document.createElement("div"));
41     header.className = "breakpoint-action-block-header";
42
43     var picker = header.appendChild(document.createElement("select"));
44     picker.addEventListener("change", this._pickerChanged.bind(this));
45
46     for (var key in WebInspector.BreakpointAction.Type) {
47         var type = WebInspector.BreakpointAction.Type[key];
48         var option = document.createElement("option");
49         option.textContent = WebInspector.BreakpointActionView.displayStringForType(type);
50         option.selected = this._action.type === type;
51         option.value = type;
52         picker.add(option);
53     }
54
55     var appendActionButton = header.appendChild(document.createElement("button"));
56     appendActionButton.className = "breakpoint-action-append-button";
57     appendActionButton.addEventListener("click", this._appendActionButtonClicked.bind(this));
58     appendActionButton.title = WebInspector.UIString("Add new breakpoint action after this action");
59
60     var removeActionButton = header.appendChild(document.createElement("button"));
61     removeActionButton.className = "breakpoint-action-remove-button";
62     removeActionButton.addEventListener("click", this._removeActionButtonClicked.bind(this));
63     removeActionButton.title = WebInspector.UIString("Remove this breakpoint action");
64
65     this._bodyElement = this._element.appendChild(document.createElement("div"));
66     this._bodyElement.className = "breakpoint-action-block-body";
67
68     this._updateBody(omitFocus);
69 };
70
71 WebInspector.BreakpointActionView.displayStringForType = function(type)
72 {
73     switch (type) {
74     case WebInspector.BreakpointAction.Type.Log:
75         return WebInspector.UIString("Log Message");
76     case WebInspector.BreakpointAction.Type.Evaluate:
77         return WebInspector.UIString("Evaluate JavaScript");
78     case WebInspector.BreakpointAction.Type.Sound:
79         return WebInspector.UIString("Play Sound");
80     default:
81         console.assert(false);
82         return "";
83     }
84 }
85
86 WebInspector.BreakpointActionView.prototype = {
87     constructor: WebInspector.BreakpointActionView,
88
89     // Public
90
91     get action()
92     {
93         return this._action;
94     },
95
96     get element()
97     {
98         return this._element;
99     },
100
101     // Private
102
103     _pickerChanged: function(event)
104     {
105         var newType = event.target.value;
106         this._action = this._action.breakpoint.recreateAction(newType, this._action);
107         this._updateBody();
108         this._delegate.breakpointActionViewResized(this);
109     },
110
111     _appendActionButtonClicked: function(event)
112     {
113         var newAction = this._action.breakpoint.createAction(WebInspector.Breakpoint.DefaultBreakpointActionType, this._action);
114         this._delegate.breakpointActionViewAppendActionView(this, newAction);
115     },
116
117     _removeActionButtonClicked: function(event)
118     {
119         this._action.breakpoint.removeAction(this._action);
120         this._delegate.breakpointActionViewRemoveActionView(this);
121     },
122
123     _updateBody: function(omitFocus)
124     {
125         this._bodyElement.removeChildren();
126
127         switch (this._action.type) {
128         case WebInspector.BreakpointAction.Type.Log:
129             this._bodyElement.hidden = false;
130
131             var input = this._bodyElement.appendChild(document.createElement("input"));
132             input.placeholder = WebInspector.UIString("Message");
133             input.addEventListener("change", this._logInputChanged.bind(this));
134             input.value = this._action.data || "";
135             if (!omitFocus)
136                 setTimeout(function() { input.focus(); }, 0);
137
138             break;
139
140         case WebInspector.BreakpointAction.Type.Evaluate:
141             this._bodyElement.hidden = false;
142
143             var editorElement = this._bodyElement.appendChild(document.createElement("div"));
144             editorElement.classList.add("breakpoint-action-eval-editor");
145             editorElement.classList.add(WebInspector.SyntaxHighlightedStyleClassName);
146
147             this._codeMirror = CodeMirror(editorElement, {
148                 lineWrapping: true,
149                 mode: "text/javascript",
150                 indentWithTabs: true,
151                 indentUnit: 4,
152                 matchBrackets: true,
153                 value: this._action.data || "",
154             });
155
156             this._codeMirror.on("viewportChange", this._codeMirrorViewportChanged.bind(this));
157             this._codeMirror.on("blur", this._codeMirrorBlurred.bind(this));
158
159             var completionController = new WebInspector.CodeMirrorCompletionController(this._codeMirror);
160             completionController.addExtendedCompletionProvider("javascript", WebInspector.javaScriptRuntimeCompletionProvider);
161
162             // CodeMirror needs a refresh after the popover displays, to layout, otherwise it doesn't appear.
163             setTimeout(function() {
164                 this._codeMirror.refresh();
165                 if (!omitFocus)
166                     this._codeMirror.focus();
167             }.bind(this), 0);
168
169             break;
170
171         case WebInspector.BreakpointAction.Type.Sound:
172             this._bodyElement.hidden = true;
173             break;
174
175         default:
176             console.assert(false);
177             this._bodyElement.hidden = true;
178             break;
179         }
180     },
181
182     _logInputChanged: function(event)
183     {
184         this._action.data = event.target.value;
185     },
186
187     _codeMirrorBlurred: function(event)
188     {
189         this._action.data = this._codeMirror.getValue();
190     },
191
192     _codeMirrorViewportChanged: function(event)
193     {
194         this._delegate.breakpointActionViewResized(this);
195     }
196 };
197
198 WebInspector.BreakpointActionView.prototype.__proto__ = WebInspector.Object.prototype;