Modified: trunk/Source/WebInspectorUI/ChangeLog (237400 => 237401)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-10-24 21:35:35 UTC (rev 237400)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-10-24 22:12:54 UTC (rev 237401)
@@ -1,5 +1,31 @@
2018-10-24 Devin Rousso <[email protected]>
+ Web Inspector: popovers for function source code are malformed
+ https://bugs.webkit.org/show_bug.cgi?id=190859
+
+ Reviewed by Joseph Pecoraro.
+
+ Previously, the `WI.Popover` would be drawn twice: once when the
+ `WI.CodeMirrorTokenTrackingController` determines that the user has hovered on a function
+ token, and once again when the source for that function is formatted (after being retrieved).
+ In the case that the formatter is able to return the prettified source within a frame (or
+ two), the `WI.Popover` is still in the middle of animating to its new size, meaning that the
+ changes made by the formatted `update` will be overridden on the next rAF (creates a flash).
+
+ * UserInterface/Views/Popover.js:
+ (WI.Popover.prototype):
+ (WI.Popover.prototype._animateFrame.drawBackground):
+ (WI.Popover.prototype._drawBackground):
+ Add a member variable to make sure that there is only ever one rAF firing at a time.
+ Drive-by: rework the background code to only use one canvas.
+
+ * UserInterface/Views/SourceCodeTextEditor.js:
+ (WI.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
+ Don't show the `WI.Popover` until the formatter has finished prettifying the function's
+ source code, as otherwise there is brief moment that the popover appears and is empty.
+
+2018-10-24 Devin Rousso <[email protected]>
+
Web Inspector: REGRESSION (r237232): changing resources via up/down blurs the TreeOutline in Resources
https://bugs.webkit.org/show_bug.cgi?id=190862
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/Popover.js (237400 => 237401)
--- trunk/Source/WebInspectorUI/UserInterface/Views/Popover.js 2018-10-24 21:35:35 UTC (rev 237400)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/Popover.js 2018-10-24 22:12:54 UTC (rev 237401)
@@ -47,6 +47,8 @@
this._container = this._element.appendChild(document.createElement("div"));
this._container.className = "container";
+
+ this._drawBackgroundAnimationIdentifier = undefined;
}
// Public
@@ -370,7 +372,7 @@
this._drawBackground();
if (progress < 1)
- requestAnimationFrame(drawBackground.bind(this));
+ this._drawBackgroundAnimationIdentifier = requestAnimationFrame(drawBackground.bind(this));
}
drawBackground.call(this);
@@ -378,6 +380,11 @@
_drawBackground()
{
+ if (this._drawBackgroundAnimationIdentifier) {
+ cancelAnimationFrame(this._drawBackgroundAnimationIdentifier);
+ this._drawBackgroundAnimationIdentifier = undefined;
+ }
+
let scaleFactor = window.devicePixelRatio;
let width = this._frame.size.width;
@@ -385,15 +392,6 @@
let scaledWidth = width * scaleFactor;
let scaledHeight = height * scaleFactor;
- // Create a scratch canvas so we can draw the popover that will later be drawn into
- // the final context with a shadow.
- let scratchCanvas = document.createElement("canvas");
- scratchCanvas.width = scaledWidth;
- scratchCanvas.height = scaledHeight;
-
- let ctx = scratchCanvas.getContext("2d");
- ctx.scale(scaleFactor, scaleFactor);
-
// Bounds of the path don't take into account the arrow, but really only the tight bounding box
// of the content contained within the frame.
let bounds;
@@ -416,30 +414,30 @@
bounds = bounds.inset(WI.Popover.ShadowEdgeInsets);
let computedStyle = window.getComputedStyle(this._element, null);
+ let context = document.getCSSCanvasContext("2d", "popover", scaledWidth, scaledHeight);
+ context.clearRect(0, 0, scaledWidth, scaledHeight);
+ context.shadowOffsetX = 1;
+ context.shadowOffsetY = 1;
+ context.shadowBlur = 5;
+ context.shadowColor = computedStyle.getPropertyValue("--popover-shadow-color").trim();
+ context.resetTransform();
+ context.scale(scaleFactor, scaleFactor);
+
// Clip the frame.
- ctx.fillStyle = computedStyle.getPropertyValue("--popover-text-color").trim();
- this._drawFrame(ctx, bounds, this._edge, this._anchorPoint);
- ctx.clip();
+ context.fillStyle = computedStyle.getPropertyValue("--popover-text-color").trim();
+ this._drawFrame(context, bounds, this._edge, this._anchorPoint);
+ context.clip();
// Panel background color fill.
- ctx.fillStyle = computedStyle.getPropertyValue("--popover-background-color").trim();
+ context.fillStyle = computedStyle.getPropertyValue("--popover-background-color").trim();
- ctx.fillRect(0, 0, width, height);
+ context.fillRect(0, 0, width, height);
// Stroke.
- ctx.strokeStyle = computedStyle.getPropertyValue("--popover-border-color").trim();
- ctx.lineWidth = 2;
- this._drawFrame(ctx, bounds, this._edge, this._anchorPoint);
- ctx.stroke();
-
- // Draw the popover into the final context with a drop shadow.
- let finalContext = document.getCSSCanvasContext("2d", "popover", scaledWidth, scaledHeight);
- finalContext.clearRect(0, 0, scaledWidth, scaledHeight);
- finalContext.shadowOffsetX = 1;
- finalContext.shadowOffsetY = 1;
- finalContext.shadowBlur = 5;
- finalContext.shadowColor = computedStyle.getPropertyValue("--popover-shadow-color").trim();
- finalContext.drawImage(scratchCanvas, 0, 0, scaledWidth, scaledHeight);
+ context.strokeStyle = computedStyle.getPropertyValue("--popover-border-color").trim();
+ context.lineWidth = 2;
+ this._drawFrame(context, bounds, this._edge, this._anchorPoint);
+ context.stroke();
}
_bestMetricsForEdge(preferredSize, targetFrame, containerFrame, edge)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (237400 => 237401)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2018-10-24 21:35:35 UTC (rev 237400)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2018-10-24 22:12:54 UTC (rev 237401)
@@ -1875,9 +1875,6 @@
mode: "text/_javascript_",
readOnly: "nocursor",
});
- codeMirror.on("update", () => {
- this._popover.update();
- });
const isModule = false;
const indentString = WI.indentString();
@@ -1884,10 +1881,13 @@
const includeSourceMapData = false;
let workerProxy = WI.FormatterWorkerProxy.singleton();
workerProxy.formatJavaScript(data.description, isModule, indentString, includeSourceMapData, ({formattedText}) => {
+ if (candidate !== this.tokenTrackingController.candidate)
+ return;
+
+ this._showPopover(content);
codeMirror.setValue(formattedText || data.description);
+ this._popover.update();
});
-
- this._showPopover(content);
}
data.target.DebuggerAgent.getFunctionDetails(data.objectId, didGetDetails.bind(this));