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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 10 *
11 * 2. Redistributions in binary form must reproduce the above 11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer 12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the 13 * in the documentation and/or other materials provided with the
14 * distribution. 14 * distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28
29 /** 28 /**
30 * @constructor 29 * @unrestricted
31 * @extends {WebInspector.SourceFrame}
32 * @param {!WebInspector.UISourceCode} uiSourceCode
33 */ 30 */
34 WebInspector.UISourceCodeFrame = function(uiSourceCode) 31 WebInspector.UISourceCodeFrame = class extends WebInspector.SourceFrame {
35 { 32 /**
36 WebInspector.SourceFrame.call(this, uiSourceCode.contentURL(), workingCopy); 33 * @param {!WebInspector.UISourceCode} uiSourceCode
34 */
35 constructor(uiSourceCode) {
36 super(uiSourceCode.contentURL(), workingCopy);
37 this._uiSourceCode = uiSourceCode; 37 this._uiSourceCode = uiSourceCode;
38 this.setEditable(this._canEditSource()); 38 this.setEditable(this._canEditSource());
39 39
40 if (Runtime.experiments.isEnabled("sourceDiff")) 40 if (Runtime.experiments.isEnabled('sourceDiff'))
41 this._diff = new WebInspector.SourceCodeDiff(uiSourceCode.requestOrigina lContent(), this.textEditor); 41 this._diff = new WebInspector.SourceCodeDiff(uiSourceCode.requestOriginalC ontent(), this.textEditor);
42 42
43 /** @type {?WebInspector.AutocompleteConfig} */ 43 /** @type {?WebInspector.AutocompleteConfig} */
44 this._autocompleteConfig = {isWordChar: WebInspector.TextUtils.isWordChar}; 44 this._autocompleteConfig = {isWordChar: WebInspector.TextUtils.isWordChar};
45 WebInspector.moduleSetting("textEditorAutocompletion").addChangeListener(thi s._updateAutocomplete, this); 45 WebInspector.moduleSetting('textEditorAutocompletion').addChangeListener(thi s._updateAutocomplete, this);
46 this._updateAutocomplete(); 46 this._updateAutocomplete();
47 47
48 this._rowMessageBuckets = {}; 48 this._rowMessageBuckets = {};
49 /** @type {!Set<string>} */ 49 /** @type {!Set<string>} */
50 this._typeDecorationsPending = new Set(); 50 this._typeDecorationsPending = new Set();
51 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Working CopyChanged, this._onWorkingCopyChanged, this); 51 this._uiSourceCode.addEventListener(
52 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Working CopyCommitted, this._onWorkingCopyCommitted, this); 52 WebInspector.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopy Changed, this);
53 this._uiSourceCode.addEventListener(
54 WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCo pyCommitted, this);
53 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Message Added, this._onMessageAdded, this); 55 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Message Added, this._onMessageAdded, this);
54 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Message Removed, this._onMessageRemoved, this); 56 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Message Removed, this._onMessageRemoved, this);
55 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDec orationAdded, this._onLineDecorationAdded, this); 57 this._uiSourceCode.addEventListener(
56 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.LineDec orationRemoved, this._onLineDecorationRemoved, this); 58 WebInspector.UISourceCode.Events.LineDecorationAdded, this._onLineDecora tionAdded, this);
57 WebInspector.persistence.addEventListener(WebInspector.Persistence.Events.Bi ndingCreated, this._onBindingChanged, this); 59 this._uiSourceCode.addEventListener(
58 WebInspector.persistence.addEventListener(WebInspector.Persistence.Events.Bi ndingRemoved, this._onBindingChanged, this); 60 WebInspector.UISourceCode.Events.LineDecorationRemoved, this._onLineDeco rationRemoved, this);
61 WebInspector.persistence.addEventListener(
62 WebInspector.Persistence.Events.BindingCreated, this._onBindingChanged, this);
63 WebInspector.persistence.addEventListener(
64 WebInspector.Persistence.Events.BindingRemoved, this._onBindingChanged, this);
59 65
60 this.textEditor.addEventListener(WebInspector.SourcesTextEditor.Events.Edito rBlurred, 66 this.textEditor.addEventListener(
67 WebInspector.SourcesTextEditor.Events.EditorBlurred,
61 () => WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, nul l)); 68 () => WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, nul l));
62 this.textEditor.addEventListener(WebInspector.SourcesTextEditor.Events.Edito rFocused, 69 this.textEditor.addEventListener(
70 WebInspector.SourcesTextEditor.Events.EditorFocused,
63 () => WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, thi s)); 71 () => WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, thi s));
64 72
65 this._updateStyle(); 73 this._updateStyle();
66 74
67 this._errorPopoverHelper = new WebInspector.PopoverHelper(this.element); 75 this._errorPopoverHelper = new WebInspector.PopoverHelper(this.element);
68 this._errorPopoverHelper.initializeCallbacks(this._getErrorAnchor.bind(this) , this._showErrorPopover.bind(this)); 76 this._errorPopoverHelper.initializeCallbacks(this._getErrorAnchor.bind(this) , this._showErrorPopover.bind(this));
69 77
70 this._errorPopoverHelper.setTimeout(100, 100); 78 this._errorPopoverHelper.setTimeout(100, 100);
71 79
72 /** 80 /**
73 * @return {!Promise<?string>} 81 * @return {!Promise<?string>}
74 */ 82 */
75 function workingCopy() 83 function workingCopy() {
76 { 84 if (uiSourceCode.isDirty())
77 if (uiSourceCode.isDirty()) 85 return /** @type {!Promise<?string>} */ (Promise.resolve(uiSourceCode.wo rkingCopy()));
78 return /** @type {!Promise<?string>} */(Promise.resolve(uiSourceCode .workingCopy())); 86 return uiSourceCode.requestContent();
79 return uiSourceCode.requestContent(); 87 }
80 } 88 }
89
90 /**
91 * @return {!WebInspector.UISourceCode}
92 */
93 uiSourceCode() {
94 return this._uiSourceCode;
95 }
96
97 /**
98 * @override
99 */
100 wasShown() {
101 super.wasShown();
102 this._boundWindowFocused = this._windowFocused.bind(this);
103 this.element.ownerDocument.defaultView.addEventListener('focus', this._bound WindowFocused, false);
104 this._checkContentUpdated();
105 // We need CodeMirrorTextEditor to be initialized prior to this call as it c alls |cursorPositionToCoordinates| internally. @see crbug.com/506566
106 setImmediate(this._updateBucketDecorations.bind(this));
107 }
108
109 /**
110 * @override
111 */
112 willHide() {
113 super.willHide();
114 WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, null);
115 this.element.ownerDocument.defaultView.removeEventListener('focus', this._bo undWindowFocused, false);
116 delete this._boundWindowFocused;
117 this._uiSourceCode.removeWorkingCopyGetter();
118 }
119
120 /**
121 * @return {boolean}
122 */
123 _canEditSource() {
124 if (WebInspector.persistence.binding(this._uiSourceCode))
125 return true;
126 var projectType = this._uiSourceCode.project().type();
127 if (projectType === WebInspector.projectTypes.Service || projectType === Web Inspector.projectTypes.Debugger ||
128 projectType === WebInspector.projectTypes.Formatter)
129 return false;
130 if (projectType === WebInspector.projectTypes.Network &&
131 this._uiSourceCode.contentType() === WebInspector.resourceTypes.Document )
132 return false;
133 return true;
134 }
135
136 _windowFocused(event) {
137 this._checkContentUpdated();
138 }
139
140 _checkContentUpdated() {
141 if (!this.loaded || !this.isShowing())
142 return;
143 this._uiSourceCode.checkContentUpdated(true);
144 }
145
146 commitEditing() {
147 if (!this._uiSourceCode.isDirty())
148 return;
149
150 this._muteSourceCodeEvents = true;
151 this._uiSourceCode.commitWorkingCopy();
152 delete this._muteSourceCodeEvents;
153 }
154
155 /**
156 * @override
157 */
158 onTextEditorContentSet() {
159 if (this._diff)
160 this._diff.updateDiffMarkersImmediately();
161 super.onTextEditorContentSet();
162 for (var message of this._uiSourceCode.messages())
163 this._addMessageToSource(message);
164 this._decorateAllTypes();
165 }
166
167 /**
168 * @override
169 * @param {!WebInspector.TextRange} oldRange
170 * @param {!WebInspector.TextRange} newRange
171 */
172 onTextChanged(oldRange, newRange) {
173 if (this._diff)
174 this._diff.updateDiffMarkersWhenPossible();
175 super.onTextChanged(oldRange, newRange);
176 this._clearMessages();
177 if (this._isSettingContent)
178 return;
179 this._muteSourceCodeEvents = true;
180 if (this._textEditor.isClean())
181 this._uiSourceCode.resetWorkingCopy();
182 else
183 this._uiSourceCode.setWorkingCopyGetter(this._textEditor.text.bind(this._t extEditor));
184 delete this._muteSourceCodeEvents;
185 }
186
187 /**
188 * @param {!WebInspector.Event} event
189 */
190 _onWorkingCopyChanged(event) {
191 if (this._muteSourceCodeEvents)
192 return;
193 this._innerSetContent(this._uiSourceCode.workingCopy());
194 this.onUISourceCodeContentChanged();
195 }
196
197 /**
198 * @param {!WebInspector.Event} event
199 */
200 _onWorkingCopyCommitted(event) {
201 if (!this._muteSourceCodeEvents) {
202 this._innerSetContent(this._uiSourceCode.workingCopy());
203 this.onUISourceCodeContentChanged();
204 }
205 this._textEditor.markClean();
206 this._updateStyle();
207 }
208
209 /**
210 * @param {!WebInspector.Event} event
211 */
212 _onBindingChanged(event) {
213 var binding = /** @type {!WebInspector.PersistenceBinding} */ (event.data);
214 if (binding.network === this._uiSourceCode || binding.fileSystem === this._u iSourceCode)
215 this._updateStyle();
216 }
217
218 _updateStyle() {
219 this.element.classList.toggle(
220 'source-frame-unsaved-committed-changes',
221 WebInspector.persistence.hasUnsavedCommittedChanges(this._uiSourceCode)) ;
222 this.setEditable(!this._canEditSource());
223 }
224
225 onUISourceCodeContentChanged() {
226 }
227
228 _updateAutocomplete() {
229 this._textEditor.configureAutocomplete(
230 WebInspector.moduleSetting('textEditorAutocompletion').get() ? this._aut ocompleteConfig : null);
231 }
232
233 /**
234 * @param {?WebInspector.AutocompleteConfig} config
235 */
236 configureAutocomplete(config) {
237 this._autocompleteConfig = config;
238 this._updateAutocomplete();
239 }
240
241 /**
242 * @param {string} content
243 */
244 _innerSetContent(content) {
245 this._isSettingContent = true;
246 if (this._diff) {
247 var oldContent = this._textEditor.text();
248 this.setContent(content);
249 this._diff.highlightModifiedLines(oldContent, content);
250 } else {
251 this.setContent(content);
252 }
253 delete this._isSettingContent;
254 }
255
256 /**
257 * @override
258 * @return {!Promise}
259 */
260 populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
261 /**
262 * @this {WebInspector.UISourceCodeFrame}
263 */
264 function appendItems() {
265 contextMenu.appendApplicableItems(this._uiSourceCode);
266 contextMenu.appendApplicableItems(new WebInspector.UILocation(this._uiSour ceCode, lineNumber, columnNumber));
267 contextMenu.appendApplicableItems(this);
268 }
269
270 return super.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumb er).then(appendItems.bind(this));
271 }
272
273 /**
274 * @param {!Array.<!WebInspector.Infobar|undefined>} infobars
275 */
276 attachInfobars(infobars) {
277 for (var i = infobars.length - 1; i >= 0; --i) {
278 var infobar = infobars[i];
279 if (!infobar)
280 continue;
281 this.element.insertBefore(infobar.element, this.element.children[0]);
282 infobar.setParentView(this);
283 }
284 this.doResize();
285 }
286
287 dispose() {
288 this._textEditor.dispose();
289 WebInspector.moduleSetting('textEditorAutocompletion').removeChangeListener( this._updateAutocomplete, this);
290 this.detach();
291 }
292
293 /**
294 * @param {!WebInspector.Event} event
295 */
296 _onMessageAdded(event) {
297 if (!this.loaded)
298 return;
299 var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.data) ;
300 this._addMessageToSource(message);
301 }
302
303 /**
304 * @param {!WebInspector.UISourceCode.Message} message
305 */
306 _addMessageToSource(message) {
307 var lineNumber = message.lineNumber();
308 if (lineNumber >= this._textEditor.linesCount)
309 lineNumber = this._textEditor.linesCount - 1;
310 if (lineNumber < 0)
311 lineNumber = 0;
312
313 if (!this._rowMessageBuckets[lineNumber])
314 this._rowMessageBuckets[lineNumber] =
315 new WebInspector.UISourceCodeFrame.RowMessageBucket(this, this._textEd itor, lineNumber);
316 var messageBucket = this._rowMessageBuckets[lineNumber];
317 messageBucket.addMessage(message);
318 }
319
320 /**
321 * @param {!WebInspector.Event} event
322 */
323 _onMessageRemoved(event) {
324 if (!this.loaded)
325 return;
326 var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.data) ;
327 this._removeMessageFromSource(message);
328 }
329
330 /**
331 * @param {!WebInspector.UISourceCode.Message} message
332 */
333 _removeMessageFromSource(message) {
334 var lineNumber = message.lineNumber();
335 if (lineNumber >= this._textEditor.linesCount)
336 lineNumber = this._textEditor.linesCount - 1;
337 if (lineNumber < 0)
338 lineNumber = 0;
339
340 var messageBucket = this._rowMessageBuckets[lineNumber];
341 if (!messageBucket)
342 return;
343 messageBucket.removeMessage(message);
344 if (!messageBucket.uniqueMessagesCount()) {
345 messageBucket.detachFromEditor();
346 delete this._rowMessageBuckets[lineNumber];
347 }
348 }
349
350 _clearMessages() {
351 for (var line in this._rowMessageBuckets) {
352 var bubble = this._rowMessageBuckets[line];
353 bubble.detachFromEditor();
354 }
355
356 this._rowMessageBuckets = {};
357 this._errorPopoverHelper.hidePopover();
358 this._uiSourceCode.removeAllMessages();
359 }
360
361 /**
362 * @param {!Element} target
363 * @param {!Event} event
364 * @return {(!Element|undefined)}
365 */
366 _getErrorAnchor(target, event) {
367 var element = target.enclosingNodeOrSelfWithClass('text-editor-line-decorati on-icon') ||
368 target.enclosingNodeOrSelfWithClass('text-editor-line-decoration-wave');
369 if (!element)
370 return;
371 this._errorWavePopoverAnchor = new AnchorBox(event.clientX, event.clientY, 1 , 1);
372 return element;
373 }
374
375 /**
376 * @param {!Element} anchor
377 * @param {!WebInspector.Popover} popover
378 */
379 _showErrorPopover(anchor, popover) {
380 var messageBucket = anchor.enclosingNodeOrSelfWithClass('text-editor-line-de coration')._messageBucket;
381 var messagesOutline = messageBucket.messagesDescription();
382 var popoverAnchor =
383 anchor.enclosingNodeOrSelfWithClass('text-editor-line-decoration-icon') ? anchor : this._errorWavePopoverAnchor;
384 popover.showForAnchor(messagesOutline, popoverAnchor);
385 }
386
387 _updateBucketDecorations() {
388 for (var line in this._rowMessageBuckets) {
389 var bucket = this._rowMessageBuckets[line];
390 bucket._updateDecoration();
391 }
392 }
393
394 /**
395 * @param {!WebInspector.Event} event
396 */
397 _onLineDecorationAdded(event) {
398 var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event.dat a);
399 this._decorateTypeThrottled(marker.type());
400 }
401
402 /**
403 * @param {!WebInspector.Event} event
404 */
405 _onLineDecorationRemoved(event) {
406 var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event.dat a);
407 this._decorateTypeThrottled(marker.type());
408 }
409
410 /**
411 * @param {string} type
412 */
413 _decorateTypeThrottled(type) {
414 if (this._typeDecorationsPending.has(type))
415 return;
416 this._typeDecorationsPending.add(type);
417 self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator)
418 .find(extension => extension.descriptor()['decoratorType'] === type)
419 .instance()
420 .then(decorator => {
421 this._typeDecorationsPending.delete(type);
422 decorator.decorate(this.uiSourceCode(), this._textEditor);
423 });
424 }
425
426 _decorateAllTypes() {
427 var extensions = self.runtime.extensions(WebInspector.UISourceCodeFrame.Line Decorator);
428 extensions.forEach(extension => this._decorateTypeThrottled(extension.descri ptor()['decoratorType']));
429 }
81 }; 430 };
82 431
83 WebInspector.UISourceCodeFrame.prototype = {
84 /**
85 * @return {!WebInspector.UISourceCode}
86 */
87 uiSourceCode: function()
88 {
89 return this._uiSourceCode;
90 },
91
92 wasShown: function()
93 {
94 WebInspector.SourceFrame.prototype.wasShown.call(this);
95 this._boundWindowFocused = this._windowFocused.bind(this);
96 this.element.ownerDocument.defaultView.addEventListener("focus", this._b oundWindowFocused, false);
97 this._checkContentUpdated();
98 // We need CodeMirrorTextEditor to be initialized prior to this call as it calls |cursorPositionToCoordinates| internally. @see crbug.com/506566
99 setImmediate(this._updateBucketDecorations.bind(this));
100 },
101
102 willHide: function()
103 {
104 WebInspector.SourceFrame.prototype.willHide.call(this);
105 WebInspector.context.setFlavor(WebInspector.UISourceCodeFrame, null);
106 this.element.ownerDocument.defaultView.removeEventListener("focus", this ._boundWindowFocused, false);
107 delete this._boundWindowFocused;
108 this._uiSourceCode.removeWorkingCopyGetter();
109 },
110
111 /**
112 * @return {boolean}
113 */
114 _canEditSource: function()
115 {
116 if (WebInspector.persistence.binding(this._uiSourceCode))
117 return true;
118 var projectType = this._uiSourceCode.project().type();
119 if (projectType === WebInspector.projectTypes.Service || projectType === WebInspector.projectTypes.Debugger || projectType === WebInspector.projectTypes .Formatter)
120 return false;
121 if (projectType === WebInspector.projectTypes.Network && this._uiSourceC ode.contentType() === WebInspector.resourceTypes.Document)
122 return false;
123 return true;
124 },
125
126 _windowFocused: function(event)
127 {
128 this._checkContentUpdated();
129 },
130
131 _checkContentUpdated: function()
132 {
133 if (!this.loaded || !this.isShowing())
134 return;
135 this._uiSourceCode.checkContentUpdated(true);
136 },
137
138 commitEditing: function()
139 {
140 if (!this._uiSourceCode.isDirty())
141 return;
142
143 this._muteSourceCodeEvents = true;
144 this._uiSourceCode.commitWorkingCopy();
145 delete this._muteSourceCodeEvents;
146 },
147
148 /**
149 * @override
150 */
151 onTextEditorContentSet: function()
152 {
153 if (this._diff)
154 this._diff.updateDiffMarkersImmediately();
155 WebInspector.SourceFrame.prototype.onTextEditorContentSet.call(this);
156 for (var message of this._uiSourceCode.messages())
157 this._addMessageToSource(message);
158 this._decorateAllTypes();
159 },
160
161 /**
162 * @override
163 * @param {!WebInspector.TextRange} oldRange
164 * @param {!WebInspector.TextRange} newRange
165 */
166 onTextChanged: function(oldRange, newRange)
167 {
168 if (this._diff)
169 this._diff.updateDiffMarkersWhenPossible();
170 WebInspector.SourceFrame.prototype.onTextChanged.call(this, oldRange, ne wRange);
171 this._clearMessages();
172 if (this._isSettingContent)
173 return;
174 this._muteSourceCodeEvents = true;
175 if (this._textEditor.isClean())
176 this._uiSourceCode.resetWorkingCopy();
177 else
178 this._uiSourceCode.setWorkingCopyGetter(this._textEditor.text.bind(t his._textEditor));
179 delete this._muteSourceCodeEvents;
180 },
181
182 /**
183 * @param {!WebInspector.Event} event
184 */
185 _onWorkingCopyChanged: function(event)
186 {
187 if (this._muteSourceCodeEvents)
188 return;
189 this._innerSetContent(this._uiSourceCode.workingCopy());
190 this.onUISourceCodeContentChanged();
191 },
192
193 /**
194 * @param {!WebInspector.Event} event
195 */
196 _onWorkingCopyCommitted: function(event)
197 {
198 if (!this._muteSourceCodeEvents) {
199 this._innerSetContent(this._uiSourceCode.workingCopy());
200 this.onUISourceCodeContentChanged();
201 }
202 this._textEditor.markClean();
203 this._updateStyle();
204 },
205
206 /**
207 * @param {!WebInspector.Event} event
208 */
209 _onBindingChanged: function(event)
210 {
211 var binding = /** @type {!WebInspector.PersistenceBinding} */(event.data );
212 if (binding.network === this._uiSourceCode || binding.fileSystem === thi s._uiSourceCode)
213 this._updateStyle();
214 },
215
216 _updateStyle: function()
217 {
218 this.element.classList.toggle("source-frame-unsaved-committed-changes", WebInspector.persistence.hasUnsavedCommittedChanges(this._uiSourceCode));
219 this.setEditable(!this._canEditSource());
220 },
221
222 onUISourceCodeContentChanged: function()
223 {
224 },
225
226 _updateAutocomplete: function()
227 {
228 this._textEditor.configureAutocomplete(WebInspector.moduleSetting("textE ditorAutocompletion").get() ? this._autocompleteConfig : null);
229 },
230
231 /**
232 * @param {?WebInspector.AutocompleteConfig} config
233 */
234 configureAutocomplete: function(config)
235 {
236 this._autocompleteConfig = config;
237 this._updateAutocomplete();
238 },
239
240 /**
241 * @param {string} content
242 */
243 _innerSetContent: function(content)
244 {
245 this._isSettingContent = true;
246 if (this._diff) {
247 var oldContent = this._textEditor.text();
248 this.setContent(content);
249 this._diff.highlightModifiedLines(oldContent, content);
250 } else {
251 this.setContent(content);
252 }
253 delete this._isSettingContent;
254 },
255
256 /**
257 * @override
258 * @return {!Promise}
259 */
260 populateTextAreaContextMenu: function(contextMenu, lineNumber, columnNumber)
261 {
262 /**
263 * @this {WebInspector.UISourceCodeFrame}
264 */
265 function appendItems()
266 {
267 contextMenu.appendApplicableItems(this._uiSourceCode);
268 contextMenu.appendApplicableItems(new WebInspector.UILocation(this._ uiSourceCode, lineNumber, columnNumber));
269 contextMenu.appendApplicableItems(this);
270 }
271
272 return WebInspector.SourceFrame.prototype.populateTextAreaContextMenu.ca ll(this, contextMenu, lineNumber, columnNumber)
273 .then(appendItems.bind(this));
274 },
275
276 /**
277 * @param {!Array.<!WebInspector.Infobar|undefined>} infobars
278 */
279 attachInfobars: function(infobars)
280 {
281 for (var i = infobars.length - 1; i >= 0; --i) {
282 var infobar = infobars[i];
283 if (!infobar)
284 continue;
285 this.element.insertBefore(infobar.element, this.element.children[0]) ;
286 infobar.setParentView(this);
287 }
288 this.doResize();
289 },
290
291 dispose: function()
292 {
293 this._textEditor.dispose();
294 WebInspector.moduleSetting("textEditorAutocompletion").removeChangeListe ner(this._updateAutocomplete, this);
295 this.detach();
296 },
297
298 /**
299 * @param {!WebInspector.Event} event
300 */
301 _onMessageAdded: function(event)
302 {
303 if (!this.loaded)
304 return;
305 var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.d ata);
306 this._addMessageToSource(message);
307 },
308
309 /**
310 * @param {!WebInspector.UISourceCode.Message} message
311 */
312 _addMessageToSource: function(message)
313 {
314 var lineNumber = message.lineNumber();
315 if (lineNumber >= this._textEditor.linesCount)
316 lineNumber = this._textEditor.linesCount - 1;
317 if (lineNumber < 0)
318 lineNumber = 0;
319
320 if (!this._rowMessageBuckets[lineNumber])
321 this._rowMessageBuckets[lineNumber] = new WebInspector.UISourceCodeF rame.RowMessageBucket(this, this._textEditor, lineNumber);
322 var messageBucket = this._rowMessageBuckets[lineNumber];
323 messageBucket.addMessage(message);
324 },
325
326 /**
327 * @param {!WebInspector.Event} event
328 */
329 _onMessageRemoved: function(event)
330 {
331 if (!this.loaded)
332 return;
333 var message = /** @type {!WebInspector.UISourceCode.Message} */ (event.d ata);
334 this._removeMessageFromSource(message);
335 },
336
337 /**
338 * @param {!WebInspector.UISourceCode.Message} message
339 */
340 _removeMessageFromSource: function(message)
341 {
342 var lineNumber = message.lineNumber();
343 if (lineNumber >= this._textEditor.linesCount)
344 lineNumber = this._textEditor.linesCount - 1;
345 if (lineNumber < 0)
346 lineNumber = 0;
347
348 var messageBucket = this._rowMessageBuckets[lineNumber];
349 if (!messageBucket)
350 return;
351 messageBucket.removeMessage(message);
352 if (!messageBucket.uniqueMessagesCount()) {
353 messageBucket.detachFromEditor();
354 delete this._rowMessageBuckets[lineNumber];
355 }
356 },
357
358 _clearMessages: function()
359 {
360 for (var line in this._rowMessageBuckets) {
361 var bubble = this._rowMessageBuckets[line];
362 bubble.detachFromEditor();
363 }
364
365 this._rowMessageBuckets = {};
366 this._errorPopoverHelper.hidePopover();
367 this._uiSourceCode.removeAllMessages();
368 },
369
370 /**
371 * @param {!Element} target
372 * @param {!Event} event
373 * @return {(!Element|undefined)}
374 */
375 _getErrorAnchor: function(target, event)
376 {
377 var element = target.enclosingNodeOrSelfWithClass("text-editor-line-deco ration-icon")
378 || target.enclosingNodeOrSelfWithClass("text-editor-line-decoration- wave");
379 if (!element)
380 return;
381 this._errorWavePopoverAnchor = new AnchorBox(event.clientX, event.client Y, 1, 1);
382 return element;
383 },
384
385 /**
386 * @param {!Element} anchor
387 * @param {!WebInspector.Popover} popover
388 */
389 _showErrorPopover: function(anchor, popover)
390 {
391 var messageBucket = anchor.enclosingNodeOrSelfWithClass("text-editor-lin e-decoration")._messageBucket;
392 var messagesOutline = messageBucket.messagesDescription();
393 var popoverAnchor = anchor.enclosingNodeOrSelfWithClass("text-editor-lin e-decoration-icon") ? anchor : this._errorWavePopoverAnchor;
394 popover.showForAnchor(messagesOutline, popoverAnchor);
395 },
396
397 _updateBucketDecorations: function()
398 {
399 for (var line in this._rowMessageBuckets) {
400 var bucket = this._rowMessageBuckets[line];
401 bucket._updateDecoration();
402 }
403 },
404
405 /**
406 * @param {!WebInspector.Event} event
407 */
408 _onLineDecorationAdded: function(event)
409 {
410 var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event .data);
411 this._decorateTypeThrottled(marker.type());
412 },
413
414 /**
415 * @param {!WebInspector.Event} event
416 */
417 _onLineDecorationRemoved: function(event)
418 {
419 var marker = /** @type {!WebInspector.UISourceCode.LineMarker} */ (event .data);
420 this._decorateTypeThrottled(marker.type());
421 },
422
423 /**
424 * @param {string} type
425 */
426 _decorateTypeThrottled: function(type)
427 {
428 if (this._typeDecorationsPending.has(type))
429 return;
430 this._typeDecorationsPending.add(type);
431 self.runtime.extensions(WebInspector.UISourceCodeFrame.LineDecorator).fi nd(extension => extension.descriptor()["decoratorType"] === type).instance().the n(decorator => {
432 this._typeDecorationsPending.delete(type);
433 decorator.decorate(this.uiSourceCode(), this._textEditor);
434 });
435 },
436
437 _decorateAllTypes: function()
438 {
439 var extensions = self.runtime.extensions(WebInspector.UISourceCodeFrame. LineDecorator);
440 extensions.forEach(extension => this._decorateTypeThrottled(extension.de scriptor()["decoratorType"]));
441 },
442
443 __proto__: WebInspector.SourceFrame.prototype
444 };
445
446 WebInspector.UISourceCodeFrame._iconClassPerLevel = {}; 432 WebInspector.UISourceCodeFrame._iconClassPerLevel = {};
447 WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Error] = "error-icon"; 433 WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Error] = 'error-icon';
448 WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Warning] = "warning-icon"; 434 WebInspector.UISourceCodeFrame._iconClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Warning] = 'warning-icon';
449 435
450 WebInspector.UISourceCodeFrame._bubbleTypePerLevel = {}; 436 WebInspector.UISourceCodeFrame._bubbleTypePerLevel = {};
451 WebInspector.UISourceCodeFrame._bubbleTypePerLevel[WebInspector.UISourceCode.Mes sage.Level.Error] = "error"; 437 WebInspector.UISourceCodeFrame._bubbleTypePerLevel[WebInspector.UISourceCode.Mes sage.Level.Error] = 'error';
452 WebInspector.UISourceCodeFrame._bubbleTypePerLevel[WebInspector.UISourceCode.Mes sage.Level.Warning] = "warning"; 438 WebInspector.UISourceCodeFrame._bubbleTypePerLevel[WebInspector.UISourceCode.Mes sage.Level.Warning] = 'warning';
453 439
454 WebInspector.UISourceCodeFrame._lineClassPerLevel = {}; 440 WebInspector.UISourceCodeFrame._lineClassPerLevel = {};
455 WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Error] = "text-editor-line-with-error"; 441 WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Error] =
456 WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Warning] = "text-editor-line-with-warning"; 442 'text-editor-line-with-error';
443 WebInspector.UISourceCodeFrame._lineClassPerLevel[WebInspector.UISourceCode.Mess age.Level.Warning] =
444 'text-editor-line-with-warning';
457 445
458 /** 446 /**
459 * @interface 447 * @interface
460 */ 448 */
461 WebInspector.UISourceCodeFrame.LineDecorator = function() { }; 449 WebInspector.UISourceCodeFrame.LineDecorator = function() {};
462 450
463 WebInspector.UISourceCodeFrame.LineDecorator.prototype = { 451 WebInspector.UISourceCodeFrame.LineDecorator.prototype = {
464 /** 452 /**
465 * @param {!WebInspector.UISourceCode} uiSourceCode 453 * @param {!WebInspector.UISourceCode} uiSourceCode
466 * @param {!WebInspector.CodeMirrorTextEditor} textEditor 454 * @param {!WebInspector.CodeMirrorTextEditor} textEditor
467 */ 455 */
468 decorate: function(uiSourceCode, textEditor) { } 456 decorate: function(uiSourceCode, textEditor) {}
469 }; 457 };
470 458
471 /** 459 /**
472 * @constructor 460 * @unrestricted
473 * @param {!WebInspector.UISourceCode.Message} message
474 */ 461 */
475 WebInspector.UISourceCodeFrame.RowMessage = function(message) 462 WebInspector.UISourceCodeFrame.RowMessage = class {
476 { 463 /**
464 * @param {!WebInspector.UISourceCode.Message} message
465 */
466 constructor(message) {
477 this._message = message; 467 this._message = message;
478 this._repeatCount = 1; 468 this._repeatCount = 1;
479 this.element = createElementWithClass("div", "text-editor-row-message"); 469 this.element = createElementWithClass('div', 'text-editor-row-message');
480 this._icon = this.element.createChild("label", "", "dt-icon-label"); 470 this._icon = this.element.createChild('label', '', 'dt-icon-label');
481 this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[message. level()]; 471 this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[message. level()];
482 this._repeatCountElement = this.element.createChild("label", "message-repeat -count hidden", "dt-small-bubble"); 472 this._repeatCountElement = this.element.createChild('label', 'message-repeat -count hidden', 'dt-small-bubble');
483 this._repeatCountElement.type = WebInspector.UISourceCodeFrame._bubbleTypePe rLevel[message.level()]; 473 this._repeatCountElement.type = WebInspector.UISourceCodeFrame._bubbleTypePe rLevel[message.level()];
484 var linesContainer = this.element.createChild("div", "text-editor-row-messag e-lines"); 474 var linesContainer = this.element.createChild('div', 'text-editor-row-messag e-lines');
485 var lines = this._message.text().split("\n"); 475 var lines = this._message.text().split('\n');
486 for (var i = 0; i < lines.length; ++i) { 476 for (var i = 0; i < lines.length; ++i) {
487 var messageLine = linesContainer.createChild("div"); 477 var messageLine = linesContainer.createChild('div');
488 messageLine.textContent = lines[i]; 478 messageLine.textContent = lines[i];
489 } 479 }
480 }
481
482 /**
483 * @return {!WebInspector.UISourceCode.Message}
484 */
485 message() {
486 return this._message;
487 }
488
489 /**
490 * @return {number}
491 */
492 repeatCount() {
493 return this._repeatCount;
494 }
495
496 setRepeatCount(repeatCount) {
497 if (this._repeatCount === repeatCount)
498 return;
499 this._repeatCount = repeatCount;
500 this._updateMessageRepeatCount();
501 }
502
503 _updateMessageRepeatCount() {
504 this._repeatCountElement.textContent = this._repeatCount;
505 var showRepeatCount = this._repeatCount > 1;
506 this._repeatCountElement.classList.toggle('hidden', !showRepeatCount);
507 this._icon.classList.toggle('hidden', showRepeatCount);
508 }
490 }; 509 };
491 510
492 WebInspector.UISourceCodeFrame.RowMessage.prototype = {
493 /**
494 * @return {!WebInspector.UISourceCode.Message}
495 */
496 message: function()
497 {
498 return this._message;
499 },
500
501 /**
502 * @return {number}
503 */
504 repeatCount: function()
505 {
506 return this._repeatCount;
507 },
508
509 setRepeatCount: function(repeatCount)
510 {
511 if (this._repeatCount === repeatCount)
512 return;
513 this._repeatCount = repeatCount;
514 this._updateMessageRepeatCount();
515 },
516
517 _updateMessageRepeatCount: function()
518 {
519 this._repeatCountElement.textContent = this._repeatCount;
520 var showRepeatCount = this._repeatCount > 1;
521 this._repeatCountElement.classList.toggle("hidden", !showRepeatCount);
522 this._icon.classList.toggle("hidden", showRepeatCount);
523 }
524 };
525
526 /** 511 /**
527 * @constructor 512 * @unrestricted
528 * @param {!WebInspector.UISourceCodeFrame} sourceFrame
529 * @param {!WebInspector.CodeMirrorTextEditor} textEditor
530 * @param {number} lineNumber
531 */ 513 */
532 WebInspector.UISourceCodeFrame.RowMessageBucket = function(sourceFrame, textEdit or, lineNumber) 514 WebInspector.UISourceCodeFrame.RowMessageBucket = class {
533 { 515 /**
516 * @param {!WebInspector.UISourceCodeFrame} sourceFrame
517 * @param {!WebInspector.CodeMirrorTextEditor} textEditor
518 * @param {number} lineNumber
519 */
520 constructor(sourceFrame, textEditor, lineNumber) {
534 this._sourceFrame = sourceFrame; 521 this._sourceFrame = sourceFrame;
535 this._textEditor = textEditor; 522 this._textEditor = textEditor;
536 this._lineHandle = textEditor.textEditorPositionHandle(lineNumber, 0); 523 this._lineHandle = textEditor.textEditorPositionHandle(lineNumber, 0);
537 this._decoration = createElementWithClass("div", "text-editor-line-decoratio n"); 524 this._decoration = createElementWithClass('div', 'text-editor-line-decoratio n');
538 this._decoration._messageBucket = this; 525 this._decoration._messageBucket = this;
539 this._wave = this._decoration.createChild("div", "text-editor-line-decoratio n-wave"); 526 this._wave = this._decoration.createChild('div', 'text-editor-line-decoratio n-wave');
540 this._icon = this._wave.createChild("label", "text-editor-line-decoration-ic on", "dt-icon-label"); 527 this._icon = this._wave.createChild('label', 'text-editor-line-decoration-ic on', 'dt-icon-label');
541 this._hasDecoration = false; 528 this._hasDecoration = false;
542 529
543 this._messagesDescriptionElement = createElementWithClass("div", "text-edito r-messages-description-container"); 530 this._messagesDescriptionElement = createElementWithClass('div', 'text-edito r-messages-description-container');
544 /** @type {!Array.<!WebInspector.UISourceCodeFrame.RowMessage>} */ 531 /** @type {!Array.<!WebInspector.UISourceCodeFrame.RowMessage>} */
545 this._messages = []; 532 this._messages = [];
546 533
547 this._level = null; 534 this._level = null;
535 }
536
537 /**
538 * @param {number} lineNumber
539 * @param {number} columnNumber
540 */
541 _updateWavePosition(lineNumber, columnNumber) {
542 lineNumber = Math.min(lineNumber, this._textEditor.linesCount - 1);
543 var lineText = this._textEditor.line(lineNumber);
544 columnNumber = Math.min(columnNumber, lineText.length);
545 var lineIndent = WebInspector.TextUtils.lineIndent(lineText).length;
546 if (this._hasDecoration)
547 this._textEditor.removeDecoration(this._decoration, lineNumber);
548 this._hasDecoration = true;
549 this._textEditor.addDecoration(this._decoration, lineNumber, Math.max(column Number - 1, lineIndent));
550 }
551
552 /**
553 * @return {!Element}
554 */
555 messagesDescription() {
556 this._messagesDescriptionElement.removeChildren();
557 for (var i = 0; i < this._messages.length; ++i) {
558 this._messagesDescriptionElement.appendChild(this._messages[i].element);
559 }
560 return this._messagesDescriptionElement;
561 }
562
563 detachFromEditor() {
564 var position = this._lineHandle.resolve();
565 if (!position)
566 return;
567 var lineNumber = position.lineNumber;
568 if (this._level)
569 this._textEditor.toggleLineClass(
570 lineNumber, WebInspector.UISourceCodeFrame._lineClassPerLevel[this._le vel], false);
571 if (this._hasDecoration)
572 this._textEditor.removeDecoration(this._decoration, lineNumber);
573 this._hasDecoration = false;
574 }
575
576 /**
577 * @return {number}
578 */
579 uniqueMessagesCount() {
580 return this._messages.length;
581 }
582
583 /**
584 * @param {!WebInspector.UISourceCode.Message} message
585 */
586 addMessage(message) {
587 for (var i = 0; i < this._messages.length; ++i) {
588 var rowMessage = this._messages[i];
589 if (rowMessage.message().isEqual(message)) {
590 rowMessage.setRepeatCount(rowMessage.repeatCount() + 1);
591 return;
592 }
593 }
594
595 var rowMessage = new WebInspector.UISourceCodeFrame.RowMessage(message);
596 this._messages.push(rowMessage);
597 this._updateDecoration();
598 }
599
600 /**
601 * @param {!WebInspector.UISourceCode.Message} message
602 */
603 removeMessage(message) {
604 for (var i = 0; i < this._messages.length; ++i) {
605 var rowMessage = this._messages[i];
606 if (!rowMessage.message().isEqual(message))
607 continue;
608 rowMessage.setRepeatCount(rowMessage.repeatCount() - 1);
609 if (!rowMessage.repeatCount())
610 this._messages.splice(i, 1);
611 this._updateDecoration();
612 return;
613 }
614 }
615
616 _updateDecoration() {
617 if (!this._sourceFrame.isEditorShowing())
618 return;
619 if (!this._messages.length)
620 return;
621 var position = this._lineHandle.resolve();
622 if (!position)
623 return;
624
625 var lineNumber = position.lineNumber;
626 var columnNumber = Number.MAX_VALUE;
627 var maxMessage = null;
628 for (var i = 0; i < this._messages.length; ++i) {
629 var message = this._messages[i].message();
630 columnNumber = Math.min(columnNumber, message.columnNumber());
631 if (!maxMessage || WebInspector.UISourceCode.Message.messageLevelComparato r(maxMessage, message) < 0)
632 maxMessage = message;
633 }
634 this._updateWavePosition(lineNumber, columnNumber);
635
636 if (this._level) {
637 this._textEditor.toggleLineClass(
638 lineNumber, WebInspector.UISourceCodeFrame._lineClassPerLevel[this._le vel], false);
639 this._icon.type = '';
640 }
641 this._level = maxMessage.level();
642 if (!this._level)
643 return;
644 this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCodeFrame. _lineClassPerLevel[this._level], true);
645 this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[this._le vel];
646 }
548 }; 647 };
549 648
550 WebInspector.UISourceCodeFrame.RowMessageBucket.prototype = { 649 WebInspector.UISourceCode.Message._messageLevelPriority = {
551 /** 650 'Warning': 3,
552 * @param {number} lineNumber 651 'Error': 4
553 * @param {number} columnNumber
554 */
555 _updateWavePosition: function(lineNumber, columnNumber)
556 {
557 lineNumber = Math.min(lineNumber, this._textEditor.linesCount - 1);
558 var lineText = this._textEditor.line(lineNumber);
559 columnNumber = Math.min(columnNumber, lineText.length);
560 var lineIndent = WebInspector.TextUtils.lineIndent(lineText).length;
561 if (this._hasDecoration)
562 this._textEditor.removeDecoration(this._decoration, lineNumber);
563 this._hasDecoration = true;
564 this._textEditor.addDecoration(this._decoration, lineNumber, Math.max(co lumnNumber - 1, lineIndent));
565 },
566
567 /**
568 * @return {!Element}
569 */
570 messagesDescription: function()
571 {
572 this._messagesDescriptionElement.removeChildren();
573 for (var i = 0; i < this._messages.length; ++i) {
574 this._messagesDescriptionElement.appendChild(this._messages[i].eleme nt);
575 }
576 return this._messagesDescriptionElement;
577 },
578
579 detachFromEditor: function()
580 {
581 var position = this._lineHandle.resolve();
582 if (!position)
583 return;
584 var lineNumber = position.lineNumber;
585 if (this._level)
586 this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCo deFrame._lineClassPerLevel[this._level], false);
587 if (this._hasDecoration)
588 this._textEditor.removeDecoration(this._decoration, lineNumber);
589 this._hasDecoration = false;
590 },
591
592 /**
593 * @return {number}
594 */
595 uniqueMessagesCount: function()
596 {
597 return this._messages.length;
598 },
599
600 /**
601 * @param {!WebInspector.UISourceCode.Message} message
602 */
603 addMessage: function(message)
604 {
605 for (var i = 0; i < this._messages.length; ++i) {
606 var rowMessage = this._messages[i];
607 if (rowMessage.message().isEqual(message)) {
608 rowMessage.setRepeatCount(rowMessage.repeatCount() + 1);
609 return;
610 }
611 }
612
613 var rowMessage = new WebInspector.UISourceCodeFrame.RowMessage(message);
614 this._messages.push(rowMessage);
615 this._updateDecoration();
616 },
617
618 /**
619 * @param {!WebInspector.UISourceCode.Message} message
620 */
621 removeMessage: function(message)
622 {
623 for (var i = 0; i < this._messages.length; ++i) {
624 var rowMessage = this._messages[i];
625 if (!rowMessage.message().isEqual(message))
626 continue;
627 rowMessage.setRepeatCount(rowMessage.repeatCount() - 1);
628 if (!rowMessage.repeatCount())
629 this._messages.splice(i, 1);
630 this._updateDecoration();
631 return;
632 }
633 },
634
635 _updateDecoration: function()
636 {
637 if (!this._sourceFrame.isEditorShowing())
638 return;
639 if (!this._messages.length)
640 return;
641 var position = this._lineHandle.resolve();
642 if (!position)
643 return;
644
645 var lineNumber = position.lineNumber;
646 var columnNumber = Number.MAX_VALUE;
647 var maxMessage = null;
648 for (var i = 0; i < this._messages.length; ++i) {
649 var message = this._messages[i].message();
650 columnNumber = Math.min(columnNumber, message.columnNumber());
651 if (!maxMessage || WebInspector.UISourceCode.Message.messageLevelCom parator(maxMessage, message) < 0)
652 maxMessage = message;
653 }
654 this._updateWavePosition(lineNumber, columnNumber);
655
656 if (this._level) {
657 this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCo deFrame._lineClassPerLevel[this._level], false);
658 this._icon.type = "";
659 }
660 this._level = maxMessage.level();
661 if (!this._level)
662 return;
663 this._textEditor.toggleLineClass(lineNumber, WebInspector.UISourceCodeFr ame._lineClassPerLevel[this._level], true);
664 this._icon.type = WebInspector.UISourceCodeFrame._iconClassPerLevel[this ._level];
665 }
666 }; 652 };
667 653
668 WebInspector.UISourceCode.Message._messageLevelPriority = {
669 "Warning": 3,
670 "Error": 4
671 };
672
673 /** 654 /**
674 * @param {!WebInspector.UISourceCode.Message} a 655 * @param {!WebInspector.UISourceCode.Message} a
675 * @param {!WebInspector.UISourceCode.Message} b 656 * @param {!WebInspector.UISourceCode.Message} b
676 * @return {number} 657 * @return {number}
677 */ 658 */
678 WebInspector.UISourceCode.Message.messageLevelComparator = function(a, b) 659 WebInspector.UISourceCode.Message.messageLevelComparator = function(a, b) {
679 { 660 return WebInspector.UISourceCode.Message._messageLevelPriority[a.level()] -
680 return WebInspector.UISourceCode.Message._messageLevelPriority[a.level()] - WebInspector.UISourceCode.Message._messageLevelPriority[b.level()]; 661 WebInspector.UISourceCode.Message._messageLevelPriority[b.level()];
681 }; 662 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698