Title: [200337] trunk/Source/WebInspectorUI
Revision
200337
Author
[email protected]
Date
2016-05-02 14:01:08 -0700 (Mon, 02 May 2016)

Log Message

Web Inspector: Adding a new console message shouldn't modify DOM when the console log is hidden
https://bugs.webkit.org/show_bug.cgi?id=155629
<rdar://problem/25235470>

Reviewed by Timothy Hatcher.

Instead of rendering console messages right away, store them (in _pendingMessages)
and render only when the console tab or the split console is visible.
Also, batch rendering operations using requestAnimationFrame.

* UserInterface/Controllers/_javascript_LogViewController.js:
(WebInspector._javascript_LogViewController):
Store console message views in _pendingMessages.

(WebInspector._javascript_LogViewController.prototype._appendConsoleMessageView):
(WebInspector._javascript_LogViewController.prototype.renderPendingMessages):
Use requestAnimationFrame batching. Run isScrolledToBottom() at most only once
per batch.

(WebInspector._javascript_LogViewController.prototype.renderPendingMessagesSoon):
(WebInspector._javascript_LogViewController.prototype._didRenderConsoleMessageView):
There is no need to run scrollToBottom again.

* UserInterface/Views/ConsoleCommandView.js:
(WebInspector.ConsoleCommandView):
Move all DOM operations to a new render method.

(WebInspector.ConsoleCommandView.prototype.render):
* UserInterface/Views/ConsoleMessageView.js:
(WebInspector.ConsoleMessageView):
(WebInspector.ConsoleMessageView.prototype.render):
(WebInspector.ConsoleMessageView.prototype.set repeatCount):
(WebInspector.ConsoleMessageView.prototype._renderRepeatCount):
* UserInterface/Views/LogContentView.js:
(WebInspector.LogContentView.prototype.shown):
When the console tab or the split console is opened render all pending messages.

(WebInspector.LogContentView.prototype.didAppendConsoleMessageView):
No need to scrollToBottom once again.

(WebInspector.LogContentView.prototype._messageAdded):
(WebInspector.LogContentView.prototype._previousMessageRepeatCountUpdated):
(WebInspector.LogContentView.prototype._scopeFromMessageLevel): Deleted.
(WebInspector.LogContentView.prototype._markScopeBarItemUnread): Added.
Rename _pulseScopeBarItemBorder. In the very first version the border was pulsing,
but now we use small colored circles instead.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (200336 => 200337)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-05-02 20:32:25 UTC (rev 200336)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-05-02 21:01:08 UTC (rev 200337)
@@ -1,3 +1,52 @@
+2016-05-02  Nikita Vasilyev  <[email protected]>
+
+        Web Inspector: Adding a new console message shouldn't modify DOM when the console log is hidden
+        https://bugs.webkit.org/show_bug.cgi?id=155629
+        <rdar://problem/25235470>
+
+        Reviewed by Timothy Hatcher.
+
+        Instead of rendering console messages right away, store them (in _pendingMessages)
+        and render only when the console tab or the split console is visible.
+        Also, batch rendering operations using requestAnimationFrame.
+
+        * UserInterface/Controllers/_javascript_LogViewController.js:
+        (WebInspector._javascript_LogViewController):
+        Store console message views in _pendingMessages.
+
+        (WebInspector._javascript_LogViewController.prototype._appendConsoleMessageView):
+        (WebInspector._javascript_LogViewController.prototype.renderPendingMessages):
+        Use requestAnimationFrame batching. Run isScrolledToBottom() at most only once
+        per batch.
+
+        (WebInspector._javascript_LogViewController.prototype.renderPendingMessagesSoon):
+        (WebInspector._javascript_LogViewController.prototype._didRenderConsoleMessageView):
+        There is no need to run scrollToBottom again.
+
+        * UserInterface/Views/ConsoleCommandView.js:
+        (WebInspector.ConsoleCommandView):
+        Move all DOM operations to a new render method.
+
+        (WebInspector.ConsoleCommandView.prototype.render):
+        * UserInterface/Views/ConsoleMessageView.js:
+        (WebInspector.ConsoleMessageView):
+        (WebInspector.ConsoleMessageView.prototype.render):
+        (WebInspector.ConsoleMessageView.prototype.set repeatCount):
+        (WebInspector.ConsoleMessageView.prototype._renderRepeatCount):
+        * UserInterface/Views/LogContentView.js:
+        (WebInspector.LogContentView.prototype.shown):
+        When the console tab or the split console is opened render all pending messages.
+
+        (WebInspector.LogContentView.prototype.didAppendConsoleMessageView):
+        No need to scrollToBottom once again.
+
+        (WebInspector.LogContentView.prototype._messageAdded):
+        (WebInspector.LogContentView.prototype._previousMessageRepeatCountUpdated):
+        (WebInspector.LogContentView.prototype._scopeFromMessageLevel): Deleted.
+        (WebInspector.LogContentView.prototype._markScopeBarItemUnread): Added.
+        Rename _pulseScopeBarItemBorder. In the very first version the border was pulsing,
+        but now we use small colored circles instead.
+
 2016-05-02  Joseph Pecoraro  <[email protected]>
 
         Uncaught Exception: TypeError: null is not an object (evaluating 'sourceCodeLocation.formattedLineNumber')

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/_javascript_LogViewController.js (200336 => 200337)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/_javascript_LogViewController.js	2016-05-02 20:32:25 UTC (rev 200336)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/_javascript_LogViewController.js	2016-05-02 21:01:08 UTC (rev 200337)
@@ -60,6 +60,9 @@
         this._promptFindNextKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "G", this._handleFindNextShortcut.bind(this), this._prompt.element);
         this._promptFindPreviousKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl | WebInspector.KeyboardShortcut.Modifier.Shift, "G", this._handleFindPreviousShortcut.bind(this), this._prompt.element);
 
+        this._pendingMessages = [];
+        this._scheduledRenderIdentifier = 0;
+
         this.startNewSession();
     }
 
@@ -252,7 +255,7 @@
 
     _appendConsoleMessageView(messageView, repeatCountWasInterrupted)
     {
-        var wasScrolledToBottom = this.isScrolledToBottom();
+        this._pendingMessages.push(messageView);
 
         this._cleared = false;
         this._repeatCountWasInterrupted = repeatCountWasInterrupted || false;
@@ -263,6 +266,45 @@
         if (messageView.message && messageView.message.source !== WebInspector.ConsoleMessage.MessageSource.JS)
             this._lastCommitted = "";
 
+        if (WebInspector.consoleContentView.visible)
+            this.renderPendingMessagesSoon();
+    }
+
+    renderPendingMessages()
+    {
+        if (this._scheduledRenderIdentifier) {
+            cancelAnimationFrame(this._scheduledRenderIdentifier);
+            this._scheduledRenderIdentifier = 0;
+        }
+
+        if (this._pendingMessages.length === 0)
+            return;
+
+        let lastMessageView = this._pendingMessages.lastValue;
+        let isCommandView = lastMessageView instanceof WebInspector.ConsoleCommandView;
+        let shouldScrollToBottom = isCommandView || lastMessageView.message.type === WebInspector.ConsoleMessage.MessageType.Result || this.isScrolledToBottom();
+
+        for (let messageView of this._pendingMessages) {
+            messageView.render();
+            this._didRenderConsoleMessageView(messageView);
+        }
+
+        this._pendingMessages = [];
+
+        if (shouldScrollToBottom)
+            this.scrollToBottom();
+    }
+
+    renderPendingMessagesSoon()
+    {
+        if (this._scheduledRenderIdentifier)
+            return;
+
+        this._scheduledRenderIdentifier = requestAnimationFrame(() => this.renderPendingMessages());
+    }
+
+    _didRenderConsoleMessageView(messageView)
+    {
         var type = messageView instanceof WebInspector.ConsoleCommandView ? null : messageView.message.type;
         if (type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
             var parentGroup = this._currentConsoleGroup.parentGroup;
@@ -278,9 +320,6 @@
                 this._currentConsoleGroup.addMessageView(messageView);
         }
 
-        if (type === WebInspector.ConsoleMessage.MessageType.Result || wasScrolledToBottom)
-            this.scrollToBottom();
-
         if (this.delegate && typeof this.delegate.didAppendConsoleMessageView === "function")
             this.delegate.didAppendConsoleMessageView(messageView);
     }

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js (200336 => 200337)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js	2016-05-02 20:32:25 UTC (rev 200336)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js	2016-05-02 21:01:08 UTC (rev 200337)
@@ -34,13 +34,19 @@
         super();
 
         this._commandText = commandText;
+        this._className = className || "";
+    }
 
+    // Public
+
+    render()
+    {
         this._element = document.createElement("div");
         this._element.classList.add("console-user-command");
         this._element.setAttribute("data-labelprefix", WebInspector.UIString("Input: "));
 
-        if (className)
-            this._element.classList.add(className);
+        if (this._className)
+            this._element.classList.add(this._className);
 
         this._formattedCommandElement = this._element.appendChild(document.createElement("span"));
         this._formattedCommandElement.classList.add("console-message-text");
@@ -50,8 +56,6 @@
         this._element.__commandView = this;
     }
 
-    // Public
-
     get element()
     {
         return this._element;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageView.js (200336 => 200337)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageView.js	2016-05-02 20:32:25 UTC (rev 200336)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageView.js	2016-05-02 21:01:08 UTC (rev 200337)
@@ -37,9 +37,18 @@
         console.assert(message instanceof WebInspector.ConsoleMessage);
 
         this._message = message;
-
         this._expandable = false;
+        this._repeatCount = message._repeatCount || 0;
 
+        // These are the parameters unused by the messages's optional format string.
+        // Any extra parameters will be displayed as children of this message.
+        this._extraParameters = message.parameters;
+    }
+
+    // Public
+
+    render()
+    {
         this._element = document.createElement("div");
         this._element.classList.add("console-message");
 
@@ -76,10 +85,6 @@
             break;
         }
 
-        // These are the parameters unused by the messages's optional format string.
-        // Any extra parameters will be displayed as children of this message.
-        this._extraParameters = this._message.parameters;
-
         // FIXME: The location link should include stack trace information.
         this._appendLocationLink();
 
@@ -92,11 +97,9 @@
         this._appendExtraParameters();
         this._appendStackTrace();
 
-        this.repeatCount = this._message.repeatCount;
+        this._renderRepeatCount();
     }
 
-    // Public
-
     get element()
     {
         return this._element;
@@ -121,6 +124,14 @@
 
         this._repeatCount = count;
 
+        if (this._element)
+            this._renderRepeatCount();
+    }
+
+    _renderRepeatCount()
+    {
+        let count = this._repeatCount;
+
         if (count <= 1) {
             if (this._repeatCountElement) {
                 this._repeatCountElement.remove();

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js (200336 => 200337)


--- trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js	2016-05-02 20:32:25 UTC (rev 200336)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js	2016-05-02 21:01:08 UTC (rev 200337)
@@ -122,6 +122,11 @@
         return this.messagesElement.classList.contains(WebInspector.LogContentView.SearchInProgressStyleClassName);
     }
 
+    shown()
+    {
+        this._logViewController.renderPendingMessages();
+    }
+
     didAppendConsoleMessageView(messageView)
     {
         console.assert(messageView instanceof WebInspector.ConsoleMessageView || messageView instanceof WebInspector.ConsoleCommandView);
@@ -155,6 +160,14 @@
         // We want to remove focusable children after those pending dispatches too.
         InspectorBackend.runAfterPendingDispatches(this._clearFocusableChildren.bind(this));
 
+        if (type && type !== WebInspector.ConsoleMessage.MessageType.EndGroup) {
+            console.assert(messageView.message instanceof WebInspector.ConsoleMessage);
+            this._markScopeBarItemUnread(messageView.message.level);
+
+            console.assert(messageView.element instanceof Element);
+            this._filterMessageElements([messageView.element]);
+        }
+
         // We only auto show the console if the message is a non-synthetic result.
         // This is when the user evaluated something directly in the prompt.
         if (type !== WebInspector.ConsoleMessage.MessageType.Result || messageView.message.synthetic)
@@ -162,8 +175,6 @@
 
         if (!WebInspector.isShowingConsoleTab())
             WebInspector.showSplitConsole();
-
-        this._logViewController.scrollToBottom();
     }
 
     get supportsSearch()
@@ -309,7 +320,7 @@
         return messageLevel;
     }
 
-    _pulseScopeBarItemBorder(level)
+    _markScopeBarItemUnread(level)
     {
         var messageLevel = this._scopeFromMessageLevel(level);
 
@@ -327,17 +338,13 @@
         if (this._startedProvisionalLoad)
             this._provisionalMessages.push(event.data.message);
 
-        this._lastMessageView = this._logViewController.appendConsoleMessage(event.data.message);
-        if (this._lastMessageView.message.type !== WebInspector.ConsoleMessage.MessageType.EndGroup) {
-            this._pulseScopeBarItemBorder(this._lastMessageView.message.level);
-            this._filterMessageElements([this._lastMessageView.element]);
-        }
+        this._logViewController.appendConsoleMessage(event.data.message);
     }
 
     _previousMessageRepeatCountUpdated(event)
     {        
         if (this._logViewController.updatePreviousMessageRepeatCount(event.data.count) && this._lastMessageView)
-            this._pulseScopeBarItemBorder(this._lastMessageView.message.level);
+            this._markScopeBarItemUnread(this._lastMessageView.message.level);
     }
 
     _handleContextMenuEvent(event)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to