Web Inspector: [Canvas] show replay log grouped by draw calls
authoraandrey@chromium.org <aandrey@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 15:56:51 +0000 (15:56 +0000)
committeraandrey@chromium.org <aandrey@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 15:56:51 +0000 (15:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109592

Reviewed by Pavel Feldman.

Source/WebCore:

Show canvas capturing log grouped by drawing calls.
Drive-by: extended Array.prototype with a handy peekLast function.
Drive-by: removed code dups in few places.
* inspector/front-end/CanvasProfileView.js:
(WebInspector.CanvasProfileView):
(WebInspector.CanvasProfileView.prototype.dispose):
(WebInspector.CanvasProfileView.prototype._onReplayStepClick):
(WebInspector.CanvasProfileView.prototype._onReplayDrawingCallClick):
(WebInspector.CanvasProfileView.prototype._onReplayLastStepClick):
(WebInspector.CanvasProfileView.prototype._replayTraceLog.didReplayTraceLog):
(WebInspector.CanvasProfileView.prototype._replayTraceLog):
(WebInspector.CanvasProfileView.prototype._didReceiveTraceLog):
(WebInspector.CanvasProfileView.prototype._selectedCallIndex):
(WebInspector.CanvasProfileView.prototype._selectedDrawCallGroupIndex):
(WebInspector.CanvasProfileView.prototype._appendCallNode):
* inspector/front-end/DataGrid.js:
(WebInspector.DataGrid.prototype.setColumnVisible):
(WebInspector.DataGridNode.prototype.set hasChildren):
(WebInspector.DataGridNode.prototype.set revealed):
(WebInspector.DataGridNode.prototype.get leftPadding):
* inspector/front-end/externs.js:
(Array.prototype.peekLast):
* inspector/front-end/utilities.js:

LayoutTests:

A test to dump canvas replay log.

* inspector/profiler/canvas2d/canvas-replay-log-grid-expected.txt: Added.
* inspector/profiler/canvas2d/canvas-replay-log-grid.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143000 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid-expected.txt [new file with mode: 0644]
LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid.html [new file with mode: 0644]
LayoutTests/platform/efl/TestExpectations
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/qt/TestExpectations
LayoutTests/platform/win/TestExpectations
LayoutTests/platform/wincairo/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/inspector/front-end/CanvasProfileView.js
Source/WebCore/inspector/front-end/DataGrid.js
Source/WebCore/inspector/front-end/externs.js
Source/WebCore/inspector/front-end/utilities.js

index 80f2386..b14181d 100644 (file)
@@ -1,3 +1,15 @@
+2013-02-15  Andrey Adaikin  <aandrey@chromium.org>
+
+        Web Inspector: [Canvas] show replay log grouped by draw calls
+        https://bugs.webkit.org/show_bug.cgi?id=109592
+
+        Reviewed by Pavel Feldman.
+
+        A test to dump canvas replay log.
+
+        * inspector/profiler/canvas2d/canvas-replay-log-grid-expected.txt: Added.
+        * inspector/profiler/canvas2d/canvas-replay-log-grid.html: Added.
+
 2013-02-15  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: Pass original selection to textModel to correctly restore it after undo.
diff --git a/LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid-expected.txt b/LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid-expected.txt
new file mode 100644 (file)
index 0000000..bade10c
--- /dev/null
@@ -0,0 +1,25 @@
+Tests replay log grid.
+
+Bug 109592 
+
+   |         Draw call group #1 |                                | 
+ 1 |                beginPath() | canvas-replay-log-grid.html:26 | 
+ 2 |       rect(0, 0, 100, 100) | canvas-replay-log-grid.html:27 | 
+ 3 |    context.fillStyle = red | canvas-replay-log-grid.html:28 | 
+ 4 |                     fill() | canvas-replay-log-grid.html:29 | 
+   |         Draw call group #2 |                                | 
+ 5 |                beginPath() | canvas-replay-log-grid.html:26 | 
+ 6 |         rect(5, 5, 95, 95) | canvas-replay-log-grid.html:27 | 
+ 7 |  context.fillStyle = green | canvas-replay-log-grid.html:28 | 
+ 8 |                     fill() | canvas-replay-log-grid.html:29 | 
+   |         Draw call group #3 |                                | 
+ 9 |                beginPath() | canvas-replay-log-grid.html:26 | 
+10 |       rect(10, 10, 90, 90) | canvas-replay-log-grid.html:27 | 
+11 |   context.fillStyle = blue | canvas-replay-log-grid.html:28 | 
+12 |                     fill() | canvas-replay-log-grid.html:29 | 
+   |         Draw call group #4 |                                | 
+13 |                beginPath() | canvas-replay-log-grid.html:26 | 
+14 |       rect(15, 15, 85, 85) | canvas-replay-log-grid.html:27 | 
+15 | context.fillStyle = yellow | canvas-replay-log-grid.html:28 | 
+16 |                     fill() | canvas-replay-log-grid.html:29 | 
+
diff --git a/LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid.html b/LayoutTests/inspector/profiler/canvas2d/canvas-replay-log-grid.html
new file mode 100644 (file)
index 0000000..5cf117a
--- /dev/null
@@ -0,0 +1,128 @@
+<html>
+<head>
+    <script src="../../../http/tests/inspector/inspector-test.js"></script>
+    <script src="../canvas-profiler-test.js"></script>
+<script>
+
+var canvas;
+var context;
+var round = 0;
+var colors = ["red", "green", "blue", "yellow", "black"];
+
+function createCanvasContext()
+{
+    canvas = document.getElementById("canvas");
+    context = canvas.getContext("2d");
+    console.assert(context, "Failed to create a canvas context");
+}
+
+function doSomeCanvasCalls(repeats)
+{
+    if (!context)
+        createCanvasContext();
+    repeats = repeats || 1;
+    while (repeats-- > 0) {
+        var offset = 5 * round;
+        context.beginPath();
+        context.rect(offset, offset, 100 - offset, 100 - offset);
+        context.fillStyle = colors[round % colors.length];
+        context.fill();
+        ++round;
+    }
+}
+
+function test()
+{
+    // FIXME: Remove once taken out of experiments.
+    WebInspector.experimentsSettings.canvasInspection = {};
+    WebInspector.experimentsSettings.canvasInspection.isEnabled = function() { return true; };
+
+    WebInspector.showPanel("profiles");
+    var profilesPanel = WebInspector.panels.profiles;
+    var profileType = profilesPanel.getProfileType(WebInspector.CanvasProfileType.TypeId);
+    profilesPanel._onProfileTypeSelected({data: profileType});
+
+    InspectorTest.addSniffer(profileType, "_didStartCapturingFrame", didStartCapturingFrame);
+    profilesPanel.toggleRecordButton();
+
+    var traceLogId;
+    var profileHeader;
+    function didStartCapturingFrame(profilesPanel, frameId, error, traceLogId)
+    {
+        profileHeader = profilesPanel.getProfiles(WebInspector.CanvasProfileType.TypeId)[0];
+        traceLogId = profileHeader.traceLogId();
+        profilesPanel.showProfile(profileHeader);
+        InspectorTest.evaluateInConsole("doSomeCanvasCalls(4)", didSomeCanvasCalls);
+    }
+    function didSomeCanvasCalls()
+    {
+        InspectorTest.addSniffer(profileHeader, "_updateCapturingStatus", onUpdateCapturingStatus);
+        profilesPanel.toggleRecordButton();
+    }
+    function onUpdateCapturingStatus()
+    {
+        if (profileHeader._alive) {
+            InspectorTest.addSniffer(profileHeader, "_updateCapturingStatus", onUpdateCapturingStatus);
+            return;
+        }
+
+        var profileView = profilesPanel.visibleView;
+        var dataGrid = profileView._logGrid;
+        dataGrid.rootNode().expandRecursively();
+
+        dumpTableData(dataGrid.element);
+        InspectorTest.completeTest();
+    }
+    function dumpTableData(tableElement)
+    {
+        var textRows = [];
+        var textWidths = [];
+        var rows = tableElement.getElementsByTagName("tr");
+        for (var i = 0, row; row = rows[i]; ++i) {
+            if (!row.offsetHeight || !row.textContent)
+                continue;
+            var textCols = [];
+            var cols = row.getElementsByTagName("td");
+            for (var j = 0, col; col = cols[j]; ++j) {
+                if (!col.offsetHeight)
+                    continue;
+                var index = textCols.length;
+                var text = col.textContent;
+                textWidths[index] = Math.max(textWidths[index] || 0, text.length);
+                textCols[index] = text;
+            }
+            textRows.push(textCols);
+        }
+
+        function alignText(text, width)
+        {
+            var result = "";
+            var spaces = width - text.length;
+            while (spaces-- > 0)
+                result += " ";
+            result += text;
+            return result;
+        }
+
+        for (var i = 0; i < textRows.length; ++i) {
+            var line = "";
+            for (var j = 0; j < textRows[i].length; ++j) {
+                if (j)
+                    line += " | ";
+                line += alignText(textRows[i][j], textWidths[j]);
+            }
+            InspectorTest.addResult(line);
+        }
+    }
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<p>
+Tests replay log grid.
+</p>
+<a href="https://bugs.webkit.org/show_bug.cgi?id=109592">Bug 109592</a>
+<canvas id="canvas"></canvas>
+</body>
+</html>
index de32872..b572830 100644 (file)
@@ -1608,6 +1608,7 @@ webkit.org/b/23166 ietestcenter/css3/bordersbackgrounds/border-radius-clip-002.h
 webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html
 
 # EFL port does not support Emacs commands.
 Bug(EFL) editing/pasteboard/emacs-cntl-y-001.html [ Missing ]
index 9902d57..719289b 100644 (file)
@@ -1039,6 +1039,7 @@ webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html [ Failu
 
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html [ Failure ]
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html [ Failure ]
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html [ Failure ]
 
 webkit.org/b/37613 webkit.org/b/20011 printing [ Skip ]
 webkit.org/b/37613 editing/execCommand/print.html [ Skip ]
index 99b78e1..b5f6011 100644 (file)
@@ -288,6 +288,7 @@ webkit.org/b/50485 inspector-protocol/heap-profiler [ Skip ]
 webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html
 
 # Skipping newly added tests while I'm finding out what is wrong.
 # https://bugs.webkit.org/show_bug.cgi?id=59706
index e42788c..0847a48 100644 (file)
@@ -2506,6 +2506,7 @@ webkit.org/b/99893 svg/animations/mozilla/animateMotion-mpath-targetChange-1.svg
 webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html
 
 # [Qt] Unidentified pixel failures
 webkit.org/b/99306 animations/additive-transform-animations.html [ ImageOnlyFailure ]
index c0317d2..23d3282 100644 (file)
@@ -1313,6 +1313,7 @@ webkit.org/b/50485 inspector-protocol/heap-profiler [ Skip ]
 webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html
 
 # https://bugs.webkit.org/show_bug.cgi?id=40300
 inspector/debugger/live-edit.html
index 7313af2..69a61fa 100644 (file)
@@ -1831,6 +1831,7 @@ inspector/profiler/heap-snapshot-summary-sorting-instances.html
 webkit.org/b/99001 inspector/profiler/memory-instrumentation-canvas.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-has-uninstrumented-canvases.html
 webkit.org/b/73936 inspector/profiler/canvas2d/canvas-stack-trace.html
+webkit.org/b/73936 inspector/profiler/canvas2d/canvas-replay-log-grid.html
 
 # https://bugs.webkit.org/show_bug.cgi?id=40300
 inspector/debugger/live-edit.html
index 758cf82..3ac819c 100644 (file)
@@ -1,3 +1,35 @@
+2013-02-15  Andrey Adaikin  <aandrey@chromium.org>
+
+        Web Inspector: [Canvas] show replay log grouped by draw calls
+        https://bugs.webkit.org/show_bug.cgi?id=109592
+
+        Reviewed by Pavel Feldman.
+
+        Show canvas capturing log grouped by drawing calls.
+        Drive-by: extended Array.prototype with a handy peekLast function.
+        Drive-by: removed code dups in few places.
+
+        * inspector/front-end/CanvasProfileView.js:
+        (WebInspector.CanvasProfileView):
+        (WebInspector.CanvasProfileView.prototype.dispose):
+        (WebInspector.CanvasProfileView.prototype._onReplayStepClick):
+        (WebInspector.CanvasProfileView.prototype._onReplayDrawingCallClick):
+        (WebInspector.CanvasProfileView.prototype._onReplayLastStepClick):
+        (WebInspector.CanvasProfileView.prototype._replayTraceLog.didReplayTraceLog):
+        (WebInspector.CanvasProfileView.prototype._replayTraceLog):
+        (WebInspector.CanvasProfileView.prototype._didReceiveTraceLog):
+        (WebInspector.CanvasProfileView.prototype._selectedCallIndex):
+        (WebInspector.CanvasProfileView.prototype._selectedDrawCallGroupIndex):
+        (WebInspector.CanvasProfileView.prototype._appendCallNode):
+        * inspector/front-end/DataGrid.js:
+        (WebInspector.DataGrid.prototype.setColumnVisible):
+        (WebInspector.DataGridNode.prototype.set hasChildren):
+        (WebInspector.DataGridNode.prototype.set revealed):
+        (WebInspector.DataGridNode.prototype.get leftPadding):
+        * inspector/front-end/externs.js:
+        (Array.prototype.peekLast):
+        * inspector/front-end/utilities.js:
+
 2013-02-15  Yury Semikhatsky  <yurys@chromium.org>
 
         Web Inspector: highlight record revealed in Timeline
index e17afed..3d96f74 100644 (file)
@@ -76,6 +76,7 @@ WebInspector.CanvasProfileView = function(profile)
     columns[1].title = WebInspector.UIString("Call");
     columns[1].sortable = true;
     columns[1].width = "75%";
+    columns[1].disclosure = true;
     columns[2].title = WebInspector.UIString("Location");
     columns[2].sortable = true;
     columns[2].width = "20%";
@@ -87,6 +88,8 @@ WebInspector.CanvasProfileView = function(profile)
 
     /** @type {!Array.<WebInspector.DataGridNode>} */
     this._logGridNodes = [];
+    /** @type {!Array.<WebInspector.DataGridNode>} */
+    this._drawCallGroups = [];
 
     this._splitView.show(this.element);
     this._requestTraceLog();
@@ -102,6 +105,7 @@ WebInspector.CanvasProfileView.prototype = {
     dispose: function()
     {
         this._logGridNodes = [];
+        this._drawCallGroupNodes = [];
         this._linkifier.reset();
     },
 
@@ -174,14 +178,11 @@ WebInspector.CanvasProfileView.prototype = {
      */
     _onReplayStepClick: function(forward)
     {
-        var selectedNode = this._logGrid.selectedNode;
-        if (!selectedNode)
+        var index = this._selectedCallIndex();
+        if (index === -1)
             return;
-        var nextNode = forward ? selectedNode.traverseNextNode(false) : selectedNode.traversePreviousNode(false);
-        if (nextNode)
-            nextNode.revealAndSelect();
-        else
-            selectedNode.reveal();
+        var nextNode = this._logGridNodes[forward ? index + 1 : index - 1] || this._logGridNodes[index];
+        nextNode.revealAndSelect();
     },
 
     /**
@@ -189,19 +190,11 @@ WebInspector.CanvasProfileView.prototype = {
      */
     _onReplayDrawingCallClick: function(forward)
     {
-        var callNode = this._logGrid.selectedNode;
-        if (!callNode)
+        var index = this._selectedDrawCallGroupIndex();
+        if (index === -1)
             return;
-        var index = callNode.index;
-        do {
-            var nextIndex = forward ? index + 1 : index - 1;
-            var nextCallNode = this._logGridNodes[nextIndex];
-            if (!nextCallNode)
-                break;
-            index = nextIndex;
-            callNode = nextCallNode;
-        } while (!callNode.call.isDrawingCall);
-        callNode.revealAndSelect();
+        var nextNode = this._drawCallGroups[forward ? index + 1 : index - 1] || this._drawCallGroups[index];
+        nextNode.revealAndSelect();
     },
 
     _onReplayFirstStepClick: function()
@@ -213,8 +206,7 @@ WebInspector.CanvasProfileView.prototype = {
 
     _onReplayLastStepClick: function()
     {
-        var children = this._logGrid.rootNode().children;
-        var lastNode = children[children.length - 1];
+        var lastNode = this._logGrid.rootNode().children.peekLast();
         if (lastNode)
             lastNode.revealAndSelect();
     },
@@ -245,9 +237,10 @@ WebInspector.CanvasProfileView.prototype = {
 
     _replayTraceLog: function()
     {
-        var callNode = this._logGrid.selectedNode;
-        if (!callNode)
+        var index = this._selectedCallIndex();
+        if (index === -1 || index === this._lastReplayCallIndex)
             return;
+        this._lastReplayCallIndex = index;
         var time = Date.now();
         /**
          * @param {?Protocol.Error} error
@@ -255,7 +248,7 @@ WebInspector.CanvasProfileView.prototype = {
          */
         function didReplayTraceLog(error, resourceState)
         {
-            if (callNode !== this._logGrid.selectedNode)
+            if (index !== this._selectedCallIndex())
                 return;
 
             this._enableWaitIcon(false);
@@ -270,7 +263,7 @@ WebInspector.CanvasProfileView.prototype = {
             this._onReplayContextChanged();
         }
         this._enableWaitIcon(true);
-        CanvasAgent.replayTraceLog(this._traceLogId, callNode.index, didReplayTraceLog.bind(this));
+        CanvasAgent.replayTraceLog(this._traceLogId, index, didReplayTraceLog.bind(this));
     },
 
     /**
@@ -282,21 +275,18 @@ WebInspector.CanvasProfileView.prototype = {
         this._enableWaitIcon(false);
         if (error || !traceLog)
             return;
-        var lastNode = null;
         var calls = traceLog.calls;
         for (var i = 0, n = calls.length; i < n; ++i) {
             var call = calls[i];
             this._requestReplayContextInfo(call.contextId);
             var index = traceLog.startOffset + i;
             var gridNode = this._createCallNode(index, call);
-            this._logGrid.rootNode().appendChild(gridNode);
-            lastNode = gridNode;
+            this._appendCallNode(gridNode);
         }
-        if (lastNode)
-            lastNode.revealAndSelect();
         if (traceLog.alive)
             setTimeout(this._requestTraceLog.bind(this), WebInspector.CanvasProfileView.TraceLogPollingInterval);
         this._profile._updateCapturingStatus(traceLog);
+        this._onReplayLastStepClick(); // Automatically replay the last step.
     },
 
     _requestTraceLog: function()
@@ -329,6 +319,62 @@ WebInspector.CanvasProfileView.prototype = {
     },
 
     /**
+     * @return {number}
+     */
+    _selectedCallIndex: function()
+    {
+        var node = this._logGrid.selectedNode;
+        while (node) {
+            if (typeof node.index === "number")
+                return node.index;
+            node = node.children.peekLast();
+        }
+        return -1;
+    },
+
+    /**
+     * @return {number}
+     */
+    _selectedDrawCallGroupIndex: function()
+    {
+        for (var node = this._logGrid.selectedNode; node; node = node.children.peekLast()) {
+            if (typeof node.drawCallGroupIndex === "number")
+                return node.drawCallGroupIndex;
+        }
+        for (var node = this._logGrid.selectedNode; node; node = node.parent) {
+            if (typeof node.drawCallGroupIndex === "number")
+                return node.drawCallGroupIndex;
+        }
+        return -1;
+    },
+
+    /**
+     * @param {!WebInspector.DataGridNode} gridNode
+     */
+    _appendCallNode: function(gridNode)
+    {
+        var drawCallGroup = this._drawCallGroups.peekLast();
+        if (drawCallGroup) {
+            var lastNode = drawCallGroup.children.peekLast();
+            if (lastNode && lastNode.call.isDrawingCall)
+                drawCallGroup = null;
+        }
+        if (!drawCallGroup) {
+            var index = this._drawCallGroups.length;
+            var data = {};
+            data[0] = "";
+            data[1] = "Draw call group #" + (index + 1);
+            data[2] = "";
+            drawCallGroup = new WebInspector.DataGridNode(data);
+            drawCallGroup.selectable = true;
+            drawCallGroup.drawCallGroupIndex = index;
+            this._drawCallGroups.push(drawCallGroup);
+            this._logGrid.rootNode().appendChild(drawCallGroup);
+        }
+        drawCallGroup.appendChild(gridNode);
+    },
+
+    /**
      * @param {number} index
      * @param {CanvasAgent.Call} call
      * @return {!WebInspector.DataGridNode}
index 0860eff..6675897 100644 (file)
@@ -628,10 +628,7 @@ WebInspector.DataGrid.prototype = {
             return;
 
         this.columns[columnIdentifier].hidden = !visible;
-        if (visible)
-            this.element.removeStyleClass("hide-" + columnIdentifier + "-column");
-        else
-            this.element.addStyleClass("hide-" + columnIdentifier + "-column");
+        this.element.enableStyleClass("hide-" + columnIdentifier + "-column", !visible);
     },
 
     get scrollContainer()
@@ -1149,17 +1146,8 @@ WebInspector.DataGridNode.prototype = {
         if (!this._element)
             return;
 
-        if (this._hasChildren)
-        {
-            this._element.addStyleClass("parent");
-            if (this.expanded)
-                this._element.addStyleClass("expanded");
-        }
-        else
-        {
-            this._element.removeStyleClass("parent");
-            this._element.removeStyleClass("expanded");
-        }
+        this._element.enableStyleClass("parent", this._hasChildren);
+        this._element.enableStyleClass("expanded", this._hasChildren && this.expanded);
     },
 
     get hasChildren()
@@ -1174,12 +1162,8 @@ WebInspector.DataGridNode.prototype = {
 
         this._revealed = x;
 
-        if (this._element) {
-            if (this._revealed)
-                this._element.addStyleClass("revealed");
-            else
-                this._element.removeStyleClass("revealed");
-        }
+        if (this._element)
+            this._element.enableStyleClass("revealed", this._revealed);
 
         for (var i = 0; i < this.children.length; ++i)
             this.children[i].revealed = x && this.expanded;
@@ -1198,7 +1182,7 @@ WebInspector.DataGridNode.prototype = {
 
     get leftPadding()
     {
-        if (typeof(this._leftPadding) === "number")
+        if (typeof this._leftPadding === "number")
             return this._leftPadding;
         
         this._leftPadding = this.depth * this.dataGrid.indentWidth;
@@ -1634,6 +1618,9 @@ WebInspector.DataGridNode.prototype = {
         return this.parent;
     },
 
+    /**
+     * @return {boolean}
+     */
     isEventWithinDisclosureTriangle: function(event)
     {
         if (!this.hasChildren)
index e6ef02f..a2b61c9 100644 (file)
@@ -129,6 +129,12 @@ Array.prototype.qselect = function(k, comparator) {}
  */
 Array.prototype.select = function(field) {}
 
+/**
+ * @this {Array.<*>}
+ * @return {*}
+ */
+Array.prototype.peekLast = function() {}
+
 DOMApplicationCache.prototype.UNCACHED = 0;
 DOMApplicationCache.prototype.IDLE = 1;
 DOMApplicationCache.prototype.CHECKING = 2;
index 871b924..890ca2e 100644 (file)
@@ -427,6 +427,18 @@ Object.defineProperty(Array.prototype, "select",
     }
 });
 
+Object.defineProperty(Array.prototype, "peekLast",
+{
+    /**
+     * @this {Array.<*>}
+     * @return {*}
+     */
+    value: function()
+    {
+        return this[this.length - 1];
+    }
+});
+
 /**
  * @param {*} anObject
  * @param {Array.<*>} aList