DevTools: avoid slowdown from unnecessary DOM, style mutations on CodeMirrorTextEditor

Logging console messages that generate decorations (wavy underline under errors)
will cause a slowdown. UISourceCodeFrame's _updateDecorations() can remove and
re-add the same decoration or CSS class from a line, even if it did not change.

This CL avoids removing a decoration/class if the new one is the same.

BUG=651610

Review-Url: https://codereview.chromium.org/2820253002
Cr-Original-Commit-Position: refs/heads/master@{#467394}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: f677ae05d0b2e54b4876b3921a0dc1b9d66b4a21
diff --git a/front_end/source_frame/UISourceCodeFrame.js b/front_end/source_frame/UISourceCodeFrame.js
index 6e013ce..750c37b 100644
--- a/front_end/source_frame/UISourceCodeFrame.js
+++ b/front_end/source_frame/UISourceCodeFrame.js
@@ -568,7 +568,8 @@
     this._decoration._messageBucket = this;
     this._wave = this._decoration.createChild('div', 'text-editor-line-decoration-wave');
     this._icon = this._wave.createChild('label', 'text-editor-line-decoration-icon', 'dt-icon-label');
-    this._hasDecoration = false;
+    /** @type {?number} */
+    this._decorationStartColumn = null;
 
     this._messagesDescriptionElement = createElementWithClass('div', 'text-editor-messages-description-container');
     /** @type {!Array.<!SourceFrame.UISourceCodeFrame.RowMessage>} */
@@ -586,10 +587,13 @@
     var lineText = this.textEditor.line(lineNumber);
     columnNumber = Math.min(columnNumber, lineText.length);
     var lineIndent = TextUtils.TextUtils.lineIndent(lineText).length;
-    if (this._hasDecoration)
+    var startColumn = Math.max(columnNumber - 1, lineIndent);
+    if (this._decorationStartColumn === startColumn)
+      return;
+    if (this._decorationStartColumn !== null)
       this.textEditor.removeDecoration(this._decoration, lineNumber);
-    this._hasDecoration = true;
-    this.textEditor.addDecoration(this._decoration, lineNumber, Math.max(columnNumber - 1, lineIndent));
+    this.textEditor.addDecoration(this._decoration, lineNumber, startColumn);
+    this._decorationStartColumn = startColumn;
   }
 
   /**
@@ -611,9 +615,10 @@
     var lineNumber = position.lineNumber;
     if (this._level)
       this.textEditor.toggleLineClass(lineNumber, SourceFrame.UISourceCodeFrame._lineClassPerLevel[this._level], false);
-    if (this._hasDecoration)
+    if (this._decorationStartColumn !== null) {
       this.textEditor.removeDecoration(this._decoration, lineNumber);
-    this._hasDecoration = false;
+      this._decorationStartColumn = null;
+    }
   }
 
   /**
@@ -676,6 +681,8 @@
     }
     this._updateWavePosition(lineNumber, columnNumber);
 
+    if (this._level === maxMessage.level())
+      return;
     if (this._level) {
       this.textEditor.toggleLineClass(lineNumber, SourceFrame.UISourceCodeFrame._lineClassPerLevel[this._level], false);
       this._icon.type = '';