Changeset 237401 in webkit


Ignore:
Timestamp:
Oct 24, 2018 3:12:54 PM (5 years ago)
Author:
Devin Rousso
Message:

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.

Location:
trunk/Source/WebInspectorUI
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r237397 r237401  
     12018-10-24  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: popovers for function source code are malformed
     4        https://bugs.webkit.org/show_bug.cgi?id=190859
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Previously, the `WI.Popover` would be drawn twice: once when the
     9        `WI.CodeMirrorTokenTrackingController` determines that the user has hovered on a function
     10        token, and once again when the source for that function is formatted (after being retrieved).
     11        In the case that the formatter is able to return the prettified source within a frame (or
     12        two), the `WI.Popover` is still in the middle of animating to its new size, meaning that the
     13        changes made by the formatted `update` will be overridden on the next rAF (creates a flash).
     14
     15        * UserInterface/Views/Popover.js:
     16        (WI.Popover.prototype):
     17        (WI.Popover.prototype._animateFrame.drawBackground):
     18        (WI.Popover.prototype._drawBackground):
     19        Add a member variable to make sure that there is only ever one rAF firing at a time.
     20        Drive-by: rework the background code to only use one canvas.
     21
     22        * UserInterface/Views/SourceCodeTextEditor.js:
     23        (WI.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
     24        Don't show the `WI.Popover` until the formatter has finished prettifying the function's
     25        source code, as otherwise there is brief moment that the popover appears and is empty.
     26
    1272018-10-24  Devin Rousso  <drousso@apple.com>
    228
  • trunk/Source/WebInspectorUI/UserInterface/Views/Popover.js

    r236357 r237401  
    4848        this._container = this._element.appendChild(document.createElement("div"));
    4949        this._container.className = "container";
     50
     51        this._drawBackgroundAnimationIdentifier = undefined;
    5052    }
    5153
     
    371373
    372374            if (progress < 1)
    373                 requestAnimationFrame(drawBackground.bind(this));
     375                this._drawBackgroundAnimationIdentifier = requestAnimationFrame(drawBackground.bind(this));
    374376        }
    375377
     
    379381    _drawBackground()
    380382    {
     383        if (this._drawBackgroundAnimationIdentifier) {
     384            cancelAnimationFrame(this._drawBackgroundAnimationIdentifier);
     385            this._drawBackgroundAnimationIdentifier = undefined;
     386        }
     387
    381388        let scaleFactor = window.devicePixelRatio;
    382389
     
    385392        let scaledWidth = width * scaleFactor;
    386393        let scaledHeight = height * scaleFactor;
    387 
    388         // Create a scratch canvas so we can draw the popover that will later be drawn into
    389         // the final context with a shadow.
    390         let scratchCanvas = document.createElement("canvas");
    391         scratchCanvas.width = scaledWidth;
    392         scratchCanvas.height = scaledHeight;
    393 
    394         let ctx = scratchCanvas.getContext("2d");
    395         ctx.scale(scaleFactor, scaleFactor);
    396394
    397395        // Bounds of the path don't take into account the arrow, but really only the tight bounding box
     
    417415        let computedStyle = window.getComputedStyle(this._element, null);
    418416
     417        let context = document.getCSSCanvasContext("2d", "popover", scaledWidth, scaledHeight);
     418        context.clearRect(0, 0, scaledWidth, scaledHeight);
     419        context.shadowOffsetX = 1;
     420        context.shadowOffsetY = 1;
     421        context.shadowBlur = 5;
     422        context.shadowColor = computedStyle.getPropertyValue("--popover-shadow-color").trim();
     423        context.resetTransform();
     424        context.scale(scaleFactor, scaleFactor);
     425
    419426        // Clip the frame.
    420         ctx.fillStyle = computedStyle.getPropertyValue("--popover-text-color").trim();
    421         this._drawFrame(ctx, bounds, this._edge, this._anchorPoint);
    422         ctx.clip();
     427        context.fillStyle = computedStyle.getPropertyValue("--popover-text-color").trim();
     428        this._drawFrame(context, bounds, this._edge, this._anchorPoint);
     429        context.clip();
    423430
    424431        // Panel background color fill.
    425         ctx.fillStyle = computedStyle.getPropertyValue("--popover-background-color").trim();
    426 
    427         ctx.fillRect(0, 0, width, height);
     432        context.fillStyle = computedStyle.getPropertyValue("--popover-background-color").trim();
     433
     434        context.fillRect(0, 0, width, height);
    428435
    429436        // Stroke.
    430         ctx.strokeStyle = computedStyle.getPropertyValue("--popover-border-color").trim();
    431         ctx.lineWidth = 2;
    432         this._drawFrame(ctx, bounds, this._edge, this._anchorPoint);
    433         ctx.stroke();
    434 
    435         // Draw the popover into the final context with a drop shadow.
    436         let finalContext = document.getCSSCanvasContext("2d", "popover", scaledWidth, scaledHeight);
    437         finalContext.clearRect(0, 0, scaledWidth, scaledHeight);
    438         finalContext.shadowOffsetX = 1;
    439         finalContext.shadowOffsetY = 1;
    440         finalContext.shadowBlur = 5;
    441         finalContext.shadowColor = computedStyle.getPropertyValue("--popover-shadow-color").trim();
    442         finalContext.drawImage(scratchCanvas, 0, 0, scaledWidth, scaledHeight);
     437        context.strokeStyle = computedStyle.getPropertyValue("--popover-border-color").trim();
     438        context.lineWidth = 2;
     439        this._drawFrame(context, bounds, this._edge, this._anchorPoint);
     440        context.stroke();
    443441    }
    444442
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js

    r237232 r237401  
    18761876                readOnly: "nocursor",
    18771877            });
    1878             codeMirror.on("update", () => {
    1879                 this._popover.update();
    1880             });
    18811878
    18821879            const isModule = false;
     
    18851882            let workerProxy = WI.FormatterWorkerProxy.singleton();
    18861883            workerProxy.formatJavaScript(data.description, isModule, indentString, includeSourceMapData, ({formattedText}) => {
     1884                if (candidate !== this.tokenTrackingController.candidate)
     1885                    return;
     1886
     1887                this._showPopover(content);
    18871888                codeMirror.setValue(formattedText || data.description);
     1889                this._popover.update();
    18881890            });
    1889 
    1890             this._showPopover(content);
    18911891        }
    18921892
Note: See TracChangeset for help on using the changeset viewer.