OLD | NEW |
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; |
OLD | NEW |