Title: [237777] trunk
Revision
237777
Author
[email protected]
Date
2018-11-03 16:24:35 -0700 (Sat, 03 Nov 2018)

Log Message

Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
https://bugs.webkit.org/show_bug.cgi?id=190854

Reviewed by Matt Baker.

Source/WebCore:

Updated existing tests: inspector/canvas/recording-2d.html
                        inspector/canvas/recording-bitmaprenderer.html
                        inspector/canvas/recording-webgl.html

* html/HTMLCanvasElement.idl:
Apply `CallTracingCallback=recordCanvasAction` to the `width` and `height` attributes so
that they are recorded through the same path as `CanvasRenderingContext`.

* html/CanvasBase.h:
* html/CanvasBase.cpp:
(WebCore::CanvasBase::callTracingActive const): Added.

* bindings/js/CallTracer.h:
* bindings/js/CallTracer.cpp:
(WebCore::CallTracer::recordCanvasAction):

Source/WebInspectorUI:

* UserInterface/Models/RecordingAction.js:
(WI.RecordingAction):
(WI.RecordingAction.isFunctionForType):
(WI.RecordingAction.constantNameForParameter):
(WI.RecordingAction.prototype.get contextReplacer): Added.
(WI.RecordingAction.prototype.async.swizzle):
(WI.RecordingAction.prototype.apply):
Create a constant list of actions for each recording type that need to replace the context
with a different value before being applied (e.g. `width` should be applied to the
`context`'s `canvas` instead of directly to the `context`).

* UserInterface/Views/RecordingContentView.js:
(WI.RecordingContentView.prototype._generateContentCanvas2D.actionModifiesPath): Added.
(WI.RecordingContentView.prototype._generateContentCanvas2D):
(WI.RecordingContentView._actionModifiesPath): Deleted.
Generate the path context after the actions are applied to the preview context so that the
final width/height are known and can be used. This is needed because changing the
width/height causes the content to be erased.

* UserInterface/Views/RecordingActionTreeElement.js:
(WI.RecordingActionTreeElement._generateDOM):
(WI.RecordingActionTreeElement._classNameForAction):
* UserInterface/Views/RecordingActionTreeElement.css:
(.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
(.item.action > .titles .context-replacer::after): Added.
(.item.action.has-context-replacer > .icon): Added.
(@media (prefers-dark-interface) .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
(.tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon): Deleted.
(@media (prefers-dark-interface) .item.action:not(.initial-state) > .icon): Deleted.
(@media (prefers-dark-interface) .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon): Deleted.
Add the context replacer text to the beginning of the action's name if it exists.

* UserInterface/Views/CanvasContentView.js:
(WI.CanvasContentView.prototype._refreshPixelSize):
(WI.CanvasContentView.prototype._updatePixelSize): Deleted.
Update preview image when the canvas' size changes.

LayoutTests:

* inspector/canvas/recording-2d-expected.txt:
* inspector/canvas/recording-2d.html:
* inspector/canvas/recording-bitmaprenderer-expected.txt:
* inspector/canvas/recording-bitmaprenderer.html:
* inspector/canvas/recording-webgl-expected.txt:
* inspector/canvas/recording-webgl.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237776 => 237777)


--- trunk/LayoutTests/ChangeLog	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/ChangeLog	2018-11-03 23:24:35 UTC (rev 237777)
@@ -1,3 +1,17 @@
+2018-11-03  Devin Rousso  <[email protected]>
+
+        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
+        https://bugs.webkit.org/show_bug.cgi?id=190854
+
+        Reviewed by Matt Baker.
+
+        * inspector/canvas/recording-2d-expected.txt:
+        * inspector/canvas/recording-2d.html:
+        * inspector/canvas/recording-bitmaprenderer-expected.txt:
+        * inspector/canvas/recording-bitmaprenderer.html:
+        * inspector/canvas/recording-webgl-expected.txt:
+        * inspector/canvas/recording-webgl.html:
+
 2018-11-03  Andy Estes  <[email protected]>
 
         [Payment Request] PaymentResponse.retry()'s errorFields should be optional

Modified: trunk/LayoutTests/inspector/canvas/recording-2d-expected.txt (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-2d-expected.txt	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-2d-expected.txt	2018-11-03 23:24:35 UTC (rev 237777)
@@ -1067,6 +1067,26 @@
       trace:
         0: (anonymous function)
         1: executeFrameFunction
+  73: (duration)
+    0: width
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: width = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+  74: (duration)
+    0: height
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: height = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
 
 -- Running test case: Canvas.recording2D.memoryLimit
 initialState:

Modified: trunk/LayoutTests/inspector/canvas/recording-2d.html (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-2d.html	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-2d.html	2018-11-03 23:24:35 UTC (rev 237777)
@@ -384,6 +384,14 @@
             ctx.webkitLineDashOffset = 1;
         },
         () => {
+            ctx.canvas.width;
+            ctx.canvas.width = 2;
+        },
+        () => {
+            ctx.canvas.height;
+            ctx.canvas.height = 2;
+        },
+        () => {
             TestPage.dispatchEventToFrontend("LastFrame");
         },
     ];

Modified: trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer-expected.txt (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer-expected.txt	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer-expected.txt	2018-11-03 23:24:35 UTC (rev 237777)
@@ -43,6 +43,26 @@
         5: (anonymous function)
         6: promiseReactionJob
       snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABNJREFUCB1j/M/AAEQMDEwgAgQAHxcCAmtAm/sAAAAASUVORK5CYII="
+  1: (duration)
+    0: width
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: width = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+  2: (duration)
+    0: height
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: height = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
 
 -- Running test case: Canvas.recordingBitmapRenderer.memoryLimit
 initialState:

Modified: trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html	2018-11-03 23:24:35 UTC (rev 237777)
@@ -53,6 +53,14 @@
             ctx.transferFromImageBitmap(redBitmap);
         },
         () => {
+            ctx.canvas.width;
+            ctx.canvas.width = 2;
+        },
+        () => {
+            ctx.canvas.height;
+            ctx.canvas.height = 2;
+        },
+        () => {
             TestPage.dispatchEventToFrontend("LastFrame");
         },
     ];

Modified: trunk/LayoutTests/inspector/canvas/recording-webgl-expected.txt (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-webgl-expected.txt	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-webgl-expected.txt	2018-11-03 23:24:35 UTC (rev 237777)
@@ -5,11 +5,11 @@
 -- Running test case: Canvas.recordingWebGL.singleFrame
 initialState:
   attributes:
-    width: 300
-    height: 150
+    width: 2
+    height: 2
   parameters:
     0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
-  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDB
 gwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
 frames:
   0: (duration)
     0: activeTexture(1)
@@ -27,11 +27,11 @@
 -- Running test case: Canvas.recordingWebGL.multipleFrames
 initialState:
   attributes:
-    width: 300
-    height: 150
+    width: 2
+    height: 2
   parameters:
     0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
-  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDB
 gwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
 frames:
   0: (duration)
     0: activeTexture(1)
@@ -156,7 +156,7 @@
         0: clear
         1: (anonymous function)
         2: executeFrameFunction
-      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAA
 QMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
   16: (duration)
     0: clearColor(1, 2, 3, 4)
       swizzleTypes: [Number, Number, Number, Number]
@@ -355,7 +355,7 @@
         0: drawArrays
         1: (anonymous function)
         2: executeFrameFunction
-      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAA
 QMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
   45: (duration)
     0: drawElements(1, 2, 3, 4)
       swizzleTypes: [Number, Number, Number, Number]
@@ -363,7 +363,7 @@
         0: drawElements
         1: (anonymous function)
         2: executeFrameFunction
-      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAA
 QMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
   46: (duration)
     0: enable(1)
       swizzleTypes: [Number]
@@ -1006,15 +1006,35 @@
         0: viewport
         1: (anonymous function)
         2: executeFrameFunction
+  137: (duration)
+    0: width
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: width = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+  138: (duration)
+    0: height
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: height = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
 
 -- Running test case: Canvas.recordingWebGL.memoryLimit
 initialState:
   attributes:
-    width: 300
-    height: 150
+    width: 2
+    height: 2
   parameters:
     0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
-  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDB
 gwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
+  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
 frames:
   0: (duration) (incomplete)
     0: activeTexture(1)

Modified: trunk/LayoutTests/inspector/canvas/recording-webgl.html (237776 => 237777)


--- trunk/LayoutTests/inspector/canvas/recording-webgl.html	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/LayoutTests/inspector/canvas/recording-webgl.html	2018-11-03 23:24:35 UTC (rev 237777)
@@ -39,6 +39,9 @@
     createProgram("webgl");
     linkProgram("vertex-shader", "fragment-shader");
 
+    context.canvas.width = 2;
+    context.canvas.height = 2;
+
     buffer = context.createBuffer();
     framebuffer = context.createFramebuffer();
     uniformLocation = context.getUniformLocation(program, "test");
@@ -484,6 +487,14 @@
             context.viewport(1, 2, 3, 4);
         },
         () => {
+            context.canvas.width;
+            context.canvas.width = 2;
+        },
+        () => {
+            context.canvas.height;
+            context.canvas.height = 2;
+        },
+        () => {
             TestPage.dispatchEventToFrontend("LastFrame");
         },
     ];

Modified: trunk/Source/WebCore/ChangeLog (237776 => 237777)


--- trunk/Source/WebCore/ChangeLog	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/ChangeLog	2018-11-03 23:24:35 UTC (rev 237777)
@@ -1,3 +1,27 @@
+2018-11-03  Devin Rousso  <[email protected]>
+
+        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
+        https://bugs.webkit.org/show_bug.cgi?id=190854
+
+        Reviewed by Matt Baker.
+
+        Updated existing tests: inspector/canvas/recording-2d.html
+                                inspector/canvas/recording-bitmaprenderer.html
+                                inspector/canvas/recording-webgl.html
+
+        * html/HTMLCanvasElement.idl:
+        Apply `CallTracingCallback=recordCanvasAction` to the `width` and `height` attributes so
+        that they are recorded through the same path as `CanvasRenderingContext`.
+
+        * html/CanvasBase.h:
+        * html/CanvasBase.cpp:
+        (WebCore::CanvasBase::callTracingActive const): Added.
+
+        * bindings/js/CallTracer.h:
+        * bindings/js/CallTracer.cpp:
+        (WebCore::CallTracer::recordCanvasAction):
+
+
 2018-11-03  Andy Estes  <[email protected]>
 
         [Payment Request] PaymentResponse.retry()'s errorFields should be optional

Modified: trunk/Source/WebCore/bindings/js/CallTracer.cpp (237776 => 237777)


--- trunk/Source/WebCore/bindings/js/CallTracer.cpp	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/bindings/js/CallTracer.cpp	2018-11-03 23:24:35 UTC (rev 237777)
@@ -27,10 +27,17 @@
 #include "CallTracer.h"
 
 #include "CanvasRenderingContext.h"
+#include "HTMLCanvasElement.h"
 #include "InspectorInstrumentation.h"
 
 namespace WebCore {
 
+void CallTracer::recordCanvasAction(const HTMLCanvasElement& canvasElement, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
+{
+    if (auto* canvasRenderingContext = canvasElement.renderingContext())
+        InspectorInstrumentation::recordCanvasAction(*canvasRenderingContext, name, WTFMove(parameters));
+}
+
 void CallTracer::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
     InspectorInstrumentation::recordCanvasAction(canvasRenderingContext, name, WTFMove(parameters));

Modified: trunk/Source/WebCore/bindings/js/CallTracer.h (237776 => 237777)


--- trunk/Source/WebCore/bindings/js/CallTracer.h	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/bindings/js/CallTracer.h	2018-11-03 23:24:35 UTC (rev 237777)
@@ -32,9 +32,11 @@
 namespace WebCore {
 
 class CanvasRenderingContext;
+class HTMLCanvasElement;
 
 class CallTracer {
 public:
+    static void recordCanvasAction(const HTMLCanvasElement&, const String&, Vector<RecordCanvasActionVariant>&& = { });
     static void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
 };
 

Modified: trunk/Source/WebCore/html/CanvasBase.cpp (237776 => 237777)


--- trunk/Source/WebCore/html/CanvasBase.cpp	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/html/CanvasBase.cpp	2018-11-03 23:24:35 UTC (rev 237777)
@@ -109,4 +109,9 @@
     return cssCanvasClients;
 }
 
+bool CanvasBase::callTracingActive() const
+{
+    return m_context && m_context->callTracingActive();
 }
+
+}

Modified: trunk/Source/WebCore/html/CanvasBase.h (237776 => 237777)


--- trunk/Source/WebCore/html/CanvasBase.h	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/html/CanvasBase.h	2018-11-03 23:24:35 UTC (rev 237777)
@@ -95,6 +95,8 @@
     virtual AffineTransform baseTransform() const = 0;
     virtual Image* copiedImage() const = 0;
 
+    bool callTracingActive() const;
+
 protected:
     CanvasBase(ScriptExecutionContext*);
 

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.idl (237776 => 237777)


--- trunk/Source/WebCore/html/HTMLCanvasElement.idl	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.idl	2018-11-03 23:24:35 UTC (rev 237777)
@@ -45,8 +45,8 @@
     ReportExtraMemoryCost,
     ReportExternalMemoryCost,
 ] interface HTMLCanvasElement : HTMLElement {
-    attribute unsigned long width;
-    attribute unsigned long height;
+    [CallTracingCallback=recordCanvasAction] attribute unsigned long width;
+    [CallTracingCallback=recordCanvasAction] attribute unsigned long height;
 
     [CallWith=ExecState, MayThrowException] RenderingContext? getContext(DOMString contextId, any... arguments);
 

Modified: trunk/Source/WebInspectorUI/ChangeLog (237776 => 237777)


--- trunk/Source/WebInspectorUI/ChangeLog	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/ChangeLog	2018-11-03 23:24:35 UTC (rev 237777)
@@ -1,3 +1,47 @@
+2018-11-03  Devin Rousso  <[email protected]>
+
+        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
+        https://bugs.webkit.org/show_bug.cgi?id=190854
+
+        Reviewed by Matt Baker.
+
+        * UserInterface/Models/RecordingAction.js:
+        (WI.RecordingAction):
+        (WI.RecordingAction.isFunctionForType):
+        (WI.RecordingAction.constantNameForParameter):
+        (WI.RecordingAction.prototype.get contextReplacer): Added.
+        (WI.RecordingAction.prototype.async.swizzle):
+        (WI.RecordingAction.prototype.apply):
+        Create a constant list of actions for each recording type that need to replace the context
+        with a different value before being applied (e.g. `width` should be applied to the
+        `context`'s `canvas` instead of directly to the `context`).
+
+        * UserInterface/Views/RecordingContentView.js:
+        (WI.RecordingContentView.prototype._generateContentCanvas2D.actionModifiesPath): Added.
+        (WI.RecordingContentView.prototype._generateContentCanvas2D):
+        (WI.RecordingContentView._actionModifiesPath): Deleted.
+        Generate the path context after the actions are applied to the preview context so that the
+        final width/height are known and can be used. This is needed because changing the
+        width/height causes the content to be erased.
+
+        * UserInterface/Views/RecordingActionTreeElement.js:
+        (WI.RecordingActionTreeElement._generateDOM):
+        (WI.RecordingActionTreeElement._classNameForAction):
+        * UserInterface/Views/RecordingActionTreeElement.css:
+        (.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
+        (.item.action > .titles .context-replacer::after): Added.
+        (.item.action.has-context-replacer > .icon): Added.
+        (@media (prefers-dark-interface) .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
+        (.tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon): Deleted.
+        (@media (prefers-dark-interface) .item.action:not(.initial-state) > .icon): Deleted.
+        (@media (prefers-dark-interface) .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon): Deleted.
+        Add the context replacer text to the beginning of the action's name if it exists.
+
+        * UserInterface/Views/CanvasContentView.js:
+        (WI.CanvasContentView.prototype._refreshPixelSize):
+        (WI.CanvasContentView.prototype._updatePixelSize): Deleted.
+        Update preview image when the canvas' size changes.
+
 2018-11-02  Matt Baker  <[email protected]>
 
         Web Inspector: support multiple selection/deletion of cookie records

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js (237776 => 237777)


--- trunk/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js	2018-11-03 23:24:35 UTC (rev 237777)
@@ -45,6 +45,8 @@
         this._isGetter = false;
         this._isVisual = false;
 
+        this._contextReplacer = null;
+
         this._states = [];
         this._stateModifiers = new Set;
 
@@ -84,7 +86,10 @@
         let prototype = WI.RecordingAction._prototypeForType(type);
         if (!prototype)
             return false;
-        return typeof Object.getOwnPropertyDescriptor(prototype, name).value === "function";
+        let propertyDescriptor = Object.getOwnPropertyDescriptor(prototype, name);
+        if (!propertyDescriptor)
+            return false;
+        return typeof propertyDescriptor.value === "function";
     }
 
     static constantNameForParameter(type, name, value, index, count)
@@ -123,7 +128,7 @@
         let prototype = WI.RecordingAction._prototypeForType(type);
         for (let key in prototype) {
             let descriptor = Object.getOwnPropertyDescriptor(prototype, key);
-            if (descriptor.value === value)
+            if (descriptor && descriptor.value === value)
                 return key;
         }
 
@@ -198,6 +203,7 @@
     get isFunction() { return this._isFunction; }
     get isGetter() { return this._isGetter; }
     get isVisual() { return this._isVisual; }
+    get contextReplacer() { return this._contextReplacer; }
     get states() { return this._states; }
     get stateModifiers() { return this._stateModifiers; }
     get warning() { return this._warning; }
@@ -330,18 +336,31 @@
         if (this._payloadSnapshot >= 0)
             this._snapshot = snapshot;
 
-        this._isFunction = WI.RecordingAction.isFunctionForType(recording.type, this._name);
-        this._isGetter = !this._isFunction && !this._parameters.length;
+        if (recording.type === WI.Recording.Type.Canvas2D || recording.type === WI.Recording.Type.CanvasBitmapRenderer || recording.type === WI.Recording.Type.CanvasWebGL) {
+            if (this._name === "width" || this._name === "height") {
+                this._contextReplacer = "canvas";
+                this._isFunction = false;
+                this._isGetter = !this._parameters.length;
+                this._isVisual = !this._isGetter;
+            }
 
-        let visualNames = WI.RecordingAction._visualNames[recording.type];
-        this._isVisual = visualNames ? visualNames.has(this._name) : false;
+            // FIXME: <https://webkit.org/b/180833>
+        }
 
-        if (this._valid) {
-            let prototype = WI.RecordingAction._prototypeForType(recording.type);
-            if (prototype && !(name in prototype)) {
-                this.markInvalid();
+        if (!this._contextReplacer) {
+            this._isFunction = WI.RecordingAction.isFunctionForType(recording.type, this._name);
+            this._isGetter = !this._isFunction && !this._parameters.length;
 
-                WI.Recording.synthesizeError(WI.UIString("ā€œ%sā€ is invalid.").format(name));
+            let visualNames = WI.RecordingAction._visualNames[recording.type];
+            this._isVisual = visualNames ? visualNames.has(this._name) : false;
+
+            if (this._valid) {
+                let prototype = WI.RecordingAction._prototypeForType(recording.type);
+                if (prototype && !(name in prototype)) {
+                    this.markInvalid();
+
+                    WI.Recording.synthesizeError(WI.UIString("ā€œ%sā€ is invalid.").format(name));
+                }
             }
         }
 
@@ -375,6 +394,10 @@
 
         try {
             let name = options.nameOverride || this._name;
+
+            if (this._contextReplacer)
+                context = context[this._contextReplacer];
+
             if (this.isFunction)
                 context[name](...this._parameters);
             else {

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js (237776 => 237777)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js	2018-11-03 23:24:35 UTC (rev 237777)
@@ -287,13 +287,28 @@
 
     _refreshPixelSize()
     {
-        this._pixelSize = null;
+        let updatePixelSize = (size) => {
+            if (this._pixelSize && size.width === this._pixelSize.width && size.height === this._pixelSize.height)
+                return;
 
-        this.representedObject.requestSize().then((size) => {
             this._pixelSize = size;
-            this._updatePixelSize();
-        }).catch((error) => {
-            this._updatePixelSize();
+
+            if (this._pixelSizeElement) {
+                if (this._pixelSize)
+                    this._pixelSizeElement.textContent = `${this._pixelSize.width} ${multiplicationSign} ${this._pixelSize.height}`;
+                else
+                    this._pixelSizeElement.textContent = emDash;
+            }
+
+            this.refresh();
+        };
+
+        this.representedObject.requestSize()
+        .then((size) => {
+            updatePixelSize(size);
+        })
+        .catch((error) => {
+            updatePixelSize(null);
         });
     }
 
@@ -349,17 +364,6 @@
         }
     }
 
-    _updatePixelSize()
-    {
-        if (!this._pixelSizeElement)
-            return;
-
-        if (this._pixelSize)
-            this._pixelSizeElement.textContent = `${this._pixelSize.width} ${multiplicationSign} ${this._pixelSize.height}`;
-        else
-            this._pixelSizeElement.textContent = emDash;
-    }
-
     _updateRecordNavigationItem()
     {
         if (!this._recordButtonNavigationItem)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.css (237776 => 237777)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.css	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.css	2018-11-03 23:24:35 UTC (rev 237777)
@@ -52,7 +52,7 @@
     margin-left: var(--tree-outline-icon-margin-end);
 }
 
-.tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon {
+.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon {
     filter: invert();
     opacity: 1;
 }
@@ -109,6 +109,10 @@
     background-color: var(--value-changed-highlight);
 }
 
+.item.action > .titles .context-replacer::after {
+    content: ".";
+}
+
 .item.action.attribute > .titles .parameters::before {
     content: " = ";
 }
@@ -133,6 +137,10 @@
     vertical-align: -1px;
 }
 
+.item.action.has-context-replacer > .icon {
+    content: url("../Images/Source.svg");
+}
+
 .item.action.composite > .icon {
     content: url(../Images/Composite.svg);
 }
@@ -236,12 +244,8 @@
         color: var(--green-highlight-text-color);
     }
 
-    .item.action:not(.initial-state) > .icon {
+    .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon {
         filter: invert();
-    }
-
-    .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon {
-        filter: invert();
         opacity: 0.8;
     }
 }

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.js (237776 => 237777)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.js	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.js	2018-11-03 23:24:35 UTC (rev 237777)
@@ -105,6 +105,15 @@
         let titleFragment = document.createDocumentFragment();
         let copyText = recordingAction.name;
 
+        let contextReplacer = recordingAction.contextReplacer;
+        if (contextReplacer) {
+            copyText = contextReplacer + "." + copyText;
+
+            let contextReplacerContainer = titleFragment.appendChild(document.createElement("span"));
+            contextReplacerContainer.classList.add("context-replacer");
+            contextReplacerContainer.textContent = contextReplacer;
+        }
+
         let nameContainer = titleFragment.appendChild(document.createElement("span"));
         nameContainer.classList.add("name");
         nameContainer.textContent = recordingAction.name;
@@ -247,6 +256,9 @@
 
     static _classNameForAction(recordingAction)
     {
+        if (recordingAction.contextReplacer)
+            return "has-context-replacer";
+
         function classNameForActionName(name) {
             switch (name) {
             case "arc":

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js (237776 => 237777)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js	2018-11-03 18:45:47 UTC (rev 237776)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js	2018-11-03 23:24:35 UTC (rev 237777)
@@ -64,27 +64,6 @@
         }
     }
 
-    // Static
-
-    static _actionModifiesPath(recordingAction)
-    {
-        switch (recordingAction.name) {
-        case "arc":
-        case "arcTo":
-        case "beginPath":
-        case "bezierCurveTo":
-        case "closePath":
-        case "ellipse":
-        case "lineTo":
-        case "moveTo":
-        case "quadraticCurveTo":
-        case "rect":
-            return true;
-        }
-
-        return false;
-    }
-
     // Public
 
     get navigationItems()
@@ -241,6 +220,9 @@
             let saveCount = 0;
             snapshot.context.save();
 
+            for (let attribute in snapshot.attributes)
+                snapshot.element[attribute] = snapshot.attributes[attribute];
+
             if (snapshot.content) {
                 snapshot.context.clearRect(0, 0, snapshot.element.width, snapshot.element.height);
                 snapshot.context.drawImage(snapshot.content, 0, 0);
@@ -269,8 +251,21 @@
                 snapshot.context.save();
             }
 
-            let shouldDrawCanvasPath = showCanvasPath && indexOfLastBeginPathAction <= to;
-            if (shouldDrawCanvasPath) {
+            let lastPathPoint = {};
+            let subPathStartPoint = {};
+
+            for (let i = from; i <= to; ++i) {
+                if (actions[i].name === "save")
+                    ++saveCount;
+                else if (actions[i].name === "restore") {
+                    if (!saveCount) // Only attempt to restore if save has been called.
+                        continue;
+                }
+
+                actions[i].apply(snapshot.context);
+            }
+
+            if (showCanvasPath && indexOfLastBeginPathAction <= to) {
                 if (!this._pathContext) {
                     let pathCanvas = document.createElement("canvas");
                     pathCanvas.classList.add("path");
@@ -285,22 +280,29 @@
 
                 this._pathContext.fillStyle = "hsla(0, 0%, 100%, 0.75)";
                 this._pathContext.fillRect(0, 0, snapshot.element.width, snapshot.element.height);
-            }
 
-            let lastPathPoint = {};
-            let subPathStartPoint = {};
+                function actionModifiesPath(action) {
+                    switch (action.name) {
+                    case "arc":
+                    case "arcTo":
+                    case "beginPath":
+                    case "bezierCurveTo":
+                    case "closePath":
+                    case "ellipse":
+                    case "lineTo":
+                    case "moveTo":
+                    case "quadraticCurveTo":
+                    case "rect":
+                        return true;
+                    }
 
-            for (let i = from; i <= to; ++i) {
-                if (actions[i].name === "save")
-                    ++saveCount;
-                else if (actions[i].name === "restore") {
-                    if (!saveCount) // Only attempt to restore if save has been called.
-                        continue;
+                    return false;
                 }
 
-                actions[i].apply(snapshot.context);
+                for (let i = indexOfLastBeginPathAction; i <= to; ++i) {
+                    if (!actionModifiesPath(actions[i]))
+                        continue;
 
-                if (shouldDrawCanvasPath && i >= indexOfLastBeginPathAction && WI.RecordingContentView._actionModifiesPath(actions[i])) {
                     lastPathPoint = {x: this._pathContext.currentX, y: this._pathContext.currentY};
 
                     if (i === indexOfLastBeginPathAction)
@@ -326,9 +328,7 @@
 
                     this._pathContext.stroke();
                 }
-            }
 
-            if (shouldDrawCanvasPath) {
                 this._pathContext.restore();
                 this._previewContainer.appendChild(this._pathContext.canvas);
             } else if (this._pathContext)
@@ -358,10 +358,16 @@
             if (lastSnapshotIndex < 0) {
                 snapshot.content = this._initialContent;
                 snapshot.states = actions[0].states;
+                snapshot.attributes = Object.shallowCopy(initialState.attributes);
             } else {
-                snapshot.content = this._snapshots[lastSnapshotIndex].content;
-                snapshot.states = this._snapshots[lastSnapshotIndex].states;
-                startIndex = this._snapshots[lastSnapshotIndex].index;
+                let lastSnapshot = this._snapshots[lastSnapshotIndex];
+                snapshot.content = lastSnapshot.content;
+                snapshot.states = lastSnapshot.states;
+                snapshot.attributes = {};
+                for (let attribute in initialState.attributes)
+                    snapshot.attributes[attribute] = lastSnapshot.element[attribute];
+
+                startIndex = lastSnapshot.index;
             }
 
             applyActions(startIndex, snapshot.index - 1);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to