From cc9396d739067e7c6f74ec31470132f8c6cee167 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Fri, 19 Aug 2016 14:13:20 -0700 Subject: [PATCH] Prefer functions in workspaceSvg to functions in blockly.js --- core/block_render_svg.js | 2 +- core/block_svg.js | 6 +- core/blockly.js | 123 ------------------------------------- core/inject.js | 2 - core/options.js | 10 ++- core/toolbox.js | 2 +- core/workspace_svg.js | 128 ++++++++++++++++++++++++++++++++++++++- core/xml.js | 2 +- 8 files changed, 135 insertions(+), 140 deletions(-) diff --git a/core/block_render_svg.js b/core/block_render_svg.js index 2a8ee7443..14c42b0af 100644 --- a/core/block_render_svg.js +++ b/core/block_render_svg.js @@ -288,7 +288,7 @@ Blockly.BlockSvg.prototype.render = function(opt_bubble) { parentBlock.render(true); } else { // Top-most block. Fire an event to allow scrollbars to resize. - Blockly.resizeSvgContents(this.workspace); + this.workspace.resizeContents(); } } Blockly.Field.stopCache(); diff --git a/core/block_svg.js b/core/block_svg.js index 0631d88a9..4d4a7299b 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -276,7 +276,7 @@ Blockly.BlockSvg.terminateDrag = function() { Blockly.Events.setGroup(false); }, Blockly.BUMP_DELAY); // Fire an event to allow scrollbars to resize. - Blockly.resizeSvgContents(selected.workspace); + selected.workspace.resizeContents(); } } Blockly.dragMode_ = Blockly.DRAG_NONE; @@ -346,7 +346,7 @@ Blockly.BlockSvg.prototype.moveBy = function(dx, dy) { 'translate(' + (xy.x + dx) + ',' + (xy.y + dy) + ')'); this.moveConnections_(dx, dy); event.recordNew(); - Blockly.resizeSvgContents(this.workspace); + this.workspace.resizeContents(); Blockly.Events.fire(event); }; @@ -1021,7 +1021,7 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) { Blockly.BlockSvg.superClass_.dispose.call(this, healStack); goog.dom.removeNode(this.svgGroup_); - Blockly.resizeSvgContents(blockWorkspace); + blockWorkspace.resizeContents(); // Sever JavaScript to DOM connections. this.svgGroup_ = null; this.svgPath_ = null; diff --git a/core/blockly.js b/core/blockly.js index c01e94a25..fb6562ed2 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -149,7 +149,6 @@ Blockly.resizeSvgContents = function(workspace) { workspace.resizeContents(); }; - /** * Size the SVG image to completely fill its container. Call this when the view * actually changes sizes (e.g. on a window resize/device orientation change). @@ -414,128 +413,6 @@ Blockly.hideChaff = function(opt_allowToolbox) { } }; -/** - * Return an object with all the metrics required to size scrollbars for the - * main workspace. The following properties are computed: - * .viewHeight: Height of the visible rectangle, - * .viewWidth: Width of the visible rectangle, - * .contentHeight: Height of the contents, - * .contentWidth: Width of the content, - * .viewTop: Offset of top edge of visible rectangle from parent, - * .viewLeft: Offset of left edge of visible rectangle from parent, - * .contentTop: Offset of the top-most content from the y=0 coordinate, - * .contentLeft: Offset of the left-most content from the x=0 coordinate. - * .absoluteTop: Top-edge of view. - * .absoluteLeft: Left-edge of view. - * .toolboxWidth: Width of toolbox, if it exists. Otherwise zero. - * .toolboxHeight: Height of toolbox, if it exists. Otherwise zero. - * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. - * .flyoutHeight: Height of flyout if it is always open. Otherwise zero. - * .toolboxPosition: Top, bottom, left or right. - * @return {Object} Contains size and position metrics of main workspace. - * @private - * @this Blockly.WorkspaceSvg - */ -Blockly.getMainWorkspaceMetrics_ = function() { - var svgSize = Blockly.svgSize(this.getParentSvg()); - if (this.toolbox_) { - if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP || - this.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { - svgSize.height -= this.toolbox_.getHeight(); - } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT || - this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { - svgSize.width -= this.toolbox_.getWidth(); - } - } - // Set the margin to match the flyout's margin so that the workspace does - // not jump as blocks are added. - var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1; - var viewWidth = svgSize.width - MARGIN; - var viewHeight = svgSize.height - MARGIN; - var blockBox = this.getBlocksBoundingBox(); - - // Fix scale. - var contentWidth = blockBox.width * this.scale; - var contentHeight = blockBox.height * this.scale; - var contentX = blockBox.x * this.scale; - var contentY = blockBox.y * this.scale; - if (this.scrollbar) { - // Add a border around the content that is at least half a screenful wide. - // Ensure border is wide enough that blocks can scroll over entire screen. - var leftEdge = Math.min(contentX - viewWidth / 2, - contentX + contentWidth - viewWidth); - var rightEdge = Math.max(contentX + contentWidth + viewWidth / 2, - contentX + viewWidth); - var topEdge = Math.min(contentY - viewHeight / 2, - contentY + contentHeight - viewHeight); - var bottomEdge = Math.max(contentY + contentHeight + viewHeight / 2, - contentY + viewHeight); - } else { - var leftEdge = blockBox.x; - var rightEdge = leftEdge + blockBox.width; - var topEdge = blockBox.y; - var bottomEdge = topEdge + blockBox.height; - } - var absoluteLeft = 0; - if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - absoluteLeft = this.toolbox_.getWidth(); - } - var absoluteTop = 0; - if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { - absoluteTop = this.toolbox_.getHeight(); - } - - var metrics = { - viewHeight: svgSize.height, - viewWidth: svgSize.width, - contentHeight: bottomEdge - topEdge, - contentWidth: rightEdge - leftEdge, - viewTop: -this.scrollY, - viewLeft: -this.scrollX, - contentTop: topEdge, - contentLeft: leftEdge, - absoluteTop: absoluteTop, - absoluteLeft: absoluteLeft, - toolboxWidth: this.toolbox_ ? this.toolbox_.getWidth() : 0, - toolboxHeight: this.toolbox_ ? this.toolbox_.getHeight() : 0, - flyoutWidth: this.flyout_ ? this.flyout_.getWidth() : 0, - flyoutHeight: this.flyout_ ? this.flyout_.getHeight() : 0, - toolboxPosition: this.toolboxPosition - }; - return metrics; -}; - -/** - * Sets the X/Y translations of the main workspace to match the scrollbars. - * @param {!Object} xyRatio Contains an x and/or y property which is a float - * between 0 and 1 specifying the degree of scrolling. - * @private - * @this Blockly.WorkspaceSvg - */ -Blockly.setMainWorkspaceMetrics_ = function(xyRatio) { - if (!this.scrollbar) { - throw 'Attempt to set main workspace scroll without scrollbars.'; - } - var metrics = this.getMetrics(); - if (goog.isNumber(xyRatio.x)) { - this.scrollX = -metrics.contentWidth * xyRatio.x - metrics.contentLeft; - } - if (goog.isNumber(xyRatio.y)) { - this.scrollY = -metrics.contentHeight * xyRatio.y - metrics.contentTop; - } - var x = this.scrollX + metrics.absoluteLeft; - var y = this.scrollY + metrics.absoluteTop; - this.translate(x, y); - if (this.options.gridPattern) { - this.options.gridPattern.setAttribute('x', x); - this.options.gridPattern.setAttribute('y', y); - if (goog.userAgent.IE) { - // IE doesn't notice that the x/y offsets have changed. Force an update. - this.updateGridPattern_(); - } - } -}; - /** * When something in Blockly's workspace changes, call a function. * @param {!Function} func Function to call. diff --git a/core/inject.js b/core/inject.js index d7fc9758c..57e3e51f4 100644 --- a/core/inject.js +++ b/core/inject.js @@ -185,8 +185,6 @@ Blockly.createDom_ = function(container, options) { */ Blockly.createMainWorkspace_ = function(svg, options) { options.parentWorkspace = null; - options.getMetrics = Blockly.getMainWorkspaceMetrics_; - options.setMetrics = Blockly.setMainWorkspaceMetrics_; var mainWorkspace = new Blockly.WorkspaceSvg(options); mainWorkspace.scale = options.zoomOptions.startScale; svg.appendChild(mainWorkspace.createDom('blocklyMainBackground')); diff --git a/core/options.js b/core/options.js index c86224cfc..268affa9b 100644 --- a/core/options.js +++ b/core/options.js @@ -132,16 +132,14 @@ Blockly.Options.prototype.parentWorkspace = null; /** * If set, sets the translation of the workspace to match the scrollbars. - * No-op if unset. */ -Blockly.Options.prototype.setMetrics = function() { return; }; +Blockly.Options.prototype.setMetrics = null; /** - * Return an object with the metrics required to size the workspace, or null - * if unset. - * @return {Object} Contains size an position metrics, or null. + * Return an object with the metrics required to size the workspace. + * @return {Object} Contains size and position metrics, or null. */ -Blockly.Options.prototype.getMetrics = function() { return null; }; +Blockly.Options.prototype.getMetrics = null; /** * Parse the user-specified zoom options, using reasonable defaults where diff --git a/core/toolbox.js b/core/toolbox.js index eab72b30e..bfb131c50 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -269,7 +269,7 @@ Blockly.Toolbox.prototype.populate_ = function(newTree) { } // Fire a resize event since the toolbox may have changed width and height. - Blockly.resizeSvgContents(this.workspace_); + this.workspace_.resizeContents(); }; /** diff --git a/core/workspace_svg.js b/core/workspace_svg.js index ee46738d6..6979df497 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -50,8 +50,10 @@ goog.require('goog.userAgent'); */ Blockly.WorkspaceSvg = function(options) { Blockly.WorkspaceSvg.superClass_.constructor.call(this, options); - this.getMetrics = options.getMetrics; - this.setMetrics = options.setMetrics; + this.getMetrics = + options.getMetrics || Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_; + this.setMetrics = + options.setMetrics || Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_; Blockly.ConnectionDB.init(this); @@ -853,7 +855,7 @@ Blockly.WorkspaceSvg.prototype.cleanUp = function() { } Blockly.Events.setGroup(false); // Fire an event to allow scrollbars to resize. - Blockly.resizeSvgContents(this); + this.resizeContents(); }; /** @@ -1273,6 +1275,126 @@ Blockly.WorkspaceSvg.prototype.updateGridPattern_ = function() { } }; + +/** + * Return an object with all the metrics required to size scrollbars for a + * top level workspace. The following properties are computed: + * .viewHeight: Height of the visible rectangle, + * .viewWidth: Width of the visible rectangle, + * .contentHeight: Height of the contents, + * .contentWidth: Width of the content, + * .viewTop: Offset of top edge of visible rectangle from parent, + * .viewLeft: Offset of left edge of visible rectangle from parent, + * .contentTop: Offset of the top-most content from the y=0 coordinate, + * .contentLeft: Offset of the left-most content from the x=0 coordinate. + * .absoluteTop: Top-edge of view. + * .absoluteLeft: Left-edge of view. + * .toolboxWidth: Width of toolbox, if it exists. Otherwise zero. + * .toolboxHeight: Height of toolbox, if it exists. Otherwise zero. + * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. + * .flyoutHeight: Height of flyout if it is always open. Otherwise zero. + * .toolboxPosition: Top, bottom, left or right. + * @return {Object} Contains size and position metrics of a top level workspace. + * @private + */ +Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_ = function() { + var svgSize = Blockly.svgSize(this.getParentSvg()); + if (this.toolbox_) { + if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP || + this.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { + svgSize.height -= this.toolbox_.getHeight(); + } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT || + this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { + svgSize.width -= this.toolbox_.getWidth(); + } + } + // Set the margin to match the flyout's margin so that the workspace does + // not jump as blocks are added. + var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1; + var viewWidth = svgSize.width - MARGIN; + var viewHeight = svgSize.height - MARGIN; + var blockBox = this.getBlocksBoundingBox(); + + // Fix scale. + var contentWidth = blockBox.width * this.scale; + var contentHeight = blockBox.height * this.scale; + var contentX = blockBox.x * this.scale; + var contentY = blockBox.y * this.scale; + if (this.scrollbar) { + // Add a border around the content that is at least half a screenful wide. + // Ensure border is wide enough that blocks can scroll over entire screen. + var leftEdge = Math.min(contentX - viewWidth / 2, + contentX + contentWidth - viewWidth); + var rightEdge = Math.max(contentX + contentWidth + viewWidth / 2, + contentX + viewWidth); + var topEdge = Math.min(contentY - viewHeight / 2, + contentY + contentHeight - viewHeight); + var bottomEdge = Math.max(contentY + contentHeight + viewHeight / 2, + contentY + viewHeight); + } else { + var leftEdge = blockBox.x; + var rightEdge = leftEdge + blockBox.width; + var topEdge = blockBox.y; + var bottomEdge = topEdge + blockBox.height; + } + var absoluteLeft = 0; + if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { + absoluteLeft = this.toolbox_.getWidth(); + } + var absoluteTop = 0; + if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { + absoluteTop = this.toolbox_.getHeight(); + } + + var metrics = { + viewHeight: svgSize.height, + viewWidth: svgSize.width, + contentHeight: bottomEdge - topEdge, + contentWidth: rightEdge - leftEdge, + viewTop: -this.scrollY, + viewLeft: -this.scrollX, + contentTop: topEdge, + contentLeft: leftEdge, + absoluteTop: absoluteTop, + absoluteLeft: absoluteLeft, + toolboxWidth: this.toolbox_ ? this.toolbox_.getWidth() : 0, + toolboxHeight: this.toolbox_ ? this.toolbox_.getHeight() : 0, + flyoutWidth: this.flyout_ ? this.flyout_.getWidth() : 0, + flyoutHeight: this.flyout_ ? this.flyout_.getHeight() : 0, + toolboxPosition: this.toolboxPosition + }; + return metrics; +}; + +/** + * Sets the X/Y translations of a top level workspace to match the scrollbars. + * @param {!Object} xyRatio Contains an x and/or y property which is a float + * between 0 and 1 specifying the degree of scrolling. + * @private + */ +Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_ = function(xyRatio) { + if (!this.scrollbar) { + throw 'Attempt to set top level workspace scroll without scrollbars.'; + } + var metrics = this.getMetrics(); + if (goog.isNumber(xyRatio.x)) { + this.scrollX = -metrics.contentWidth * xyRatio.x - metrics.contentLeft; + } + if (goog.isNumber(xyRatio.y)) { + this.scrollY = -metrics.contentHeight * xyRatio.y - metrics.contentTop; + } + var x = this.scrollX + metrics.absoluteLeft; + var y = this.scrollY + metrics.absoluteTop; + this.translate(x, y); + if (this.options.gridPattern) { + this.options.gridPattern.setAttribute('x', x); + this.options.gridPattern.setAttribute('y', y); + if (goog.userAgent.IE) { + // IE doesn't notice that the x/y offsets have changed. Force an update. + this.updateGridPattern_(); + } + } +}; // Export symbols that would otherwise be renamed by Closure compiler. Blockly.WorkspaceSvg.prototype['setVisible'] = Blockly.WorkspaceSvg.prototype.setVisible; diff --git a/core/xml.js b/core/xml.js index 959526e67..2567560cd 100644 --- a/core/xml.js +++ b/core/xml.js @@ -358,7 +358,7 @@ Blockly.Xml.domToBlock = function(xmlBlock, workspace) { topBlock.updateDisabled(); // Allow the scrollbars to resize and move based on the new contents. // TODO(@picklesrus): #387. Remove when domToBlock avoids resizing. - Blockly.resizeSvgContents(workspace); + workspace.resizeContents(); } } finally { Blockly.Events.enable();