diff --git a/core/blockly.js b/core/blockly.js index eed6b4130..c9233088d 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -42,6 +42,7 @@ goog.require('Blockly.Tooltip'); goog.require('Blockly.Touch'); goog.require('Blockly.utils'); goog.require('Blockly.utils.colour'); +goog.require('Blockly.utils.deprecation'); goog.require('Blockly.utils.Size'); /** @suppress {extraRequire} */ goog.require('Blockly.Variables'); @@ -125,8 +126,16 @@ Blockly.parentContainer = null; * Returns the dimensions of the specified SVG image. * @param {!SVGElement} svg SVG image. * @return {!Blockly.utils.Size} Contains width and height properties. + * @deprecated Use workspace.setCachedParentSvgSize. (2021 March 5) */ Blockly.svgSize = function(svg) { + // When removing this function, remove svg.cachedWidth_ and svg.cachedHeight_ + // from setCachedParentSvgSize. + Blockly.utils.deprecation.warn( + 'Blockly.svgSize', + 'March 2021', + 'March 2022', + 'workspace.getCachedParentSvgSize'); svg = /** @type {?} */ (svg); return new Blockly.utils.Size(svg.cachedWidth_, svg.cachedHeight_); }; @@ -154,6 +163,7 @@ Blockly.svgResize = function(workspace) { mainWorkspace = mainWorkspace.options.parentWorkspace; } var svg = mainWorkspace.getParentSvg(); + var cachedSize = mainWorkspace.getCachedParentSvgSize(); var div = svg.parentNode; if (!div) { // Workspace deleted, or something. @@ -161,13 +171,13 @@ Blockly.svgResize = function(workspace) { } var width = div.offsetWidth; var height = div.offsetHeight; - if (svg.cachedWidth_ != width) { + if (cachedSize.width != width) { svg.setAttribute('width', width + 'px'); - svg.cachedWidth_ = width; + mainWorkspace.setCachedParentSvgSize(width, null); } - if (svg.cachedHeight_ != height) { + if (cachedSize.height != height) { svg.setAttribute('height', height + 'px'); - svg.cachedHeight_ = height; + mainWorkspace.setCachedParentSvgSize(null, height); } mainWorkspace.resize(); }; diff --git a/core/flyout_horizontal.js b/core/flyout_horizontal.js index 11cbe8302..62220e673 100644 --- a/core/flyout_horizontal.js +++ b/core/flyout_horizontal.js @@ -193,18 +193,16 @@ Blockly.HorizontalFlyout.prototype.getY = function() { * Move the flyout to the edge of the workspace. */ Blockly.HorizontalFlyout.prototype.position = function() { - if (!this.isVisible()) { + if (!this.isVisible() || !this.targetWorkspace.isVisible()) { return; } - var targetWorkspaceMetrics = this.targetWorkspace.getMetrics(); - if (!targetWorkspaceMetrics) { - // Hidden components will return null. - return; - } - // Record the width for Blockly.Flyout.getMetrics_. - this.width_ = targetWorkspaceMetrics.viewWidth; + var metricsManager = this.targetWorkspace.getMetricsManager(); + var targetWorkspaceViewMetrics = metricsManager.getViewMetrics(); - var edgeWidth = targetWorkspaceMetrics.viewWidth - 2 * this.CORNER_RADIUS; + // Record the width for Blockly.Flyout.getMetrics_. + this.width_ = targetWorkspaceViewMetrics.width; + + var edgeWidth = targetWorkspaceViewMetrics.width - 2 * this.CORNER_RADIUS; var edgeHeight = this.height_ - this.CORNER_RADIUS; this.setBackgroundPath_(edgeWidth, edgeHeight); diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js index 576c61b78..71771b893 100644 --- a/core/flyout_vertical.js +++ b/core/flyout_vertical.js @@ -194,19 +194,17 @@ Blockly.VerticalFlyout.prototype.getY = function() { * Move the flyout to the edge of the workspace. */ Blockly.VerticalFlyout.prototype.position = function() { - if (!this.isVisible()) { - return; - } - var targetWorkspaceMetrics = this.targetWorkspace.getMetrics(); - if (!targetWorkspaceMetrics) { - // Hidden components will return null. + if (!this.isVisible() || !this.targetWorkspace.isVisible()) { return; } + var metricsManager = this.targetWorkspace.getMetricsManager(); + var targetWorkspaceViewMetrics = metricsManager.getViewMetrics(); + // Record the height for Blockly.Flyout.getMetrics_ - this.height_ = targetWorkspaceMetrics.viewHeight; + this.height_ = targetWorkspaceViewMetrics.height; var edgeWidth = this.width_ - this.CORNER_RADIUS; - var edgeHeight = targetWorkspaceMetrics.viewHeight - 2 * this.CORNER_RADIUS; + var edgeHeight = targetWorkspaceViewMetrics.height - 2 * this.CORNER_RADIUS; this.setBackgroundPath_(edgeWidth, edgeHeight); var x = this.getX(); diff --git a/core/metrics_manager.js b/core/metrics_manager.js index 2ee7821e5..0c6964bc1 100644 --- a/core/metrics_manager.js +++ b/core/metrics_manager.js @@ -156,8 +156,7 @@ Blockly.MetricsManager.prototype.getToolboxMetrics = function() { * @public */ Blockly.MetricsManager.prototype.getSvgMetrics = function() { - var svgSize = Blockly.svgSize(this.workspace_.getParentSvg()); - return new Blockly.utils.Size(svgSize.width, svgSize.height); + return this.workspace_.getCachedParentSvgSize(); }; /** diff --git a/core/mutator.js b/core/mutator.js index 96baf0420..c4abea3e8 100644 --- a/core/mutator.js +++ b/core/mutator.js @@ -34,7 +34,6 @@ goog.requireType('Blockly.BlockSvg'); goog.requireType('Blockly.Connection'); goog.requireType('Blockly.Events.Abstract'); goog.requireType('Blockly.utils.Coordinate'); -goog.requireType('Blockly.utils.Metrics'); goog.requireType('Blockly.Workspace'); @@ -183,7 +182,6 @@ Blockly.Mutator.prototype.createEditor_ = function() { if (hasFlyout) { workspaceOptions.languageTree = Blockly.utils.toolbox.convertToolboxDefToJson(quarkXml); - workspaceOptions.getMetrics = this.getFlyoutMetrics_.bind(this); } this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions); this.workspace_.isMutator = true; @@ -244,7 +242,7 @@ Blockly.Mutator.prototype.resizeBubble_ = function() { var flyout = this.workspace_.getFlyout(); if (flyout) { var flyoutMetrics = flyout.getMetrics_(); - height = Math.max(height, flyoutMetrics.contentHeight + 20); + height = Math.max(height, flyoutMetrics.scrollHeight + 20); width += flyout.getWidth(); } if (this.block_.RTL) { @@ -254,7 +252,7 @@ Blockly.Mutator.prototype.resizeBubble_ = function() { // Only resize if the size difference is significant. Eliminates shuddering. if (Math.abs(this.workspaceWidth_ - width) > doubleBorderWidth || Math.abs(this.workspaceHeight_ - height) > doubleBorderWidth) { - // Record some layout information for getFlyoutMetrics_. + // Record some layout information for workspace metrics. this.workspaceWidth_ = width; this.workspaceHeight_ = height; // Resize the bubble. @@ -262,6 +260,8 @@ Blockly.Mutator.prototype.resizeBubble_ = function() { width + doubleBorderWidth, height + doubleBorderWidth); this.svgDialog_.setAttribute('width', this.workspaceWidth_); this.svgDialog_.setAttribute('height', this.workspaceHeight_); + this.workspace_.setCachedParentSvgSize( + this.workspaceWidth_, this.workspaceHeight_); } if (this.block_.RTL) { @@ -447,44 +447,6 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) { } }; -/** - * Returns an object with all the metrics required to correctly position the - * mutator's flyout. The following properties are computed: - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .absoluteTop: Top-edge of view. - * .absoluteLeft: Left-edge of view. - * @return {!Blockly.utils.Metrics} Contains size and position metrics of - * mutator dialog's workspace. - * @private - */ -Blockly.Mutator.prototype.getFlyoutMetrics_ = function() { - // The mutator workspace only uses a subset of Blockly.utils.Metrics - // properties as features such as scroll and zoom are unsupported. - var unsupported = 0; - var flyout = this.workspace_.getFlyout(); - var flyoutWidth = flyout ? flyout.getWidth() : 0; - return { - contentHeight: unsupported, - contentWidth: unsupported, - contentTop: unsupported, - contentLeft: unsupported, - - scrollHeight: unsupported, - scrollWidth: unsupported, - scrollTop: unsupported, - scrollLeft: unsupported, - - viewHeight: this.workspaceHeight_, - viewWidth: this.workspaceWidth_ - flyoutWidth, - viewTop: unsupported, - viewLeft: unsupported, - - absoluteTop: unsupported, - absoluteLeft: this.workspace_.RTL ? 0 : flyoutWidth - }; -}; - /** * Dispose of this mutator. */ diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 8e311093e..6634cdef5 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -230,6 +230,14 @@ Blockly.WorkspaceSvg = function( * @private */ this.topBoundedElements_ = []; + + /** + * The cached size of the parent svg element. + * Used to compute svg metrics. + * @type {!Blockly.utils.Size} + * @private + */ + this.cachedParentSvgSize_ = new Blockly.utils.Size(0, 0); }; Blockly.utils.object.inherits(Blockly.WorkspaceSvg, Blockly.Workspace); @@ -729,6 +737,17 @@ Blockly.WorkspaceSvg.prototype.getSvgXY = function(element) { return new Blockly.utils.Coordinate(x, y); }; +/** + * Gets the size of the workspace's parent svg element. + * @return {!Blockly.utils.Size} The cached width and height of the workspace's + * parent svg element. + * @package + */ +Blockly.WorkspaceSvg.prototype.getCachedParentSvgSize = function() { + var size = this.cachedParentSvgSize_; + return new Blockly.utils.Size(size.width, size.height); +}; + /** * Return the position of the workspace origin relative to the injection div * origin in pixels. @@ -1150,6 +1169,27 @@ Blockly.WorkspaceSvg.prototype.getCanvas = function() { return /** @type {!SVGGElement} */ (this.svgBlockCanvas_); }; +/** + * Caches the width and height of the workspace's parent svg element for use + * with getSvgMetrics. + * @param {?number} width The width of the parent svg element. + * @param {?number} height The height of the parent svg element + * @package + */ +Blockly.WorkspaceSvg.prototype.setCachedParentSvgSize = function(width, height) { + var svg = this.getParentSvg(); + if (width) { + this.cachedParentSvgSize_.width = width; + // This is set to support the public (but deprecated) Blockly.svgSize method. + svg.cachedWidth_ = width; + } + if (height) { + this.cachedParentSvgSize_.height = height; + // This is set to support the public (but deprecated) Blockly.svgSize method. + svg.cachedHeight_ = height; + } +}; + /** * Get the SVG element that forms the bubble surface. * @return {!SVGGElement} SVG group element.