diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js index 968d01c78..c95de2607 100644 --- a/core/flyout_vertical.js +++ b/core/flyout_vertical.js @@ -155,6 +155,9 @@ Blockly.VerticalFlyout.prototype.position = function() { var x = targetWorkspaceMetrics.absoluteLeft; if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT) { x += (targetWorkspaceMetrics.viewWidth - this.width_); + // Save the location of the left edge of the flyout, for use when Firefox + // gets the bounding client rect wrong. + this.leftEdge_ = x; } this.positionAt_(this.width_, this.height_, x, y); }; @@ -315,6 +318,30 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() { return new goog.math.Rect(x - BIG_NUM, -BIG_NUM, BIG_NUM + width, BIG_NUM * 2); } else { // Right + // Firefox sometimes reports the wrong value for the client rect. + // See https://github.com/google/blockly/issues/1425 and + // https://bugzilla.mozilla.org/show_bug.cgi?id=1066435 + if (goog.userAgent.GECKO && + this.targetWorkspace_ && this.targetWorkspace_.isMutator) { + // The position of the left side of the mutator workspace in pixels + // relative to the window origin. + var targetWsLeftPixels = + this.targetWorkspace_.svgGroup_.getBoundingClientRect().x; + // The client rect is in pixels relative to the window origin. When the + // browser gets the wrong value it reports that the flyout left is the + // same as the mutator workspace left. + // We know that in a mutator workspace with the flyout on the right, the + // visible area of the workspace should be more than ten pixels wide. If + // the browser reports that the flyout is within ten pixels of the left + // side of the workspace, ignore it and manually calculate the value. + if (Math.abs(targetWsLeftPixels - x) < 10) { + // If we're in a mutator, its scale is always 1, purely because of some + // oddities in our rendering optimizations. The actual scale is the + // same as the scale on the parent workspace. + var scale = this.targetWorkspace_.options.parentWorkspace.scale; + x = x + this.leftEdge_ * scale; + } + } return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + width, BIG_NUM * 2); } };