Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived 15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission. 16 * from this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29
30 /** 29 /**
31 * @constructor
32 * @extends {WebInspector.VBox}
33 * @implements {WebInspector.Searchable} 30 * @implements {WebInspector.Searchable}
34 * @implements {WebInspector.TargetManager.Observer} 31 * @implements {WebInspector.TargetManager.Observer}
35 * @implements {WebInspector.ViewportControl.Provider} 32 * @implements {WebInspector.ViewportControl.Provider}
33 * @unrestricted
36 */ 34 */
37 WebInspector.ConsoleView = function() 35 WebInspector.ConsoleView = class extends WebInspector.VBox {
38 { 36 constructor() {
39 WebInspector.VBox.call(this); 37 super();
40 this.setMinimumSize(0, 35); 38 this.setMinimumSize(0, 35);
41 this.registerRequiredCSS("console/consoleView.css"); 39 this.registerRequiredCSS('console/consoleView.css');
42 40
43 this._searchableView = new WebInspector.SearchableView(this); 41 this._searchableView = new WebInspector.SearchableView(this);
44 this._searchableView.setPlaceholder(WebInspector.UIString("Find string in lo gs")); 42 this._searchableView.setPlaceholder(WebInspector.UIString('Find string in lo gs'));
45 this._searchableView.setMinimalSearchQuerySize(0); 43 this._searchableView.setMinimalSearchQuerySize(0);
46 this._searchableView.show(this.element); 44 this._searchableView.show(this.element);
47 45
48 this._contentsElement = this._searchableView.element; 46 this._contentsElement = this._searchableView.element;
49 this._contentsElement.classList.add("console-view"); 47 this._contentsElement.classList.add('console-view');
50 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */ 48 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
51 this._visibleViewMessages = []; 49 this._visibleViewMessages = [];
52 this._urlToMessageCount = {}; 50 this._urlToMessageCount = {};
53 this._hiddenByFilterCount = 0; 51 this._hiddenByFilterCount = 0;
54 52
55 /** 53 /**
56 * @type {!Array.<!WebInspector.ConsoleView.RegexMatchRange>} 54 * @type {!Array.<!WebInspector.ConsoleView.RegexMatchRange>}
57 */ 55 */
58 this._regexMatchRanges = []; 56 this._regexMatchRanges = [];
59 57
60 this._executionContextComboBox = new WebInspector.ToolbarComboBox(null, "con sole-context"); 58 this._executionContextComboBox = new WebInspector.ToolbarComboBox(null, 'con sole-context');
61 this._executionContextComboBox.setMaxWidth(200); 59 this._executionContextComboBox.setMaxWidth(200);
62 this._consoleContextSelector = new WebInspector.ConsoleContextSelector(this. _executionContextComboBox.selectElement()); 60 this._consoleContextSelector =
61 new WebInspector.ConsoleContextSelector(this._executionContextComboBox.s electElement());
63 62
64 this._filter = new WebInspector.ConsoleViewFilter(this); 63 this._filter = new WebInspector.ConsoleViewFilter(this);
65 this._filter.addEventListener(WebInspector.ConsoleViewFilter.Events.FilterCh anged, this._updateMessageList.bind(this)); 64 this._filter.addEventListener(
65 WebInspector.ConsoleViewFilter.Events.FilterChanged, this._updateMessage List.bind(this));
66 66
67 this._filterBar = new WebInspector.FilterBar("consoleView"); 67 this._filterBar = new WebInspector.FilterBar('consoleView');
68 68
69 this._preserveLogCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UI String("Preserve log"), WebInspector.UIString("Do not clear log on page reload / navigation"), WebInspector.moduleSetting("preserveConsoleLog")); 69 this._preserveLogCheckbox = new WebInspector.ToolbarCheckbox(
70 this._progressToolbarItem = new WebInspector.ToolbarItem(createElement("div" )); 70 WebInspector.UIString('Preserve log'), WebInspector.UIString('Do not cle ar log on page reload / navigation'),
71 WebInspector.moduleSetting('preserveConsoleLog'));
72 this._progressToolbarItem = new WebInspector.ToolbarItem(createElement('div' ));
71 73
72 var toolbar = new WebInspector.Toolbar("", this._contentsElement); 74 var toolbar = new WebInspector.Toolbar('', this._contentsElement);
73 toolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(/** @type {!WebInspector.Action }*/ (WebInspector.actionRegistry.action("console.clear"))) ); 75 toolbar.appendToolbarItem(WebInspector.Toolbar.createActionButton(
76 /** @type {!WebInspector.Action }*/ (WebInspector.actionRegistry.action( 'console.clear'))));
74 toolbar.appendToolbarItem(this._filterBar.filterButton()); 77 toolbar.appendToolbarItem(this._filterBar.filterButton());
75 toolbar.appendToolbarItem(this._executionContextComboBox); 78 toolbar.appendToolbarItem(this._executionContextComboBox);
76 toolbar.appendToolbarItem(this._preserveLogCheckbox); 79 toolbar.appendToolbarItem(this._preserveLogCheckbox);
77 toolbar.appendToolbarItem(this._progressToolbarItem); 80 toolbar.appendToolbarItem(this._progressToolbarItem);
78 81
79 this._filterBar.show(this._contentsElement); 82 this._filterBar.show(this._contentsElement);
80 this._filter.addFilters(this._filterBar); 83 this._filter.addFilters(this._filterBar);
81 84
82 this._viewport = new WebInspector.ViewportControl(this); 85 this._viewport = new WebInspector.ViewportControl(this);
83 this._viewport.setStickToBottom(true); 86 this._viewport.setStickToBottom(true);
84 this._viewport.contentElement().classList.add("console-group", "console-grou p-messages"); 87 this._viewport.contentElement().classList.add('console-group', 'console-grou p-messages');
85 this._contentsElement.appendChild(this._viewport.element); 88 this._contentsElement.appendChild(this._viewport.element);
86 this._messagesElement = this._viewport.element; 89 this._messagesElement = this._viewport.element;
87 this._messagesElement.id = "console-messages"; 90 this._messagesElement.id = 'console-messages';
88 this._messagesElement.classList.add("monospace"); 91 this._messagesElement.classList.add('monospace');
89 this._messagesElement.addEventListener("click", this._messagesClicked.bind(t his), true); 92 this._messagesElement.addEventListener('click', this._messagesClicked.bind(t his), true);
90 93
91 this._viewportThrottler = new WebInspector.Throttler(50); 94 this._viewportThrottler = new WebInspector.Throttler(50);
92 95
93 this._filterStatusMessageElement = createElementWithClass("div", "console-me ssage"); 96 this._filterStatusMessageElement = createElementWithClass('div', 'console-me ssage');
94 this._messagesElement.insertBefore(this._filterStatusMessageElement, this._m essagesElement.firstChild); 97 this._messagesElement.insertBefore(this._filterStatusMessageElement, this._m essagesElement.firstChild);
95 this._filterStatusTextElement = this._filterStatusMessageElement.createChild ("span", "console-info"); 98 this._filterStatusTextElement = this._filterStatusMessageElement.createChild ('span', 'console-info');
96 this._filterStatusMessageElement.createTextChild(" "); 99 this._filterStatusMessageElement.createTextChild(' ');
97 var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "console-info link"); 100 var resetFiltersLink = this._filterStatusMessageElement.createChild('span', 'console-info link');
98 resetFiltersLink.textContent = WebInspector.UIString("Show all messages."); 101 resetFiltersLink.textContent = WebInspector.UIString('Show all messages.');
99 resetFiltersLink.addEventListener("click", this._filter.reset.bind(this._fil ter), true); 102 resetFiltersLink.addEventListener('click', this._filter.reset.bind(this._fil ter), true);
100 103
101 this._topGroup = WebInspector.ConsoleGroup.createTopGroup(); 104 this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
102 this._currentGroup = this._topGroup; 105 this._currentGroup = this._topGroup;
103 106
104 this._promptElement = this._messagesElement.createChild("div", "source-code" ); 107 this._promptElement = this._messagesElement.createChild('div', 'source-code' );
105 this._promptElement.id = "console-prompt"; 108 this._promptElement.id = 'console-prompt';
106 this._promptElement.addEventListener("input", this._promptInput.bind(this), false); 109 this._promptElement.addEventListener('input', this._promptInput.bind(this), false);
107 110
108 // FIXME: This is a workaround for the selection machinery bug. See crbug.co m/410899 111 // FIXME: This is a workaround for the selection machinery bug. See crbug.co m/410899
109 var selectAllFixer = this._messagesElement.createChild("div", "console-view- fix-select-all"); 112 var selectAllFixer = this._messagesElement.createChild('div', 'console-view- fix-select-all');
110 selectAllFixer.textContent = "."; 113 selectAllFixer.textContent = '.';
111 114
112 this._showAllMessagesCheckbox = new WebInspector.ToolbarCheckbox(WebInspecto r.UIString("Show all messages")); 115 this._showAllMessagesCheckbox = new WebInspector.ToolbarCheckbox(WebInspecto r.UIString('Show all messages'));
113 this._showAllMessagesCheckbox.inputElement.checked = true; 116 this._showAllMessagesCheckbox.inputElement.checked = true;
114 this._showAllMessagesCheckbox.inputElement.addEventListener("change", this._ updateMessageList.bind(this), false); 117 this._showAllMessagesCheckbox.inputElement.addEventListener('change', this._ updateMessageList.bind(this), false);
115 118
116 this._showAllMessagesCheckbox.element.classList.add("hidden"); 119 this._showAllMessagesCheckbox.element.classList.add('hidden');
117 120
118 toolbar.appendToolbarItem(this._showAllMessagesCheckbox); 121 toolbar.appendToolbarItem(this._showAllMessagesCheckbox);
119 122
120 this._registerShortcuts(); 123 this._registerShortcuts();
121 124
122 this._messagesElement.addEventListener("contextmenu", this._handleContextMen uEvent.bind(this), false); 125 this._messagesElement.addEventListener('contextmenu', this._handleContextMen uEvent.bind(this), false);
123 WebInspector.moduleSetting("monitoringXHREnabled").addChangeListener(this._m onitoringXHREnabledSettingChanged, this); 126 WebInspector.moduleSetting('monitoringXHREnabled')
127 .addChangeListener(this._monitoringXHREnabledSettingChanged, this);
124 128
125 this._linkifier = new WebInspector.Linkifier(); 129 this._linkifier = new WebInspector.Linkifier();
126 130
127 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */ 131 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
128 this._consoleMessages = []; 132 this._consoleMessages = [];
129 this._viewMessageSymbol = Symbol("viewMessage"); 133 this._viewMessageSymbol = Symbol('viewMessage');
130 134
131 this._consoleHistorySetting = WebInspector.settings.createLocalSetting("cons oleHistory", []); 135 this._consoleHistorySetting = WebInspector.settings.createLocalSetting('cons oleHistory', []);
132 136
133 this._prompt = new WebInspector.ConsolePrompt(); 137 this._prompt = new WebInspector.ConsolePrompt();
134 this._prompt.show(this._promptElement); 138 this._prompt.show(this._promptElement);
135 this._prompt.element.addEventListener("keydown", this._promptKeyDown.bind(th is), true); 139 this._prompt.element.addEventListener('keydown', this._promptKeyDown.bind(th is), true);
136 140
137 this._consoleHistoryAutocompleteSetting = WebInspector.moduleSetting("consol eHistoryAutocomplete"); 141 this._consoleHistoryAutocompleteSetting = WebInspector.moduleSetting('consol eHistoryAutocomplete');
138 this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHisto ryAutocompleteChanged, this); 142 this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHisto ryAutocompleteChanged, this);
139 143
140 var historyData = this._consoleHistorySetting.get(); 144 var historyData = this._consoleHistorySetting.get();
141 this._prompt.history().setHistoryData(historyData); 145 this._prompt.history().setHistoryData(historyData);
142 this._consoleHistoryAutocompleteChanged(); 146 this._consoleHistoryAutocompleteChanged();
143 147
144 this._updateFilterStatus(); 148 this._updateFilterStatus();
145 WebInspector.moduleSetting("consoleTimestampsEnabled").addChangeListener(thi s._consoleTimestampsSettingChanged, this); 149 WebInspector.moduleSetting('consoleTimestampsEnabled')
150 .addChangeListener(this._consoleTimestampsSettingChanged, this);
146 151
147 this._registerWithMessageSink(); 152 this._registerWithMessageSink();
148 WebInspector.targetManager.observeTargets(this); 153 WebInspector.targetManager.observeTargets(this);
149 154
150 this._initConsoleMessages(); 155 this._initConsoleMessages();
151 156
152 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this); 157 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this);
153 158
154 this._messagesElement.addEventListener("mousedown", this._updateStickToBotto mOnMouseDown.bind(this), false); 159 this._messagesElement.addEventListener('mousedown', this._updateStickToBotto mOnMouseDown.bind(this), false);
155 this._messagesElement.addEventListener("mouseup", this._updateStickToBottomO nMouseUp.bind(this), false); 160 this._messagesElement.addEventListener('mouseup', this._updateStickToBottomO nMouseUp.bind(this), false);
156 this._messagesElement.addEventListener("mouseleave", this._updateStickToBott omOnMouseUp.bind(this), false); 161 this._messagesElement.addEventListener('mouseleave', this._updateStickToBott omOnMouseUp.bind(this), false);
157 this._messagesElement.addEventListener("wheel", this._updateStickToBottomOnW heel.bind(this), false); 162 this._messagesElement.addEventListener('wheel', this._updateStickToBottomOnW heel.bind(this), false);
158 }; 163 }
159 164
160 WebInspector.ConsoleView.persistedHistorySize = 300; 165 /**
161 166 * @return {!WebInspector.ConsoleView}
162 WebInspector.ConsoleView.prototype = { 167 */
163 /** 168 static instance() {
164 * @return {!WebInspector.SearchableView} 169 if (!WebInspector.ConsoleView._instance)
165 */ 170 WebInspector.ConsoleView._instance = new WebInspector.ConsoleView();
166 searchableView: function() 171 return WebInspector.ConsoleView._instance;
167 { 172 }
168 return this._searchableView; 173
169 }, 174 static clearConsole() {
170 175 for (var target of WebInspector.targetManager.targets()) {
171 _clearHistory: function() 176 target.runtimeModel.discardConsoleEntries();
172 { 177 target.consoleModel.requestClearMessages();
173 this._consoleHistorySetting.set([]); 178 }
174 this._prompt.history().setHistoryData([]); 179 }
175 }, 180
176 181 /**
177 _consoleHistoryAutocompleteChanged: function() 182 * @return {!WebInspector.SearchableView}
178 { 183 */
179 this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocomple teSetting.get()); 184 searchableView() {
180 }, 185 return this._searchableView;
181 186 }
182 _initConsoleMessages: function() 187
183 { 188 _clearHistory() {
184 var mainTarget = WebInspector.targetManager.mainTarget(); 189 this._consoleHistorySetting.set([]);
185 var resourceTreeModel = mainTarget && WebInspector.ResourceTreeModel.fro mTarget(mainTarget); 190 this._prompt.history().setHistoryData([]);
186 var resourcesLoaded = !resourceTreeModel || resourceTreeModel.cachedReso urcesLoaded(); 191 }
187 if (!mainTarget || !resourcesLoaded) { 192
188 WebInspector.targetManager.addModelListener(WebInspector.ResourceTre eModel, WebInspector.ResourceTreeModel.Events.CachedResourcesLoaded, this._onRes ourceTreeModelLoaded, this); 193 _consoleHistoryAutocompleteChanged() {
189 return; 194 this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSe tting.get());
190 } 195 }
191 this._fetchMultitargetMessages(); 196
192 }, 197 _initConsoleMessages() {
198 var mainTarget = WebInspector.targetManager.mainTarget();
199 var resourceTreeModel = mainTarget && WebInspector.ResourceTreeModel.fromTar get(mainTarget);
200 var resourcesLoaded = !resourceTreeModel || resourceTreeModel.cachedResource sLoaded();
201 if (!mainTarget || !resourcesLoaded) {
202 WebInspector.targetManager.addModelListener(
203 WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.Events. CachedResourcesLoaded,
204 this._onResourceTreeModelLoaded, this);
205 return;
206 }
207 this._fetchMultitargetMessages();
208 }
209
210 /**
211 * @param {!WebInspector.Event} event
212 */
213 _onResourceTreeModelLoaded(event) {
214 var resourceTreeModel = event.target;
215 if (resourceTreeModel.target() !== WebInspector.targetManager.mainTarget())
216 return;
217 WebInspector.targetManager.removeModelListener(
218 WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.Events.Ca chedResourcesLoaded,
219 this._onResourceTreeModelLoaded, this);
220 this._fetchMultitargetMessages();
221 }
222
223 _fetchMultitargetMessages() {
224 WebInspector.multitargetConsoleModel.addEventListener(
225 WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, t his);
226 WebInspector.multitargetConsoleModel.addEventListener(
227 WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdd ed, this);
228 WebInspector.multitargetConsoleModel.addEventListener(
229 WebInspector.ConsoleModel.Events.MessageUpdated, this._onConsoleMessageU pdated, this);
230 WebInspector.multitargetConsoleModel.addEventListener(
231 WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluate d, this);
232 WebInspector.multitargetConsoleModel.messages().forEach(this._addConsoleMess age, this);
233 this._viewport.invalidate();
234 }
235
236 /**
237 * @override
238 * @return {number}
239 */
240 itemCount() {
241 return this._visibleViewMessages.length;
242 }
243
244 /**
245 * @override
246 * @param {number} index
247 * @return {?WebInspector.ViewportElement}
248 */
249 itemElement(index) {
250 return this._visibleViewMessages[index];
251 }
252
253 /**
254 * @override
255 * @param {number} index
256 * @return {number}
257 */
258 fastHeight(index) {
259 return this._visibleViewMessages[index].fastHeight();
260 }
261
262 /**
263 * @override
264 * @return {number}
265 */
266 minimumRowHeight() {
267 return 16;
268 }
269
270 /**
271 * @override
272 * @param {!WebInspector.Target} target
273 */
274 targetAdded(target) {
275 this._viewport.invalidate();
276 this._updateAllMessagesCheckbox();
277 }
278
279 /**
280 * @override
281 * @param {!WebInspector.Target} target
282 */
283 targetRemoved(target) {
284 this._updateAllMessagesCheckbox();
285 }
286
287 _updateAllMessagesCheckbox() {
288 var hasMultipleCotexts = WebInspector.targetManager.targets(WebInspector.Tar get.Capability.JS).length > 1;
289 this._showAllMessagesCheckbox.element.classList.toggle('hidden', !hasMultipl eCotexts);
290 }
291
292 _registerWithMessageSink() {
293 WebInspector.console.messages().forEach(this._addSinkMessage, this);
294 WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdd ed, messageAdded, this);
193 295
194 /** 296 /**
195 * @param {!WebInspector.Event} event 297 * @param {!WebInspector.Event} event
298 * @this {WebInspector.ConsoleView}
196 */ 299 */
197 _onResourceTreeModelLoaded: function(event) 300 function messageAdded(event) {
198 { 301 this._addSinkMessage(/** @type {!WebInspector.Console.Message} */ (event.d ata));
199 var resourceTreeModel = event.target; 302 }
200 if (resourceTreeModel.target() !== WebInspector.targetManager.mainTarget ()) 303 }
201 return; 304
202 WebInspector.targetManager.removeModelListener(WebInspector.ResourceTree Model, WebInspector.ResourceTreeModel.Events.CachedResourcesLoaded, this._onReso urceTreeModelLoaded, this); 305 /**
203 this._fetchMultitargetMessages(); 306 * @param {!WebInspector.Console.Message} message
204 }, 307 */
205 308 _addSinkMessage(message) {
206 _fetchMultitargetMessages: function() 309 var level = WebInspector.ConsoleMessage.MessageLevel.Debug;
207 { 310 switch (message.level) {
208 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso leModel.Events.ConsoleCleared, this._consoleCleared, this); 311 case WebInspector.Console.MessageLevel.Error:
209 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso leModel.Events.MessageAdded, this._onConsoleMessageAdded, this); 312 level = WebInspector.ConsoleMessage.MessageLevel.Error;
210 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso leModel.Events.MessageUpdated, this._onConsoleMessageUpdated, this); 313 break;
211 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso leModel.Events.CommandEvaluated, this._commandEvaluated, this); 314 case WebInspector.Console.MessageLevel.Warning:
212 WebInspector.multitargetConsoleModel.messages().forEach(this._addConsole Message, this); 315 level = WebInspector.ConsoleMessage.MessageLevel.Warning;
316 break;
317 }
318
319 var consoleMessage = new WebInspector.ConsoleMessage(
320 null, WebInspector.ConsoleMessage.MessageSource.Other, level, message.te xt, undefined, undefined, undefined,
321 undefined, undefined, undefined, undefined, message.timestamp);
322 this._addConsoleMessage(consoleMessage);
323 }
324
325 /**
326 * @param {!WebInspector.Event} event
327 */
328 _consoleTimestampsSettingChanged(event) {
329 var enabled = /** @type {boolean} */ (event.data);
330 this._updateMessageList();
331 this._consoleMessages.forEach(function(viewMessage) {
332 viewMessage.updateTimestamp(enabled);
333 });
334 }
335
336 _executionContextChanged() {
337 this._prompt.clearAutocomplete();
338 if (!this._showAllMessagesCheckbox.checked())
339 this._updateMessageList();
340 }
341
342 /**
343 * @override
344 */
345 willHide() {
346 this._hidePromptSuggestBox();
347 }
348
349 /**
350 * @override
351 */
352 wasShown() {
353 this._viewport.refresh();
354 }
355
356 /**
357 * @override
358 */
359 focus() {
360 if (this._prompt.hasFocus())
361 return;
362 // Set caret position before setting focus in order to avoid scrolling
363 // by focus().
364 this._prompt.moveCaretToEndOfPrompt();
365 this._prompt.focus();
366 }
367
368 /**
369 * @override
370 */
371 restoreScrollPositions() {
372 if (this._viewport.stickToBottom())
373 this._immediatelyScrollToBottom();
374 else
375 super.restoreScrollPositions();
376 }
377
378 /**
379 * @override
380 */
381 onResize() {
382 this._scheduleViewportRefresh();
383 this._hidePromptSuggestBox();
384 if (this._viewport.stickToBottom())
385 this._immediatelyScrollToBottom();
386 for (var i = 0; i < this._visibleViewMessages.length; ++i)
387 this._visibleViewMessages[i].onResize();
388 }
389
390 _hidePromptSuggestBox() {
391 this._prompt.clearAutocomplete();
392 }
393
394 _scheduleViewportRefresh() {
395 /**
396 * @this {WebInspector.ConsoleView}
397 * @return {!Promise.<undefined>}
398 */
399 function invalidateViewport() {
400 if (this._muteViewportUpdates) {
401 this._maybeDirtyWhileMuted = true;
402 return Promise.resolve();
403 }
404 if (this._needsFullUpdate) {
405 this._updateMessageList();
406 delete this._needsFullUpdate;
407 } else {
213 this._viewport.invalidate(); 408 this._viewport.invalidate();
214 }, 409 }
215 410 return Promise.resolve();
411 }
412 if (this._muteViewportUpdates) {
413 this._maybeDirtyWhileMuted = true;
414 this._scheduleViewportRefreshForTest(true);
415 return;
416 } else {
417 this._scheduleViewportRefreshForTest(false);
418 }
419 this._viewportThrottler.schedule(invalidateViewport.bind(this));
420 }
421
422 /**
423 * @param {boolean} muted
424 */
425 _scheduleViewportRefreshForTest(muted) {
426 // This functions is sniffed in tests.
427 }
428
429 _immediatelyScrollToBottom() {
430 // This will scroll viewport and trigger its refresh.
431 this._viewport.setStickToBottom(true);
432 this._promptElement.scrollIntoView(true);
433 }
434
435 _updateFilterStatus() {
436 this._filterStatusTextElement.textContent = WebInspector.UIString(
437 this._hiddenByFilterCount === 1 ? '%d message is hidden by filters.' : ' %d messages are hidden by filters.',
438 this._hiddenByFilterCount);
439 this._filterStatusMessageElement.style.display = this._hiddenByFilterCount ? '' : 'none';
440 }
441
442 /**
443 * @param {!WebInspector.Event} event
444 */
445 _onConsoleMessageAdded(event) {
446 var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
447 this._addConsoleMessage(message);
448 }
449
450 /**
451 * @param {!WebInspector.ConsoleMessage} message
452 */
453 _addConsoleMessage(message) {
216 /** 454 /**
217 * @override 455 * @param {!WebInspector.ConsoleViewMessage} viewMessage1
456 * @param {!WebInspector.ConsoleViewMessage} viewMessage2
218 * @return {number} 457 * @return {number}
219 */ 458 */
220 itemCount: function() 459 function compareTimestamps(viewMessage1, viewMessage2) {
221 { 460 return WebInspector.ConsoleMessage.timestampComparator(
222 return this._visibleViewMessages.length; 461 viewMessage1.consoleMessage(), viewMessage2.consoleMessage());
223 }, 462 }
463
464 if (message.type === WebInspector.ConsoleMessage.MessageType.Command ||
465 message.type === WebInspector.ConsoleMessage.MessageType.Result)
466 message.timestamp =
467 this._consoleMessages.length ? this._consoleMessages.peekLast().consol eMessage().timestamp : 0;
468 var viewMessage = this._createViewMessage(message);
469 message[this._viewMessageSymbol] = viewMessage;
470 var insertAt = this._consoleMessages.upperBound(viewMessage, compareTimestam ps);
471 var insertedInMiddle = insertAt < this._consoleMessages.length;
472 this._consoleMessages.splice(insertAt, 0, viewMessage);
473
474 if (this._urlToMessageCount[message.url])
475 ++this._urlToMessageCount[message.url];
476 else
477 this._urlToMessageCount[message.url] = 1;
478
479 if (!insertedInMiddle) {
480 this._appendMessageToEnd(viewMessage);
481 this._updateFilterStatus();
482 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.lengt h);
483 } else {
484 this._needsFullUpdate = true;
485 }
486
487 this._scheduleViewportRefresh();
488 this._consoleMessageAddedForTest(viewMessage);
489 }
490
491 /**
492 * @param {!WebInspector.Event} event
493 */
494 _onConsoleMessageUpdated(event) {
495 var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
496 var viewMessage = message[this._viewMessageSymbol];
497 if (viewMessage) {
498 viewMessage.updateMessageElement();
499 this._updateMessageList();
500 }
501 }
502
503 /**
504 * @param {!WebInspector.ConsoleViewMessage} viewMessage
505 */
506 _consoleMessageAddedForTest(viewMessage) {
507 }
508
509 /**
510 * @param {!WebInspector.ConsoleViewMessage} viewMessage
511 */
512 _appendMessageToEnd(viewMessage) {
513 if (!this._filter.shouldBeVisible(viewMessage)) {
514 this._hiddenByFilterCount++;
515 return;
516 }
517
518 if (this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.peekL ast()))
519 return;
520
521 var lastMessage = this._visibleViewMessages.peekLast();
522 if (viewMessage.consoleMessage().type === WebInspector.ConsoleMessage.Messag eType.EndGroup) {
523 if (lastMessage && !this._currentGroup.messagesHidden())
524 lastMessage.incrementCloseGroupDecorationCount();
525 this._currentGroup = this._currentGroup.parentGroup();
526 return;
527 }
528 if (!this._currentGroup.messagesHidden()) {
529 var originatingMessage = viewMessage.consoleMessage().originatingMessage() ;
530 if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage)
531 lastMessage.toMessageElement().classList.add('console-adjacent-user-comm and-result');
532
533 this._visibleViewMessages.push(viewMessage);
534 this._searchMessage(this._visibleViewMessages.length - 1);
535 }
536
537 if (viewMessage.consoleMessage().isGroupStartMessage())
538 this._currentGroup = new WebInspector.ConsoleGroup(this._currentGroup, vie wMessage);
539
540 this._messageAppendedForTests();
541 }
542
543 _messageAppendedForTests() {
544 // This method is sniffed in tests.
545 }
546
547 /**
548 * @param {!WebInspector.ConsoleMessage} message
549 * @return {!WebInspector.ConsoleViewMessage}
550 */
551 _createViewMessage(message) {
552 var nestingLevel = this._currentGroup.nestingLevel();
553 switch (message.type) {
554 case WebInspector.ConsoleMessage.MessageType.Command:
555 return new WebInspector.ConsoleCommand(message, this._linkifier, nesting Level);
556 case WebInspector.ConsoleMessage.MessageType.Result:
557 return new WebInspector.ConsoleCommandResult(message, this._linkifier, n estingLevel);
558 case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
559 case WebInspector.ConsoleMessage.MessageType.StartGroup:
560 return new WebInspector.ConsoleGroupViewMessage(message, this._linkifier , nestingLevel);
561 default:
562 return new WebInspector.ConsoleViewMessage(message, this._linkifier, nes tingLevel);
563 }
564 }
565
566 _consoleCleared() {
567 this._currentMatchRangeIndex = -1;
568 this._consoleMessages = [];
569 this._updateMessageList();
570 this._hidePromptSuggestBox();
571 this._viewport.setStickToBottom(true);
572 this._linkifier.reset();
573 }
574
575 _handleContextMenuEvent(event) {
576 if (event.target.enclosingNodeOrSelfWithNodeName('a'))
577 return;
578
579 var contextMenu = new WebInspector.ContextMenu(event);
580 if (event.target.isSelfOrDescendant(this._promptElement)) {
581 contextMenu.show();
582 return;
583 }
584
585 function monitoringXHRItemAction() {
586 WebInspector.moduleSetting('monitoringXHREnabled').set(!WebInspector.modul eSetting('monitoringXHREnabled').get());
587 }
588 contextMenu.appendCheckboxItem(
589 WebInspector.UIString('Log XMLHttpRequests'), monitoringXHRItemAction,
590 WebInspector.moduleSetting('monitoringXHREnabled').get());
591
592 var sourceElement = event.target.enclosingNodeOrSelfWithClass('console-messa ge-wrapper');
593 var consoleMessage = sourceElement ? sourceElement.message.consoleMessage() : null;
594
595 var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString('Fil ter'));
596
597 if (consoleMessage && consoleMessage.url) {
598 var menuTitle = WebInspector.UIString.capitalize(
599 'Hide ^messages from %s', new WebInspector.ParsedURL(consoleMessage.ur l).displayName);
600 filterSubMenu.appendItem(menuTitle, this._filter.addMessageURLFilter.bind( this._filter, consoleMessage.url));
601 }
602
603 filterSubMenu.appendSeparator();
604 var unhideAll = filterSubMenu.appendItem(
605 WebInspector.UIString.capitalize('Unhide ^all'), this._filter.removeMess ageURLFilter.bind(this._filter));
606 filterSubMenu.appendSeparator();
607
608 var hasFilters = false;
609
610 for (var url in this._filter.messageURLFilters) {
611 filterSubMenu.appendCheckboxItem(
612 String.sprintf('%s (%d)', new WebInspector.ParsedURL(url).displayName, this._urlToMessageCount[url]),
613 this._filter.removeMessageURLFilter.bind(this._filter, url), true);
614 hasFilters = true;
615 }
616
617 filterSubMenu.setEnabled(hasFilters || (consoleMessage && consoleMessage.url ));
618 unhideAll.setEnabled(hasFilters);
619
620 contextMenu.appendSeparator();
621 contextMenu.appendAction('console.clear');
622 contextMenu.appendAction('console.clear.history');
623 contextMenu.appendItem(WebInspector.UIString('Save as...'), this._saveConsol e.bind(this));
624
625 var request = consoleMessage ? consoleMessage.request : null;
626 if (request && request.resourceType() === WebInspector.resourceTypes.XHR) {
627 contextMenu.appendSeparator();
628 contextMenu.appendItem(WebInspector.UIString('Replay XHR'), request.replay XHR.bind(request));
629 }
630
631 contextMenu.show();
632 }
633
634 _saveConsole() {
635 var url = WebInspector.targetManager.mainTarget().inspectedURL();
636 var parsedURL = url.asParsedURL();
637 var filename = String.sprintf('%s-%d.log', parsedURL ? parsedURL.host : 'con sole', Date.now());
638 var stream = new WebInspector.FileOutputStream();
639
640 var progressIndicator = new WebInspector.ProgressIndicator();
641 progressIndicator.setTitle(WebInspector.UIString('Writing file…'));
642 progressIndicator.setTotalWork(this.itemCount());
643
644 /** @const */
645 var chunkSize = 350;
646 var messageIndex = 0;
647
648 stream.open(filename, openCallback.bind(this));
224 649
225 /** 650 /**
226 * @override 651 * @param {boolean} accepted
227 * @param {number} index 652 * @this {WebInspector.ConsoleView}
228 * @return {?WebInspector.ViewportElement}
229 */ 653 */
230 itemElement: function(index) 654 function openCallback(accepted) {
231 { 655 if (!accepted)
232 return this._visibleViewMessages[index]; 656 return;
233 }, 657 this._progressToolbarItem.element.appendChild(progressIndicator.element);
658 writeNextChunk.call(this, stream);
659 }
234 660
235 /** 661 /**
236 * @override 662 * @param {!WebInspector.OutputStream} stream
237 * @param {number} index 663 * @param {string=} error
238 * @return {number} 664 * @this {WebInspector.ConsoleView}
239 */ 665 */
240 fastHeight: function(index) 666 function writeNextChunk(stream, error) {
241 { 667 if (messageIndex >= this.itemCount() || error) {
242 return this._visibleViewMessages[index].fastHeight(); 668 stream.close();
243 }, 669 progressIndicator.done();
670 return;
671 }
672 var lines = [];
673 for (var i = 0; i < chunkSize && i + messageIndex < this.itemCount(); ++i) {
674 var message = this.itemElement(messageIndex + i);
675 var messageContent = message.contentElement().deepTextContent();
676 for (var j = 0; j < message.repeatCount(); ++j)
677 lines.push(messageContent);
678 }
679 messageIndex += i;
680 stream.write(lines.join('\n') + '\n', writeNextChunk.bind(this));
681 progressIndicator.setWorked(messageIndex);
682 }
683 }
684
685 /**
686 * @param {!WebInspector.ConsoleViewMessage} lastMessage
687 * @param {?WebInspector.ConsoleViewMessage=} viewMessage
688 * @return {boolean}
689 */
690 _tryToCollapseMessages(lastMessage, viewMessage) {
691 if (!WebInspector.moduleSetting('consoleTimestampsEnabled').get() && viewMes sage &&
692 !lastMessage.consoleMessage().isGroupMessage() &&
693 lastMessage.consoleMessage().isEqual(viewMessage.consoleMessage())) {
694 viewMessage.incrementRepeatCount();
695 return true;
696 }
697
698 return false;
699 }
700
701 _updateMessageList() {
702 this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
703 this._currentGroup = this._topGroup;
704 this._regexMatchRanges = [];
705 this._hiddenByFilterCount = 0;
706 for (var i = 0; i < this._visibleViewMessages.length; ++i) {
707 this._visibleViewMessages[i].resetCloseGroupDecorationCount();
708 this._visibleViewMessages[i].resetIncrementRepeatCount();
709 }
710 this._visibleViewMessages = [];
711 for (var i = 0; i < this._consoleMessages.length; ++i)
712 this._appendMessageToEnd(this._consoleMessages[i]);
713 this._updateFilterStatus();
714 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length) ;
715 this._viewport.invalidate();
716 }
717
718 /**
719 * @param {!WebInspector.Event} event
720 */
721 _monitoringXHREnabledSettingChanged(event) {
722 var enabled = /** @type {boolean} */ (event.data);
723 WebInspector.targetManager.targets().forEach(function(target) {
724 target.networkAgent().setMonitoringXHREnabled(enabled);
725 });
726 }
727
728 /**
729 * @param {!Event} event
730 */
731 _messagesClicked(event) {
732 var targetElement = event.deepElementFromPoint();
733 if (!targetElement || targetElement.isComponentSelectionCollapsed())
734 this.focus();
735 var groupMessage = event.target.enclosingNodeOrSelfWithClass('console-group- title');
736 if (!groupMessage)
737 return;
738 var consoleGroupViewMessage = groupMessage.parentElement.message;
739 consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed());
740 this._updateMessageList();
741 }
742
743 _registerShortcuts() {
744 this._shortcuts = {};
745
746 var shortcut = WebInspector.KeyboardShortcut;
747 var section = WebInspector.shortcutsScreen.section(WebInspector.UIString('Co nsole'));
748
749 var shortcutL = shortcut.makeDescriptor('l', WebInspector.KeyboardShortcut.M odifiers.Ctrl);
750 var keys = [shortcutL];
751 if (WebInspector.isMac()) {
752 var shortcutK = shortcut.makeDescriptor('k', WebInspector.KeyboardShortcut .Modifiers.Meta);
753 keys.unshift(shortcutK);
754 }
755 section.addAlternateKeys(keys, WebInspector.UIString('Clear console'));
756
757 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector.UISt ring('Autocomplete common prefix'));
758 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspector.UI String('Accept suggestion'));
759
760 var shortcutU = shortcut.makeDescriptor('u', WebInspector.KeyboardShortcut.M odifiers.Ctrl);
761 this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
762 section.addAlternateKeys([shortcutU], WebInspector.UIString('Clear console p rompt'));
763
764 keys = [shortcut.makeDescriptor(shortcut.Keys.Down), shortcut.makeDescriptor (shortcut.Keys.Up)];
765 section.addRelatedKeys(keys, WebInspector.UIString('Next/previous line'));
766
767 if (WebInspector.isMac()) {
768 keys =
769 [shortcut.makeDescriptor('N', shortcut.Modifiers.Alt), shortcut.makeDe scriptor('P', shortcut.Modifiers.Alt)];
770 section.addRelatedKeys(keys, WebInspector.UIString('Next/previous command' ));
771 }
772
773 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspector.UI String('Execute command'));
774 }
775
776 _clearPromptBackwards() {
777 this._prompt.setText('');
778 }
779
780 /**
781 * @param {!Event} event
782 */
783 _promptKeyDown(event) {
784 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
785 if (keyboardEvent.key === 'PageUp') {
786 this._updateStickToBottomOnWheel();
787 return;
788 }
789
790 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(keyboardEvent) ;
791 var handler = this._shortcuts[shortcut];
792 if (handler) {
793 handler();
794 keyboardEvent.preventDefault();
795 }
796 }
797
798 /**
799 * @param {?WebInspector.RemoteObject} result
800 * @param {!WebInspector.ConsoleMessage} originatingConsoleMessage
801 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
802 */
803 _printResult(result, originatingConsoleMessage, exceptionDetails) {
804 if (!result)
805 return;
806
807 var level = !!exceptionDetails ? WebInspector.ConsoleMessage.MessageLevel.Er ror :
808 WebInspector.ConsoleMessage.MessageLevel.Lo g;
809 var message;
810 if (!exceptionDetails)
811 message = new WebInspector.ConsoleMessage(
812 result.target(), WebInspector.ConsoleMessage.MessageSource.JS, level, '',
813 WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, undefined, [result]);
814 else
815 message = WebInspector.ConsoleMessage.fromException(
816 result.target(), exceptionDetails, WebInspector.ConsoleMessage.Message Type.Result, undefined, undefined);
817 message.setOriginatingMessage(originatingConsoleMessage);
818 result.target().consoleModel.addMessage(message);
819 }
820
821 /**
822 * @param {!WebInspector.Event} event
823 */
824 _commandEvaluated(event) {
825 var data =
826 /** @type {{result: ?WebInspector.RemoteObject, text: string, commandMes sage: !WebInspector.ConsoleMessage, exceptionDetails: (!RuntimeAgent.ExceptionDe tails|undefined)}} */
827 (event.data);
828 this._prompt.history().pushHistoryItem(data.text);
829 this._consoleHistorySetting.set(
830 this._prompt.history().historyData().slice(-WebInspector.ConsoleView.per sistedHistorySize));
831 this._printResult(data.result, data.commandMessage, data.exceptionDetails);
832 }
833
834 /**
835 * @override
836 * @return {!Array.<!Element>}
837 */
838 elementsToRestoreScrollPositionsFor() {
839 return [this._messagesElement];
840 }
841
842 /**
843 * @override
844 */
845 searchCanceled() {
846 this._cleanupAfterSearch();
847 for (var i = 0; i < this._visibleViewMessages.length; ++i) {
848 var message = this._visibleViewMessages[i];
849 message.setSearchRegex(null);
850 }
851 this._currentMatchRangeIndex = -1;
852 this._regexMatchRanges = [];
853 delete this._searchRegex;
854 this._viewport.refresh();
855 }
856
857 /**
858 * @override
859 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
860 * @param {boolean} shouldJump
861 * @param {boolean=} jumpBackwards
862 */
863 performSearch(searchConfig, shouldJump, jumpBackwards) {
864 this.searchCanceled();
865 this._searchableView.updateSearchMatchesCount(0);
866
867 this._searchRegex = searchConfig.toSearchRegex(true);
868
869 this._regexMatchRanges = [];
870 this._currentMatchRangeIndex = -1;
871
872 if (shouldJump)
873 this._searchShouldJumpBackwards = !!jumpBackwards;
874
875 this._searchProgressIndicator = new WebInspector.ProgressIndicator();
876 this._searchProgressIndicator.setTitle(WebInspector.UIString('Searching…'));
877 this._searchProgressIndicator.setTotalWork(this._visibleViewMessages.length) ;
878 this._progressToolbarItem.element.appendChild(this._searchProgressIndicator. element);
879
880 this._innerSearch(0);
881 }
882
883 _cleanupAfterSearch() {
884 delete this._searchShouldJumpBackwards;
885 if (this._innerSearchTimeoutId) {
886 clearTimeout(this._innerSearchTimeoutId);
887 delete this._innerSearchTimeoutId;
888 }
889 if (this._searchProgressIndicator) {
890 this._searchProgressIndicator.done();
891 delete this._searchProgressIndicator;
892 }
893 }
894
895 _searchFinishedForTests() {
896 // This method is sniffed in tests.
897 }
898
899 /**
900 * @param {number} index
901 */
902 _innerSearch(index) {
903 delete this._innerSearchTimeoutId;
904 if (this._searchProgressIndicator.isCanceled()) {
905 this._cleanupAfterSearch();
906 return;
907 }
908
909 var startTime = Date.now();
910 for (; index < this._visibleViewMessages.length && Date.now() - startTime < 100; ++index)
911 this._searchMessage(index);
912
913 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length) ;
914 if (typeof this._searchShouldJumpBackwards !== 'undefined' && this._regexMat chRanges.length) {
915 this._jumpToMatch(this._searchShouldJumpBackwards ? -1 : 0);
916 delete this._searchShouldJumpBackwards;
917 }
918
919 if (index === this._visibleViewMessages.length) {
920 this._cleanupAfterSearch();
921 setTimeout(this._searchFinishedForTests.bind(this), 0);
922 return;
923 }
924
925 this._innerSearchTimeoutId = setTimeout(this._innerSearch.bind(this, index), 100);
926 this._searchProgressIndicator.setWorked(index);
927 }
928
929 /**
930 * @param {number} index
931 */
932 _searchMessage(index) {
933 var message = this._visibleViewMessages[index];
934 message.setSearchRegex(this._searchRegex);
935 for (var i = 0; i < message.searchCount(); ++i) {
936 this._regexMatchRanges.push({messageIndex: index, matchIndex: i});
937 }
938 }
939
940 /**
941 * @override
942 */
943 jumpToNextSearchResult() {
944 this._jumpToMatch(this._currentMatchRangeIndex + 1);
945 }
946
947 /**
948 * @override
949 */
950 jumpToPreviousSearchResult() {
951 this._jumpToMatch(this._currentMatchRangeIndex - 1);
952 }
953
954 /**
955 * @override
956 * @return {boolean}
957 */
958 supportsCaseSensitiveSearch() {
959 return true;
960 }
961
962 /**
963 * @override
964 * @return {boolean}
965 */
966 supportsRegexSearch() {
967 return true;
968 }
969
970 /**
971 * @param {number} index
972 */
973 _jumpToMatch(index) {
974 if (!this._regexMatchRanges.length)
975 return;
976
977 var matchRange;
978 if (this._currentMatchRangeIndex >= 0) {
979 matchRange = this._regexMatchRanges[this._currentMatchRangeIndex];
980 var message = this._visibleViewMessages[matchRange.messageIndex];
981 message.searchHighlightNode(matchRange.matchIndex)
982 .classList.remove(WebInspector.highlightedCurrentSearchResultClassName );
983 }
984
985 index = mod(index, this._regexMatchRanges.length);
986 this._currentMatchRangeIndex = index;
987 this._searchableView.updateCurrentMatchIndex(index);
988 matchRange = this._regexMatchRanges[index];
989 var message = this._visibleViewMessages[matchRange.messageIndex];
990 var highlightNode = message.searchHighlightNode(matchRange.matchIndex);
991 highlightNode.classList.add(WebInspector.highlightedCurrentSearchResultClass Name);
992 this._viewport.scrollItemIntoView(matchRange.messageIndex);
993 highlightNode.scrollIntoViewIfNeeded();
994 }
995
996 _updateStickToBottomOnMouseDown() {
997 this._muteViewportUpdates = true;
998 this._viewport.setStickToBottom(false);
999 if (this._waitForScrollTimeout) {
1000 clearTimeout(this._waitForScrollTimeout);
1001 delete this._waitForScrollTimeout;
1002 }
1003 }
1004
1005 _updateStickToBottomOnMouseUp() {
1006 if (!this._muteViewportUpdates)
1007 return;
1008
1009 // Delay querying isScrolledToBottom to give time for smooth scroll
1010 // events to arrive. The value for the longest timeout duration is
1011 // retrieved from crbug.com/575409.
1012 this._waitForScrollTimeout = setTimeout(updateViewportState.bind(this), 200) ;
244 1013
245 /** 1014 /**
246 * @override 1015 * @this {!WebInspector.ConsoleView}
247 * @return {number}
248 */ 1016 */
249 minimumRowHeight: function() 1017 function updateViewportState() {
250 { 1018 this._muteViewportUpdates = false;
251 return 16; 1019 this._viewport.setStickToBottom(this._messagesElement.isScrolledToBottom() );
252 }, 1020 if (this._maybeDirtyWhileMuted) {
253
254 /**
255 * @override
256 * @param {!WebInspector.Target} target
257 */
258 targetAdded: function(target)
259 {
260 this._viewport.invalidate();
261 this._updateAllMessagesCheckbox();
262 },
263
264 /**
265 * @override
266 * @param {!WebInspector.Target} target
267 */
268 targetRemoved: function(target)
269 {
270 this._updateAllMessagesCheckbox();
271 },
272
273 _updateAllMessagesCheckbox: function()
274 {
275 var hasMultipleCotexts = WebInspector.targetManager.targets(WebInspector .Target.Capability.JS).length > 1;
276 this._showAllMessagesCheckbox.element.classList.toggle("hidden", !hasMul tipleCotexts);
277 },
278
279 _registerWithMessageSink: function()
280 {
281 WebInspector.console.messages().forEach(this._addSinkMessage, this);
282 WebInspector.console.addEventListener(WebInspector.Console.Events.Messag eAdded, messageAdded, this);
283
284 /**
285 * @param {!WebInspector.Event} event
286 * @this {WebInspector.ConsoleView}
287 */
288 function messageAdded(event)
289 {
290 this._addSinkMessage(/** @type {!WebInspector.Console.Message} */ (e vent.data));
291 }
292 },
293
294 /**
295 * @param {!WebInspector.Console.Message} message
296 */
297 _addSinkMessage: function(message)
298 {
299 var level = WebInspector.ConsoleMessage.MessageLevel.Debug;
300 switch (message.level) {
301 case WebInspector.Console.MessageLevel.Error:
302 level = WebInspector.ConsoleMessage.MessageLevel.Error;
303 break;
304 case WebInspector.Console.MessageLevel.Warning:
305 level = WebInspector.ConsoleMessage.MessageLevel.Warning;
306 break;
307 }
308
309 var consoleMessage = new WebInspector.ConsoleMessage(null, WebInspector. ConsoleMessage.MessageSource.Other, level, message.text,
310 undefined, undefined, undefined, undefined, undefined, undefined , undefined, message.timestamp);
311 this._addConsoleMessage(consoleMessage);
312 },
313
314 /**
315 * @param {!WebInspector.Event} event
316 */
317 _consoleTimestampsSettingChanged: function(event)
318 {
319 var enabled = /** @type {boolean} */ (event.data);
320 this._updateMessageList();
321 this._consoleMessages.forEach(function(viewMessage) {
322 viewMessage.updateTimestamp(enabled);
323 });
324 },
325
326 _executionContextChanged: function()
327 {
328 this._prompt.clearAutocomplete();
329 if (!this._showAllMessagesCheckbox.checked())
330 this._updateMessageList();
331 },
332
333 willHide: function()
334 {
335 this._hidePromptSuggestBox();
336 },
337
338 wasShown: function()
339 {
340 this._viewport.refresh();
341 },
342
343 focus: function()
344 {
345 if (this._prompt.hasFocus())
346 return;
347 // Set caret position before setting focus in order to avoid scrolling
348 // by focus().
349 this._prompt.moveCaretToEndOfPrompt();
350 this._prompt.focus();
351 },
352
353 restoreScrollPositions: function()
354 {
355 if (this._viewport.stickToBottom())
356 this._immediatelyScrollToBottom();
357 else
358 WebInspector.Widget.prototype.restoreScrollPositions.call(this);
359 },
360
361 onResize: function()
362 {
363 this._scheduleViewportRefresh(); 1021 this._scheduleViewportRefresh();
364 this._hidePromptSuggestBox(); 1022 delete this._maybeDirtyWhileMuted;
365 if (this._viewport.stickToBottom()) 1023 }
366 this._immediatelyScrollToBottom(); 1024 delete this._waitForScrollTimeout;
367 for (var i = 0; i < this._visibleViewMessages.length; ++i) 1025 this._updateViewportStickinessForTest();
368 this._visibleViewMessages[i].onResize(); 1026 }
369 }, 1027 }
370 1028
371 _hidePromptSuggestBox: function() 1029 _updateViewportStickinessForTest() {
372 { 1030 // This method is sniffed in tests.
373 this._prompt.clearAutocomplete(); 1031 }
374 }, 1032
375 1033 _updateStickToBottomOnWheel() {
376 _scheduleViewportRefresh: function() 1034 this._updateStickToBottomOnMouseDown();
377 { 1035 this._updateStickToBottomOnMouseUp();
378 /** 1036 }
379 * @this {WebInspector.ConsoleView} 1037
380 * @return {!Promise.<undefined>} 1038 _promptInput(event) {
381 */ 1039 // Scroll to the bottom, except when the prompt is the only visible item.
382 function invalidateViewport() 1040 if (this.itemCount() !== 0 && this._viewport.firstVisibleIndex() !== this.it emCount())
383 { 1041 this._immediatelyScrollToBottom();
384 if (this._muteViewportUpdates) { 1042 }
385 this._maybeDirtyWhileMuted = true;
386 return Promise.resolve();
387 }
388 if (this._needsFullUpdate) {
389 this._updateMessageList();
390 delete this._needsFullUpdate;
391 } else {
392 this._viewport.invalidate();
393 }
394 return Promise.resolve();
395 }
396 if (this._muteViewportUpdates) {
397 this._maybeDirtyWhileMuted = true;
398 this._scheduleViewportRefreshForTest(true);
399 return;
400 } else {
401 this._scheduleViewportRefreshForTest(false);
402 }
403 this._viewportThrottler.schedule(invalidateViewport.bind(this));
404 },
405
406 /**
407 * @param {boolean} muted
408 */
409 _scheduleViewportRefreshForTest: function(muted)
410 {
411 // This functions is sniffed in tests.
412 },
413
414 _immediatelyScrollToBottom: function()
415 {
416 // This will scroll viewport and trigger its refresh.
417 this._viewport.setStickToBottom(true);
418 this._promptElement.scrollIntoView(true);
419 },
420
421 _updateFilterStatus: function()
422 {
423 this._filterStatusTextElement.textContent = WebInspector.UIString(this._ hiddenByFilterCount === 1 ? "%d message is hidden by filters." : "%d messages ar e hidden by filters.", this._hiddenByFilterCount);
424 this._filterStatusMessageElement.style.display = this._hiddenByFilterCou nt ? "" : "none";
425 },
426
427 /**
428 * @param {!WebInspector.Event} event
429 */
430 _onConsoleMessageAdded: function(event)
431 {
432 var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
433 this._addConsoleMessage(message);
434 },
435
436 /**
437 * @param {!WebInspector.ConsoleMessage} message
438 */
439 _addConsoleMessage: function(message)
440 {
441 /**
442 * @param {!WebInspector.ConsoleViewMessage} viewMessage1
443 * @param {!WebInspector.ConsoleViewMessage} viewMessage2
444 * @return {number}
445 */
446 function compareTimestamps(viewMessage1, viewMessage2)
447 {
448 return WebInspector.ConsoleMessage.timestampComparator(viewMessage1. consoleMessage(), viewMessage2.consoleMessage());
449 }
450
451 if (message.type === WebInspector.ConsoleMessage.MessageType.Command || message.type === WebInspector.ConsoleMessage.MessageType.Result)
452 message.timestamp = this._consoleMessages.length ? this._consoleMess ages.peekLast().consoleMessage().timestamp : 0;
453 var viewMessage = this._createViewMessage(message);
454 message[this._viewMessageSymbol] = viewMessage;
455 var insertAt = this._consoleMessages.upperBound(viewMessage, compareTime stamps);
456 var insertedInMiddle = insertAt < this._consoleMessages.length;
457 this._consoleMessages.splice(insertAt, 0, viewMessage);
458
459 if (this._urlToMessageCount[message.url])
460 ++this._urlToMessageCount[message.url];
461 else
462 this._urlToMessageCount[message.url] = 1;
463
464 if (!insertedInMiddle) {
465 this._appendMessageToEnd(viewMessage);
466 this._updateFilterStatus();
467 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges .length);
468 } else {
469 this._needsFullUpdate = true;
470 }
471
472 this._scheduleViewportRefresh();
473 this._consoleMessageAddedForTest(viewMessage);
474 },
475
476 /**
477 * @param {!WebInspector.Event} event
478 */
479 _onConsoleMessageUpdated: function(event)
480 {
481 var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
482 var viewMessage = message[this._viewMessageSymbol];
483 if (viewMessage) {
484 viewMessage.updateMessageElement();
485 this._updateMessageList();
486 }
487 },
488
489 /**
490 * @param {!WebInspector.ConsoleViewMessage} viewMessage
491 */
492 _consoleMessageAddedForTest: function(viewMessage) { },
493
494 /**
495 * @param {!WebInspector.ConsoleViewMessage} viewMessage
496 */
497 _appendMessageToEnd: function(viewMessage)
498 {
499 if (!this._filter.shouldBeVisible(viewMessage)) {
500 this._hiddenByFilterCount++;
501 return;
502 }
503
504 if (this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.p eekLast()))
505 return;
506
507 var lastMessage = this._visibleViewMessages.peekLast();
508 if (viewMessage.consoleMessage().type === WebInspector.ConsoleMessage.Me ssageType.EndGroup) {
509 if (lastMessage && !this._currentGroup.messagesHidden())
510 lastMessage.incrementCloseGroupDecorationCount();
511 this._currentGroup = this._currentGroup.parentGroup();
512 return;
513 }
514 if (!this._currentGroup.messagesHidden()) {
515 var originatingMessage = viewMessage.consoleMessage().originatingMes sage();
516 if (lastMessage && originatingMessage && lastMessage.consoleMessage( ) === originatingMessage)
517 lastMessage.toMessageElement().classList.add("console-adjacent-u ser-command-result");
518
519 this._visibleViewMessages.push(viewMessage);
520 this._searchMessage(this._visibleViewMessages.length - 1);
521 }
522
523 if (viewMessage.consoleMessage().isGroupStartMessage())
524 this._currentGroup = new WebInspector.ConsoleGroup(this._currentGrou p, viewMessage);
525
526 this._messageAppendedForTests();
527 },
528
529 _messageAppendedForTests: function()
530 {
531 // This method is sniffed in tests.
532 },
533
534 /**
535 * @param {!WebInspector.ConsoleMessage} message
536 * @return {!WebInspector.ConsoleViewMessage}
537 */
538 _createViewMessage: function(message)
539 {
540 var nestingLevel = this._currentGroup.nestingLevel();
541 switch (message.type) {
542 case WebInspector.ConsoleMessage.MessageType.Command:
543 return new WebInspector.ConsoleCommand(message, this._linkifier, nes tingLevel);
544 case WebInspector.ConsoleMessage.MessageType.Result:
545 return new WebInspector.ConsoleCommandResult(message, this._linkifie r, nestingLevel);
546 case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
547 case WebInspector.ConsoleMessage.MessageType.StartGroup:
548 return new WebInspector.ConsoleGroupViewMessage(message, this._linki fier, nestingLevel);
549 default:
550 return new WebInspector.ConsoleViewMessage(message, this._linkifier, nestingLevel);
551 }
552 },
553
554 _consoleCleared: function()
555 {
556 this._currentMatchRangeIndex = -1;
557 this._consoleMessages = [];
558 this._updateMessageList();
559 this._hidePromptSuggestBox();
560 this._viewport.setStickToBottom(true);
561 this._linkifier.reset();
562 },
563
564 _handleContextMenuEvent: function(event)
565 {
566 if (event.target.enclosingNodeOrSelfWithNodeName("a"))
567 return;
568
569 var contextMenu = new WebInspector.ContextMenu(event);
570 if (event.target.isSelfOrDescendant(this._promptElement)) {
571 contextMenu.show();
572 return;
573 }
574
575 function monitoringXHRItemAction()
576 {
577 WebInspector.moduleSetting("monitoringXHREnabled").set(!WebInspector .moduleSetting("monitoringXHREnabled").get());
578 }
579 contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequest s"), monitoringXHRItemAction, WebInspector.moduleSetting("monitoringXHREnabled") .get());
580
581 var sourceElement = event.target.enclosingNodeOrSelfWithClass("console-m essage-wrapper");
582 var consoleMessage = sourceElement ? sourceElement.message.consoleMessag e() : null;
583
584 var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString( "Filter"));
585
586 if (consoleMessage && consoleMessage.url) {
587 var menuTitle = WebInspector.UIString.capitalize("Hide ^messages fro m %s", new WebInspector.ParsedURL(consoleMessage.url).displayName);
588 filterSubMenu.appendItem(menuTitle, this._filter.addMessageURLFilter .bind(this._filter, consoleMessage.url));
589 }
590
591 filterSubMenu.appendSeparator();
592 var unhideAll = filterSubMenu.appendItem(WebInspector.UIString.capitaliz e("Unhide ^all"), this._filter.removeMessageURLFilter.bind(this._filter));
593 filterSubMenu.appendSeparator();
594
595 var hasFilters = false;
596
597 for (var url in this._filter.messageURLFilters) {
598 filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)", new WebIn spector.ParsedURL(url).displayName, this._urlToMessageCount[url]), this._filter. removeMessageURLFilter.bind(this._filter, url), true);
599 hasFilters = true;
600 }
601
602 filterSubMenu.setEnabled(hasFilters || (consoleMessage && consoleMessage .url));
603 unhideAll.setEnabled(hasFilters);
604
605 contextMenu.appendSeparator();
606 contextMenu.appendAction("console.clear");
607 contextMenu.appendAction("console.clear.history");
608 contextMenu.appendItem(WebInspector.UIString("Save as..."), this._saveCo nsole.bind(this));
609
610 var request = consoleMessage ? consoleMessage.request : null;
611 if (request && request.resourceType() === WebInspector.resourceTypes.XHR ) {
612 contextMenu.appendSeparator();
613 contextMenu.appendItem(WebInspector.UIString("Replay XHR"), request. replayXHR.bind(request));
614 }
615
616 contextMenu.show();
617 },
618
619 _saveConsole: function()
620 {
621 var url = WebInspector.targetManager.mainTarget().inspectedURL();
622 var parsedURL = url.asParsedURL();
623 var filename = String.sprintf("%s-%d.log", parsedURL ? parsedURL.host : "console", Date.now());
624 var stream = new WebInspector.FileOutputStream();
625
626 var progressIndicator = new WebInspector.ProgressIndicator();
627 progressIndicator.setTitle(WebInspector.UIString("Writing file…"));
628 progressIndicator.setTotalWork(this.itemCount());
629
630 /** @const */
631 var chunkSize = 350;
632 var messageIndex = 0;
633
634 stream.open(filename, openCallback.bind(this));
635
636 /**
637 * @param {boolean} accepted
638 * @this {WebInspector.ConsoleView}
639 */
640 function openCallback(accepted)
641 {
642 if (!accepted)
643 return;
644 this._progressToolbarItem.element.appendChild(progressIndicator.elem ent);
645 writeNextChunk.call(this, stream);
646 }
647
648 /**
649 * @param {!WebInspector.OutputStream} stream
650 * @param {string=} error
651 * @this {WebInspector.ConsoleView}
652 */
653 function writeNextChunk(stream, error)
654 {
655 if (messageIndex >= this.itemCount() || error) {
656 stream.close();
657 progressIndicator.done();
658 return;
659 }
660 var lines = [];
661 for (var i = 0; i < chunkSize && i + messageIndex < this.itemCount() ; ++i) {
662 var message = this.itemElement(messageIndex + i);
663 var messageContent = message.contentElement().deepTextContent();
664 for (var j = 0; j < message.repeatCount(); ++j)
665 lines.push(messageContent);
666 }
667 messageIndex += i;
668 stream.write(lines.join("\n") + "\n", writeNextChunk.bind(this));
669 progressIndicator.setWorked(messageIndex);
670 }
671
672 },
673
674 /**
675 * @param {!WebInspector.ConsoleViewMessage} lastMessage
676 * @param {?WebInspector.ConsoleViewMessage=} viewMessage
677 * @return {boolean}
678 */
679 _tryToCollapseMessages: function(lastMessage, viewMessage)
680 {
681 if (!WebInspector.moduleSetting("consoleTimestampsEnabled").get() && vie wMessage && !lastMessage.consoleMessage().isGroupMessage() && lastMessage.consol eMessage().isEqual(viewMessage.consoleMessage())) {
682 viewMessage.incrementRepeatCount();
683 return true;
684 }
685
686 return false;
687 },
688
689 _updateMessageList: function()
690 {
691 this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
692 this._currentGroup = this._topGroup;
693 this._regexMatchRanges = [];
694 this._hiddenByFilterCount = 0;
695 for (var i = 0; i < this._visibleViewMessages.length; ++i) {
696 this._visibleViewMessages[i].resetCloseGroupDecorationCount();
697 this._visibleViewMessages[i].resetIncrementRepeatCount();
698 }
699 this._visibleViewMessages = [];
700 for (var i = 0; i < this._consoleMessages.length; ++i)
701 this._appendMessageToEnd(this._consoleMessages[i]);
702 this._updateFilterStatus();
703 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.len gth);
704 this._viewport.invalidate();
705 },
706
707 /**
708 * @param {!WebInspector.Event} event
709 */
710 _monitoringXHREnabledSettingChanged: function(event)
711 {
712 var enabled = /** @type {boolean} */ (event.data);
713 WebInspector.targetManager.targets().forEach(function(target) {target.ne tworkAgent().setMonitoringXHREnabled(enabled);});
714 },
715
716 /**
717 * @param {!Event} event
718 */
719 _messagesClicked: function(event)
720 {
721 var targetElement = event.deepElementFromPoint();
722 if (!targetElement || targetElement.isComponentSelectionCollapsed())
723 this.focus();
724 var groupMessage = event.target.enclosingNodeOrSelfWithClass("console-gr oup-title");
725 if (!groupMessage)
726 return;
727 var consoleGroupViewMessage = groupMessage.parentElement.message;
728 consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed( ));
729 this._updateMessageList();
730 },
731
732 _registerShortcuts: function()
733 {
734 this._shortcuts = {};
735
736 var shortcut = WebInspector.KeyboardShortcut;
737 var section = WebInspector.shortcutsScreen.section(WebInspector.UIString ("Console"));
738
739 var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortc ut.Modifiers.Ctrl);
740 var keys = [shortcutL];
741 if (WebInspector.isMac()) {
742 var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardSh ortcut.Modifiers.Meta);
743 keys.unshift(shortcutK);
744 }
745 section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
746
747 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector. UIString("Autocomplete common prefix"));
748 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspecto r.UIString("Accept suggestion"));
749
750 var shortcutU = shortcut.makeDescriptor("u", WebInspector.KeyboardShortc ut.Modifiers.Ctrl);
751 this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
752 section.addAlternateKeys([shortcutU], WebInspector.UIString("Clear conso le prompt"));
753
754 keys = [
755 shortcut.makeDescriptor(shortcut.Keys.Down),
756 shortcut.makeDescriptor(shortcut.Keys.Up)
757 ];
758 section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line") );
759
760 if (WebInspector.isMac()) {
761 keys = [
762 shortcut.makeDescriptor("N", shortcut.Modifiers.Alt),
763 shortcut.makeDescriptor("P", shortcut.Modifiers.Alt)
764 ];
765 section.addRelatedKeys(keys, WebInspector.UIString("Next/previous co mmand"));
766 }
767
768 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspecto r.UIString("Execute command"));
769 },
770
771 _clearPromptBackwards: function()
772 {
773 this._prompt.setText("");
774 },
775
776 /**
777 * @param {!Event} event
778 */
779 _promptKeyDown: function(event)
780 {
781 var keyboardEvent = /** @type {!KeyboardEvent} */ (event);
782 if (keyboardEvent.key === "PageUp") {
783 this._updateStickToBottomOnWheel();
784 return;
785 }
786
787 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(keyboardEv ent);
788 var handler = this._shortcuts[shortcut];
789 if (handler) {
790 handler();
791 keyboardEvent.preventDefault();
792 }
793 },
794
795 /**
796 * @param {?WebInspector.RemoteObject} result
797 * @param {!WebInspector.ConsoleMessage} originatingConsoleMessage
798 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
799 */
800 _printResult: function(result, originatingConsoleMessage, exceptionDetails)
801 {
802 if (!result)
803 return;
804
805 var level = !!exceptionDetails ? WebInspector.ConsoleMessage.MessageLeve l.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
806 var message;
807 if (!exceptionDetails)
808 message = new WebInspector.ConsoleMessage(result.target(), WebInspec tor.ConsoleMessage.MessageSource.JS, level, "", WebInspector.ConsoleMessage.Mess ageType.Result, undefined, undefined, undefined, undefined, [result]);
809 else
810 message = WebInspector.ConsoleMessage.fromException(result.target(), exceptionDetails, WebInspector.ConsoleMessage.MessageType.Result, undefined, un defined);
811 message.setOriginatingMessage(originatingConsoleMessage);
812 result.target().consoleModel.addMessage(message);
813 },
814
815 /**
816 * @param {!WebInspector.Event} event
817 */
818 _commandEvaluated: function(event)
819 {
820 var data = /** @type {{result: ?WebInspector.RemoteObject, text: string, commandMessage: !WebInspector.ConsoleMessage, exceptionDetails: (!RuntimeAgent. ExceptionDetails|undefined)}} */ (event.data);
821 this._prompt.history().pushHistoryItem(data.text);
822 this._consoleHistorySetting.set(this._prompt.history().historyData().sli ce(-WebInspector.ConsoleView.persistedHistorySize));
823 this._printResult(data.result, data.commandMessage, data.exceptionDetail s);
824 },
825
826 /**
827 * @override
828 * @return {!Array.<!Element>}
829 */
830 elementsToRestoreScrollPositionsFor: function()
831 {
832 return [this._messagesElement];
833 },
834
835 /**
836 * @override
837 */
838 searchCanceled: function()
839 {
840 this._cleanupAfterSearch();
841 for (var i = 0; i < this._visibleViewMessages.length; ++i) {
842 var message = this._visibleViewMessages[i];
843 message.setSearchRegex(null);
844 }
845 this._currentMatchRangeIndex = -1;
846 this._regexMatchRanges = [];
847 delete this._searchRegex;
848 this._viewport.refresh();
849 },
850
851 /**
852 * @override
853 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
854 * @param {boolean} shouldJump
855 * @param {boolean=} jumpBackwards
856 */
857 performSearch: function(searchConfig, shouldJump, jumpBackwards)
858 {
859 this.searchCanceled();
860 this._searchableView.updateSearchMatchesCount(0);
861
862 this._searchRegex = searchConfig.toSearchRegex(true);
863
864 this._regexMatchRanges = [];
865 this._currentMatchRangeIndex = -1;
866
867 if (shouldJump)
868 this._searchShouldJumpBackwards = !!jumpBackwards;
869
870 this._searchProgressIndicator = new WebInspector.ProgressIndicator();
871 this._searchProgressIndicator.setTitle(WebInspector.UIString("Searching… "));
872 this._searchProgressIndicator.setTotalWork(this._visibleViewMessages.len gth);
873 this._progressToolbarItem.element.appendChild(this._searchProgressIndica tor.element);
874
875 this._innerSearch(0);
876 },
877
878 _cleanupAfterSearch: function()
879 {
880 delete this._searchShouldJumpBackwards;
881 if (this._innerSearchTimeoutId) {
882 clearTimeout(this._innerSearchTimeoutId);
883 delete this._innerSearchTimeoutId;
884 }
885 if (this._searchProgressIndicator) {
886 this._searchProgressIndicator.done();
887 delete this._searchProgressIndicator;
888 }
889 },
890
891 _searchFinishedForTests: function()
892 {
893 // This method is sniffed in tests.
894 },
895
896 /**
897 * @param {number} index
898 */
899 _innerSearch: function(index)
900 {
901 delete this._innerSearchTimeoutId;
902 if (this._searchProgressIndicator.isCanceled()) {
903 this._cleanupAfterSearch();
904 return;
905 }
906
907 var startTime = Date.now();
908 for (; index < this._visibleViewMessages.length && Date.now() - startTim e < 100; ++index)
909 this._searchMessage(index);
910
911 this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.len gth);
912 if (typeof this._searchShouldJumpBackwards !== "undefined" && this._rege xMatchRanges.length) {
913 this._jumpToMatch(this._searchShouldJumpBackwards ? -1 : 0);
914 delete this._searchShouldJumpBackwards;
915 }
916
917 if (index === this._visibleViewMessages.length) {
918 this._cleanupAfterSearch();
919 setTimeout(this._searchFinishedForTests.bind(this), 0);
920 return;
921 }
922
923 this._innerSearchTimeoutId = setTimeout(this._innerSearch.bind(this, ind ex), 100);
924 this._searchProgressIndicator.setWorked(index);
925 },
926
927 /**
928 * @param {number} index
929 */
930 _searchMessage: function(index)
931 {
932 var message = this._visibleViewMessages[index];
933 message.setSearchRegex(this._searchRegex);
934 for (var i = 0; i < message.searchCount(); ++i) {
935 this._regexMatchRanges.push({
936 messageIndex: index,
937 matchIndex: i
938 });
939 }
940 },
941
942 /**
943 * @override
944 */
945 jumpToNextSearchResult: function()
946 {
947 this._jumpToMatch(this._currentMatchRangeIndex + 1);
948 },
949
950 /**
951 * @override
952 */
953 jumpToPreviousSearchResult: function()
954 {
955 this._jumpToMatch(this._currentMatchRangeIndex - 1);
956 },
957
958 /**
959 * @override
960 * @return {boolean}
961 */
962 supportsCaseSensitiveSearch: function()
963 {
964 return true;
965 },
966
967 /**
968 * @override
969 * @return {boolean}
970 */
971 supportsRegexSearch: function()
972 {
973 return true;
974 },
975
976 /**
977 * @param {number} index
978 */
979 _jumpToMatch: function(index)
980 {
981 if (!this._regexMatchRanges.length)
982 return;
983
984 var matchRange;
985 if (this._currentMatchRangeIndex >= 0) {
986 matchRange = this._regexMatchRanges[this._currentMatchRangeIndex];
987 var message = this._visibleViewMessages[matchRange.messageIndex];
988 message.searchHighlightNode(matchRange.matchIndex).classList.remove( WebInspector.highlightedCurrentSearchResultClassName);
989 }
990
991 index = mod(index, this._regexMatchRanges.length);
992 this._currentMatchRangeIndex = index;
993 this._searchableView.updateCurrentMatchIndex(index);
994 matchRange = this._regexMatchRanges[index];
995 var message = this._visibleViewMessages[matchRange.messageIndex];
996 var highlightNode = message.searchHighlightNode(matchRange.matchIndex);
997 highlightNode.classList.add(WebInspector.highlightedCurrentSearchResultC lassName);
998 this._viewport.scrollItemIntoView(matchRange.messageIndex);
999 highlightNode.scrollIntoViewIfNeeded();
1000 },
1001
1002 _updateStickToBottomOnMouseDown: function()
1003 {
1004 this._muteViewportUpdates = true;
1005 this._viewport.setStickToBottom(false);
1006 if (this._waitForScrollTimeout) {
1007 clearTimeout(this._waitForScrollTimeout);
1008 delete this._waitForScrollTimeout;
1009 }
1010 },
1011
1012 _updateStickToBottomOnMouseUp: function()
1013 {
1014 if (!this._muteViewportUpdates)
1015 return;
1016
1017 // Delay querying isScrolledToBottom to give time for smooth scroll
1018 // events to arrive. The value for the longest timeout duration is
1019 // retrieved from crbug.com/575409.
1020 this._waitForScrollTimeout = setTimeout(updateViewportState.bind(this), 200);
1021
1022 /**
1023 * @this {!WebInspector.ConsoleView}
1024 */
1025 function updateViewportState()
1026 {
1027 this._muteViewportUpdates = false;
1028 this._viewport.setStickToBottom(this._messagesElement.isScrolledToBo ttom());
1029 if (this._maybeDirtyWhileMuted) {
1030 this._scheduleViewportRefresh();
1031 delete this._maybeDirtyWhileMuted;
1032 }
1033 delete this._waitForScrollTimeout;
1034 this._updateViewportStickinessForTest();
1035 }
1036 },
1037
1038 _updateViewportStickinessForTest: function()
1039 {
1040 // This method is sniffed in tests.
1041 },
1042
1043 _updateStickToBottomOnWheel: function()
1044 {
1045 this._updateStickToBottomOnMouseDown();
1046 this._updateStickToBottomOnMouseUp();
1047 },
1048
1049 _promptInput: function(event)
1050 {
1051 // Scroll to the bottom, except when the prompt is the only visible item .
1052 if (this.itemCount() !== 0 && this._viewport.firstVisibleIndex() !== thi s.itemCount())
1053 this._immediatelyScrollToBottom();
1054 },
1055
1056 __proto__: WebInspector.VBox.prototype
1057 }; 1043 };
1058 1044
1045 WebInspector.ConsoleView.persistedHistorySize = 300;
1046
1059 /** 1047 /**
1060 * @constructor 1048 * @unrestricted
1061 * @extends {WebInspector.Object}
1062 * @param {!WebInspector.ConsoleView} view
1063 */ 1049 */
1064 WebInspector.ConsoleViewFilter = function(view) 1050 WebInspector.ConsoleViewFilter = class extends WebInspector.Object {
1065 { 1051 /**
1066 this._messageURLFiltersSetting = WebInspector.settings.createSetting("messag eURLFilters", {}); 1052 * @param {!WebInspector.ConsoleView} view
1067 this._messageLevelFiltersSetting = WebInspector.settings.createSetting("mess ageLevelFilters", {}); 1053 */
1054 constructor(view) {
1055 super();
1056 this._messageURLFiltersSetting = WebInspector.settings.createSetting('messag eURLFilters', {});
1057 this._messageLevelFiltersSetting = WebInspector.settings.createSetting('mess ageLevelFilters', {});
1068 1058
1069 this._view = view; 1059 this._view = view;
1070 this._messageURLFilters = this._messageURLFiltersSetting.get(); 1060 this._messageURLFilters = this._messageURLFiltersSetting.get();
1071 this._filterChanged = this.dispatchEventToListeners.bind(this, WebInspector. ConsoleViewFilter.Events.FilterChanged); 1061 this._filterChanged = this.dispatchEventToListeners.bind(this, WebInspector. ConsoleViewFilter.Events.FilterChanged);
1062 }
1063
1064 addFilters(filterBar) {
1065 this._textFilterUI = new WebInspector.TextFilterUI(true);
1066 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChang ed, this._textFilterChanged, this);
1067 filterBar.addFilter(this._textFilterUI);
1068
1069 this._hideNetworkMessagesCheckbox = new WebInspector.CheckboxFilterUI(
1070 'hide-network-messages', WebInspector.UIString('Hide network messages'), true,
1071 WebInspector.moduleSetting('hideNetworkMessages'));
1072 this._hideNetworkMessagesCheckbox.addEventListener(
1073 WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(thi s), this);
1074 filterBar.addFilter(this._hideNetworkMessagesCheckbox);
1075
1076 var levels = [
1077 {name: WebInspector.ConsoleMessage.MessageLevel.Error, label: WebInspector .UIString('Errors')},
1078 {name: WebInspector.ConsoleMessage.MessageLevel.Warning, label: WebInspect or.UIString('Warnings')},
1079 {name: WebInspector.ConsoleMessage.MessageLevel.Info, label: WebInspector. UIString('Info')},
1080 {name: WebInspector.ConsoleMessage.MessageLevel.Log, label: WebInspector.U IString('Logs')},
1081 {name: WebInspector.ConsoleMessage.MessageLevel.Debug, label: WebInspector .UIString('Debug')},
1082 {name: WebInspector.ConsoleMessage.MessageLevel.RevokedError, label: WebIn spector.UIString('Handled')}
1083 ];
1084 this._levelFilterUI = new WebInspector.NamedBitSetFilterUI(levels, this._mes sageLevelFiltersSetting);
1085 this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChan ged, this._filterChanged, this);
1086 filterBar.addFilter(this._levelFilterUI);
1087 }
1088
1089 _textFilterChanged(event) {
1090 this._filterRegex = this._textFilterUI.regex();
1091
1092 this._filterChanged();
1093 }
1094
1095 /**
1096 * @param {string} url
1097 */
1098 addMessageURLFilter(url) {
1099 this._messageURLFilters[url] = true;
1100 this._messageURLFiltersSetting.set(this._messageURLFilters);
1101 this._filterChanged();
1102 }
1103
1104 /**
1105 * @param {string} url
1106 */
1107 removeMessageURLFilter(url) {
1108 if (!url)
1109 this._messageURLFilters = {};
1110 else
1111 delete this._messageURLFilters[url];
1112
1113 this._messageURLFiltersSetting.set(this._messageURLFilters);
1114 this._filterChanged();
1115 }
1116
1117 /**
1118 * @returns {!Object}
1119 */
1120 get messageURLFilters() {
1121 return this._messageURLFilters;
1122 }
1123
1124 /**
1125 * @param {!WebInspector.ConsoleViewMessage} viewMessage
1126 * @return {boolean}
1127 */
1128 shouldBeVisible(viewMessage) {
1129 var message = viewMessage.consoleMessage();
1130 var executionContext = WebInspector.context.flavor(WebInspector.ExecutionCon text);
1131 if (!message.target())
1132 return true;
1133
1134 if (!this._view._showAllMessagesCheckbox.checked() && executionContext) {
1135 if (message.target() !== executionContext.target())
1136 return false;
1137 if (message.executionContextId && message.executionContextId !== execution Context.id) {
1138 return false;
1139 }
1140 }
1141
1142 if (WebInspector.moduleSetting('hideNetworkMessages').get() &&
1143 viewMessage.consoleMessage().source === WebInspector.ConsoleMessage.Mess ageSource.Network)
1144 return false;
1145
1146 if (viewMessage.consoleMessage().isGroupMessage())
1147 return true;
1148
1149 if (message.type === WebInspector.ConsoleMessage.MessageType.Result ||
1150 message.type === WebInspector.ConsoleMessage.MessageType.Command)
1151 return true;
1152
1153 if (message.url && this._messageURLFilters[message.url])
1154 return false;
1155
1156 if (message.level && !this._levelFilterUI.accept(message.level))
1157 return false;
1158
1159 if (this._filterRegex) {
1160 this._filterRegex.lastIndex = 0;
1161 if (!viewMessage.matchesFilterRegex(this._filterRegex))
1162 return false;
1163 }
1164
1165 return true;
1166 }
1167
1168 reset() {
1169 this._messageURLFilters = {};
1170 this._messageURLFiltersSetting.set(this._messageURLFilters);
1171 this._messageLevelFiltersSetting.set({});
1172 this._view._showAllMessagesCheckbox.inputElement.checked = true;
1173 WebInspector.moduleSetting('hideNetworkMessages').set(false);
1174 this._textFilterUI.setValue('');
1175 this._filterChanged();
1176 }
1072 }; 1177 };
1073 1178
1074 /** @enum {symbol} */ 1179 /** @enum {symbol} */
1075 WebInspector.ConsoleViewFilter.Events = { 1180 WebInspector.ConsoleViewFilter.Events = {
1076 FilterChanged: Symbol("FilterChanged") 1181 FilterChanged: Symbol('FilterChanged')
1077 }; 1182 };
1078 1183
1079 WebInspector.ConsoleViewFilter.prototype = { 1184 /**
1080 addFilters: function(filterBar) 1185 * @unrestricted
1081 { 1186 */
1082 this._textFilterUI = new WebInspector.TextFilterUI(true); 1187 WebInspector.ConsoleCommand = class extends WebInspector.ConsoleViewMessage {
1083 this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterC hanged, this._textFilterChanged, this); 1188 /**
1084 filterBar.addFilter(this._textFilterUI); 1189 * @param {!WebInspector.ConsoleMessage} message
1085 1190 * @param {!WebInspector.Linkifier} linkifier
1086 this._hideNetworkMessagesCheckbox = new WebInspector.CheckboxFilterUI("h ide-network-messages", WebInspector.UIString("Hide network messages"), true, Web Inspector.moduleSetting("hideNetworkMessages")); 1191 * @param {number} nestingLevel
1087 this._hideNetworkMessagesCheckbox.addEventListener(WebInspector.FilterUI .Events.FilterChanged, this._filterChanged.bind(this), this); 1192 */
1088 filterBar.addFilter(this._hideNetworkMessagesCheckbox); 1193 constructor(message, linkifier, nestingLevel) {
1089 1194 super(message, linkifier, nestingLevel);
1090 var levels = [ 1195 }
1091 {name: WebInspector.ConsoleMessage.MessageLevel.Error, label: WebIns pector.UIString("Errors")}, 1196
1092 {name: WebInspector.ConsoleMessage.MessageLevel.Warning, label: WebI nspector.UIString("Warnings")}, 1197 /**
1093 {name: WebInspector.ConsoleMessage.MessageLevel.Info, label: WebInsp ector.UIString("Info")}, 1198 * @override
1094 {name: WebInspector.ConsoleMessage.MessageLevel.Log, label: WebInspe ctor.UIString("Logs")}, 1199 * @return {!Element}
1095 {name: WebInspector.ConsoleMessage.MessageLevel.Debug, label: WebIns pector.UIString("Debug")}, 1200 */
1096 {name: WebInspector.ConsoleMessage.MessageLevel.RevokedError, label: WebInspector.UIString("Handled")} 1201 contentElement() {
1097 ]; 1202 if (!this._contentElement) {
1098 this._levelFilterUI = new WebInspector.NamedBitSetFilterUI(levels, this. _messageLevelFiltersSetting); 1203 this._contentElement = createElementWithClass('div', 'console-user-command ');
1099 this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.Filter Changed, this._filterChanged, this); 1204 this._contentElement.message = this;
1100 filterBar.addFilter(this._levelFilterUI); 1205
1101 }, 1206 this._formattedCommand = createElementWithClass('span', 'console-message-t ext source-code');
1102 1207 this._formattedCommand.textContent = this.text.replaceControlCharacters();
1103 _textFilterChanged: function(event) 1208 this._contentElement.appendChild(this._formattedCommand);
1104 { 1209
1105 this._filterRegex = this._textFilterUI.regex(); 1210 if (this._formattedCommand.textContent.length < WebInspector.ConsoleComman d.MaxLengthToIgnoreHighlighter) {
1106 1211 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter( 'text/javascript', true);
1107 this._filterChanged(); 1212 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand). then(this._updateSearch.bind(this));
1108 }, 1213 } else {
1109 1214 this._updateSearch();
1110 /** 1215 }
1111 * @param {string} url 1216 }
1112 */ 1217 return this._contentElement;
1113 addMessageURLFilter: function(url) 1218 }
1114 { 1219
1115 this._messageURLFilters[url] = true; 1220 _updateSearch() {
1116 this._messageURLFiltersSetting.set(this._messageURLFilters); 1221 this.setSearchRegex(this.searchRegex());
1117 this._filterChanged(); 1222 }
1118 },
1119
1120 /**
1121 * @param {string} url
1122 */
1123 removeMessageURLFilter: function(url)
1124 {
1125 if (!url)
1126 this._messageURLFilters = {};
1127 else
1128 delete this._messageURLFilters[url];
1129
1130 this._messageURLFiltersSetting.set(this._messageURLFilters);
1131 this._filterChanged();
1132 },
1133
1134 /**
1135 * @returns {!Object}
1136 */
1137 get messageURLFilters()
1138 {
1139 return this._messageURLFilters;
1140 },
1141
1142 /**
1143 * @param {!WebInspector.ConsoleViewMessage} viewMessage
1144 * @return {boolean}
1145 */
1146 shouldBeVisible: function(viewMessage)
1147 {
1148 var message = viewMessage.consoleMessage();
1149 var executionContext = WebInspector.context.flavor(WebInspector.Executio nContext);
1150 if (!message.target())
1151 return true;
1152
1153 if (!this._view._showAllMessagesCheckbox.checked() && executionContext) {
1154 if (message.target() !== executionContext.target())
1155 return false;
1156 if (message.executionContextId && message.executionContextId !== ex ecutionContext.id) {
1157 return false;
1158 }
1159 }
1160
1161 if (WebInspector.moduleSetting("hideNetworkMessages").get() && viewMessa ge.consoleMessage().source === WebInspector.ConsoleMessage.MessageSource.Network )
1162 return false;
1163
1164 if (viewMessage.consoleMessage().isGroupMessage())
1165 return true;
1166
1167 if (message.type === WebInspector.ConsoleMessage.MessageType.Result || m essage.type === WebInspector.ConsoleMessage.MessageType.Command)
1168 return true;
1169
1170 if (message.url && this._messageURLFilters[message.url])
1171 return false;
1172
1173 if (message.level && !this._levelFilterUI.accept(message.level))
1174 return false;
1175
1176 if (this._filterRegex) {
1177 this._filterRegex.lastIndex = 0;
1178 if (!viewMessage.matchesFilterRegex(this._filterRegex))
1179 return false;
1180 }
1181
1182 return true;
1183 },
1184
1185 reset: function()
1186 {
1187 this._messageURLFilters = {};
1188 this._messageURLFiltersSetting.set(this._messageURLFilters);
1189 this._messageLevelFiltersSetting.set({});
1190 this._view._showAllMessagesCheckbox.inputElement.checked = true;
1191 WebInspector.moduleSetting("hideNetworkMessages").set(false);
1192 this._textFilterUI.setValue("");
1193 this._filterChanged();
1194 },
1195
1196 __proto__: WebInspector.Object.prototype
1197 }; 1223 };
1198 1224
1199
1200 /** 1225 /**
1201 * @constructor
1202 * @extends {WebInspector.ConsoleViewMessage}
1203 * @param {!WebInspector.ConsoleMessage} message
1204 * @param {!WebInspector.Linkifier} linkifier
1205 * @param {number} nestingLevel
1206 */
1207 WebInspector.ConsoleCommand = function(message, linkifier, nestingLevel)
1208 {
1209 WebInspector.ConsoleViewMessage.call(this, message, linkifier, nestingLevel) ;
1210 };
1211
1212 WebInspector.ConsoleCommand.prototype = {
1213 /**
1214 * @override
1215 * @return {!Element}
1216 */
1217 contentElement: function()
1218 {
1219 if (!this._contentElement) {
1220 this._contentElement = createElementWithClass("div", "console-user-c ommand");
1221 this._contentElement.message = this;
1222
1223 this._formattedCommand = createElementWithClass("span", "console-mes sage-text source-code");
1224 this._formattedCommand.textContent = this.text.replaceControlCharact ers();
1225 this._contentElement.appendChild(this._formattedCommand);
1226
1227 if (this._formattedCommand.textContent.length < WebInspector.Console Command.MaxLengthToIgnoreHighlighter) {
1228 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHigh lighter("text/javascript", true);
1229 javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedC ommand).then(this._updateSearch.bind(this));
1230 } else {
1231 this._updateSearch();
1232 }
1233 }
1234 return this._contentElement;
1235 },
1236
1237 _updateSearch: function()
1238 {
1239 this.setSearchRegex(this.searchRegex());
1240 },
1241
1242 __proto__: WebInspector.ConsoleViewMessage.prototype
1243 };
1244
1245 /**
1246 * The maximum length before strings are considered too long for syntax highligh ting. 1226 * The maximum length before strings are considered too long for syntax highligh ting.
1247 * @const 1227 * @const
1248 * @type {number} 1228 * @type {number}
1249 */ 1229 */
1250 WebInspector.ConsoleCommand.MaxLengthToIgnoreHighlighter = 10000; 1230 WebInspector.ConsoleCommand.MaxLengthToIgnoreHighlighter = 10000;
1251 1231
1252 /** 1232 /**
1253 * @constructor 1233 * @unrestricted
1254 * @extends {WebInspector.ConsoleViewMessage}
1255 * @param {!WebInspector.ConsoleMessage} message
1256 * @param {!WebInspector.Linkifier} linkifier
1257 * @param {number} nestingLevel
1258 */ 1234 */
1259 WebInspector.ConsoleCommandResult = function(message, linkifier, nestingLevel) 1235 WebInspector.ConsoleCommandResult = class extends WebInspector.ConsoleViewMessag e {
1260 { 1236 /**
1261 WebInspector.ConsoleViewMessage.call(this, message, linkifier, nestingLevel) ; 1237 * @param {!WebInspector.ConsoleMessage} message
1262 }; 1238 * @param {!WebInspector.Linkifier} linkifier
1239 * @param {number} nestingLevel
1240 */
1241 constructor(message, linkifier, nestingLevel) {
1242 super(message, linkifier, nestingLevel);
1243 }
1263 1244
1264 WebInspector.ConsoleCommandResult.prototype = { 1245 /**
1265 /** 1246 * @override
1266 * @override 1247 * @return {!Element}
1267 * @return {!Element} 1248 */
1268 */ 1249 contentElement() {
1269 contentElement: function() 1250 var element = super.contentElement();
1270 { 1251 element.classList.add('console-user-command-result');
1271 var element = WebInspector.ConsoleViewMessage.prototype.contentElement.c all(this); 1252 this.updateTimestamp(false);
1272 element.classList.add("console-user-command-result"); 1253 return element;
1273 this.updateTimestamp(false); 1254 }
1274 return element;
1275 },
1276
1277 __proto__: WebInspector.ConsoleViewMessage.prototype
1278 }; 1255 };
1279 1256
1280 /** 1257 /**
1281 * @constructor 1258 * @unrestricted
1282 * @param {?WebInspector.ConsoleGroup} parentGroup
1283 * @param {?WebInspector.ConsoleViewMessage} groupMessage
1284 */ 1259 */
1285 WebInspector.ConsoleGroup = function(parentGroup, groupMessage) 1260 WebInspector.ConsoleGroup = class {
1286 { 1261 /**
1262 * @param {?WebInspector.ConsoleGroup} parentGroup
1263 * @param {?WebInspector.ConsoleViewMessage} groupMessage
1264 */
1265 constructor(parentGroup, groupMessage) {
1287 this._parentGroup = parentGroup; 1266 this._parentGroup = parentGroup;
1288 this._nestingLevel = parentGroup ? parentGroup.nestingLevel() + 1 : 0; 1267 this._nestingLevel = parentGroup ? parentGroup.nestingLevel() + 1 : 0;
1289 this._messagesHidden = groupMessage && groupMessage.collapsed() || this._par entGroup && this._parentGroup.messagesHidden(); 1268 this._messagesHidden =
1269 groupMessage && groupMessage.collapsed() || this._parentGroup && this._p arentGroup.messagesHidden();
1270 }
1271
1272 /**
1273 * @return {!WebInspector.ConsoleGroup}
1274 */
1275 static createTopGroup() {
1276 return new WebInspector.ConsoleGroup(null, null);
1277 }
1278
1279 /**
1280 * @return {boolean}
1281 */
1282 messagesHidden() {
1283 return this._messagesHidden;
1284 }
1285
1286 /**
1287 * @return {number}
1288 */
1289 nestingLevel() {
1290 return this._nestingLevel;
1291 }
1292
1293 /**
1294 * @return {?WebInspector.ConsoleGroup}
1295 */
1296 parentGroup() {
1297 return this._parentGroup || this;
1298 }
1299 };
1300
1301
1302 /**
1303 * @implements {WebInspector.ActionDelegate}
1304 * @unrestricted
1305 */
1306 WebInspector.ConsoleView.ActionDelegate = class {
1307 /**
1308 * @override
1309 * @param {!WebInspector.Context} context
1310 * @param {string} actionId
1311 * @return {boolean}
1312 */
1313 handleAction(context, actionId) {
1314 switch (actionId) {
1315 case 'console.show':
1316 WebInspector.console.show();
1317 return true;
1318 case 'console.clear':
1319 WebInspector.ConsoleView.clearConsole();
1320 return true;
1321 case 'console.clear.history':
1322 WebInspector.ConsoleView.instance()._clearHistory();
1323 return true;
1324 }
1325 return false;
1326 }
1290 }; 1327 };
1291 1328
1292 /** 1329 /**
1293 * @return {!WebInspector.ConsoleGroup} 1330 * @typedef {{messageIndex: number, matchIndex: number}}
1294 */ 1331 */
1295 WebInspector.ConsoleGroup.createTopGroup = function()
1296 {
1297 return new WebInspector.ConsoleGroup(null, null);
1298 };
1299
1300 WebInspector.ConsoleGroup.prototype = {
1301 /**
1302 * @return {boolean}
1303 */
1304 messagesHidden: function()
1305 {
1306 return this._messagesHidden;
1307 },
1308
1309 /**
1310 * @return {number}
1311 */
1312 nestingLevel: function()
1313 {
1314 return this._nestingLevel;
1315 },
1316
1317 /**
1318 * @return {?WebInspector.ConsoleGroup}
1319 */
1320 parentGroup: function()
1321 {
1322 return this._parentGroup || this;
1323 },
1324 };
1325
1326 /**
1327 * @return {!WebInspector.ConsoleView}
1328 */
1329 WebInspector.ConsoleView.instance = function()
1330 {
1331 if (!WebInspector.ConsoleView._instance)
1332 WebInspector.ConsoleView._instance = new WebInspector.ConsoleView();
1333 return WebInspector.ConsoleView._instance;
1334 };
1335
1336 WebInspector.ConsoleView.clearConsole = function()
1337 {
1338 for (var target of WebInspector.targetManager.targets()) {
1339 target.runtimeModel.discardConsoleEntries();
1340 target.consoleModel.requestClearMessages();
1341 }
1342 };
1343
1344 /**
1345 * @constructor
1346 * @implements {WebInspector.ActionDelegate}
1347 */
1348 WebInspector.ConsoleView.ActionDelegate = function()
1349 {
1350 };
1351
1352 WebInspector.ConsoleView.ActionDelegate.prototype = {
1353 /**
1354 * @override
1355 * @param {!WebInspector.Context} context
1356 * @param {string} actionId
1357 * @return {boolean}
1358 */
1359 handleAction: function(context, actionId)
1360 {
1361 switch (actionId) {
1362 case "console.show":
1363 WebInspector.console.show();
1364 return true;
1365 case "console.clear":
1366 WebInspector.ConsoleView.clearConsole();
1367 return true;
1368 case "console.clear.history":
1369 WebInspector.ConsoleView.instance()._clearHistory();
1370 return true;
1371 }
1372 return false;
1373 }
1374 };
1375
1376 /**
1377 * @typedef {{messageIndex: number, matchIndex: number}}
1378 */
1379 WebInspector.ConsoleView.RegexMatchRange; 1332 WebInspector.ConsoleView.RegexMatchRange;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698