- 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)