diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js
index 860d5eef8..97cfc3be7 100644
--- a/blockly_uncompressed.js
+++ b/blockly_uncompressed.js
@@ -62,7 +62,7 @@ goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'],
goog.addDependency("../../../" + dir + "/core/options.js", ['Blockly.Options'], []);
goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Mutator', 'Blockly.Warning', 'Blockly.Workspace', 'Blockly.Xml', 'goog.array', 'goog.asserts', 'goog.math.Coordinate', 'goog.string']);
goog.addDependency("../../../" + dir + "/core/workspace_audio.js", ['Blockly.WorkspaceAudio'], []);
-goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['Blockly.Block', 'Blockly.ContextMenu', 'Blockly.RenderedConnection', 'Blockly.Touch', 'Blockly.utils', 'goog.Timer', 'goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
+goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['Blockly.Block', 'Blockly.ContextMenu', 'Blockly.Grid', 'Blockly.RenderedConnection', 'Blockly.Touch', 'Blockly.utils', 'goog.Timer', 'goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/flyout_dragger.js", ['Blockly.FlyoutDragger'], ['Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
goog.addDependency("../../../" + dir + "/core/field_dropdown.js", ['Blockly.FieldDropdown'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/gesture.js", ['Blockly.Gesture'], ['Blockly.BlockDragger', 'Blockly.constants', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
@@ -78,11 +78,11 @@ goog.addDependency("../../../" + dir + "/core/constants.js", ['Blockly.constants
goog.addDependency("../../../" + dir + "/core/rendered_connection.js", ['Blockly.RenderedConnection'], ['Blockly.Connection']);
goog.addDependency("../../../" + dir + "/core/field_colour.js", ['Blockly.FieldColour'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.ColorPicker']);
goog.addDependency("../../../" + dir + "/core/field_image.js", ['Blockly.FieldImage'], ['Blockly.Field', 'goog.dom', 'goog.math.Size', 'goog.userAgent']);
-goog.addDependency("../../../" + dir + "/core/field_variable.js", ['Blockly.FieldVariable'], ['Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.Variables', 'goog.asserts', 'goog.string']);
+goog.addDependency("../../../" + dir + "/core/field_variable.js", ['Blockly.FieldVariable'], ['Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'goog.asserts', 'goog.string']);
goog.addDependency("../../../" + dir + "/core/input.js", ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'goog.asserts']);
goog.addDependency("../../../" + dir + "/core/field_number.js", ['Blockly.FieldNumber'], ['Blockly.FieldTextInput', 'goog.math']);
-goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.Workspace', 'goog.string']);
-goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.constants', 'Blockly.Gesture', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Touch', 'Blockly.Trashcan', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'goog.array', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
+goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.VariableModel', 'Blockly.Workspace', 'goog.string']);
+goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.constants', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Touch', 'Blockly.Trashcan', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'goog.array', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/bubble.js", ['Blockly.Bubble'], ['Blockly.Touch', 'Blockly.Workspace', 'goog.dom', 'goog.math', 'goog.math.Coordinate', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/procedures.js", ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.Field', 'Blockly.Names', 'Blockly.Workspace']);
goog.addDependency("../../../" + dir + "/core/flyout.js", ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Comment', 'Blockly.Events', 'Blockly.FlyoutButton', 'Blockly.Gesture', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
@@ -93,10 +93,11 @@ goog.addDependency("../../../" + dir + "/core/tooltip.js", ['Blockly.Tooltip'],
goog.addDependency("../../../" + dir + "/core/field_angle.js", ['Blockly.FieldAngle'], ['Blockly.FieldTextInput', 'goog.math', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/zoom_controls.js", ['Blockly.ZoomControls'], ['Blockly.Touch', 'goog.dom']);
goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.VariableMap', 'goog.array', 'goog.math']);
+goog.addDependency("../../../" + dir + "/core/grid.js", ['Blockly.Grid'], ['Blockly.utils', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/field_date.js", ['Blockly.FieldDate'], ['Blockly.Field', 'goog.date', 'goog.dom', 'goog.events', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_he', 'goog.style', 'goog.ui.DatePicker']);
goog.addDependency("../../../" + dir + "/core/touch.js", ['Blockly.Touch'], ['goog.events', 'goog.events.BrowserFeature', 'goog.string']);
goog.addDependency("../../../" + dir + "/core/generator.js", ['Blockly.Generator'], ['Blockly.Block', 'goog.asserts']);
-goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.Options', 'Blockly.WorkspaceSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'goog.dom', 'goog.ui.Component', 'goog.userAgent']);
+goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.Grid', 'Blockly.Options', 'Blockly.WorkspaceSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'goog.dom', 'goog.ui.Component', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/connection_db.js", ['Blockly.ConnectionDB'], ['Blockly.Connection']);
goog.addDependency("../../browser_capabilities.js", [], []);
goog.addDependency("../../protractor_spec.js", [], []);
@@ -1694,6 +1695,7 @@ goog.require('Blockly.FlyoutButton');
goog.require('Blockly.FlyoutDragger');
goog.require('Blockly.Generator');
goog.require('Blockly.Gesture');
+goog.require('Blockly.Grid');
goog.require('Blockly.Icon');
goog.require('Blockly.Input');
goog.require('Blockly.Msg');
diff --git a/core/block_svg.js b/core/block_svg.js
index 74040ff2f..0aec6f96c 100644
--- a/core/block_svg.js
+++ b/core/block_svg.js
@@ -28,6 +28,7 @@ goog.provide('Blockly.BlockSvg');
goog.require('Blockly.Block');
goog.require('Blockly.ContextMenu');
+goog.require('Blockly.Grid');
goog.require('Blockly.RenderedConnection');
goog.require('Blockly.Touch');
goog.require('Blockly.utils');
@@ -404,11 +405,11 @@ Blockly.BlockSvg.prototype.snapToGrid = function() {
if (this.isInFlyout) {
return; // Don't move blocks around in a flyout.
}
- if (!this.workspace.options.gridOptions ||
- !this.workspace.options.gridOptions['snap']) {
+ var grid = this.workspace.getGrid();
+ if (!grid || !grid.shouldSnap()) {
return; // Config says no snapping.
}
- var spacing = this.workspace.options.gridOptions['spacing'];
+ var spacing = grid.getSpacing();
var half = spacing / 2;
var xy = this.getRelativeToSurfaceXY();
var dx = Math.round((xy.x - half) / spacing) * spacing + half - xy.x;
diff --git a/core/grid.js b/core/grid.js
new file mode 100644
index 000000000..e87df6021
--- /dev/null
+++ b/core/grid.js
@@ -0,0 +1,222 @@
+/**
+ * @license
+ * Visual Blocks Editor
+ *
+ * Copyright 2017 Google Inc.
+ * https://developers.google.com/blockly/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileoverview Object for configuring and updating a workspace grid in
+ * Blockly.
+ * @author fenichel@google.com (Rachel Fenichel)
+ */
+'use strict';
+
+goog.provide('Blockly.Grid');
+
+goog.require('Blockly.utils');
+
+goog.require('goog.userAgent');
+
+
+/**
+ * Class for a workspace's grid.
+ * @param {!SVGElement} pattern The grid's SVG pattern, created during injection.
+ * @param {!Object} options A dictionary of normalized options for the grid.
+ * See grid documentation:
+ * https://developers.google.com/blockly/guides/configure/web/grid
+ * @constructor
+ */
+Blockly.Grid = function(pattern, options) {
+ /**
+ * The grid's SVG pattern, created during injection.
+ * @type {!SVGElement}
+ * @private
+ */
+ this.gridPattern_ = pattern;
+
+ /**
+ * The spacing of the grid lines (in px).
+ * @type {number}
+ * @private
+ */
+ this.spacing_ = options['spacing'];
+
+ /**
+ * How long the grid lines should be (in px).
+ * @type {number}
+ * @private
+ */
+ this.length_ = options['length'];
+
+ /**
+ * The horizontal grid line, if it exists.
+ * @type {SVGElement}
+ * @private
+ */
+ this.line1_ = pattern.firstChild;
+
+ /**
+ * The vertical grid line, if it exists.
+ * @type {SVGElement}
+ * @private
+ */
+ this.line2_ = this.line1_ && this.line1_.nextSibling;
+
+ /**
+ * Whether blocks should snap to the grid.
+ * @type {boolean}
+ * @private
+ */
+ this.snapToGrid_ = options['snap'];
+};
+
+/**
+ * The scale of the grid, used to set stroke width on grid lines.
+ * This should always be the same as the workspace scale.
+ * @type {number}
+ * @private
+ */
+Blockly.Grid.prototype.scale_ = 1;
+
+/**
+ * Dispose of this grid and unlink from the DOM.
+ * @package
+ */
+Blockly.Grid.prototype.dispose = function() {
+ this.gridPattern_ = null;
+};
+
+/**
+ * Whether blocks should snap to the grid, based on the initial configuration.
+ * @return {boolean} True if blocks should snap, false otherwise.
+ * @package
+ */
+Blockly.Grid.prototype.shouldSnap = function() {
+ return this.snapToGrid_;
+};
+
+/**
+ * Get the spacing of the grid points (in px).
+ * @return {number} The spacing of the grid points.
+ * @package
+ */
+Blockly.Grid.prototype.getSpacing = function() {
+ return this.spacing_;
+};
+
+/**
+ * Get the id of the pattern element, which should be randomized to avoid
+ * conflicts with other Blockly instances on the page.
+ * @return {string} The pattern id.
+ * @package
+ */
+Blockly.Grid.prototype.getPatternId = function() {
+ return this.gridPattern_.id;
+};
+
+/**
+ * Update the grid with a new scale.
+ * @param {number} scale The new workspace scale.
+ * @package
+ */
+Blockly.Grid.prototype.update = function(scale) {
+ this.scale_ = scale;
+ // MSIE freaks if it sees a 0x0 pattern, so set empty patterns to 100x100.
+ var safeSpacing = (this.spacing_ * scale) || 100;
+
+ this.gridPattern_.setAttribute('width', safeSpacing);
+ this.gridPattern_.setAttribute('height', safeSpacing);
+
+ var half = Math.floor(this.spacing_ / 2) + 0.5;
+ var start = half - this.length_ / 2;
+ var end = half + this.length_ / 2;
+
+ half *= scale;
+ start *= scale;
+ end *= scale;
+
+ this.setLineAttributes_(this.line1_, scale, start, end, half, half);
+ this.setLineAttributes_(this.line2_, scale, half, half, start, end);
+};
+
+/**
+ * Set the attributes on one of the lines in the grid. Use this to update the
+ * length and stroke width of the grid lines.
+ * @param {!SVGElement} line Which line to update.
+ * @param {number} width The new stroke size (in px).
+ * @param {number} x1 The new x start position of the line (in px).
+ * @param {number} x2 The new x end position of the line (in px).
+ * @param {number} y1 The new y start position of the line (in px).
+ * @param {number} y2 The new y end position of the line (in px).
+ * @private
+ */
+Blockly.Grid.prototype.setLineAttributes_ = function(line, width, x1, x2, y1, y2) {
+ if (line) {
+ line.setAttribute('stroke-width', width);
+ line.setAttribute('x1', x1);
+ line.setAttribute('y1', y1);
+ line.setAttribute('x2', x2);
+ line.setAttribute('y2', y2);
+ }
+};
+
+/**
+ * Move the grid to a new x and y position, and make sure that change is visible.
+ * @param {number} x The new x position of the grid (in px).
+ * @param {number} y The new y position ofthe grid (in px).
+ * @package
+ */
+Blockly.Grid.prototype.moveTo = function(x, y) {
+ this.gridPattern_.setAttribute('x', x);
+ this.gridPattern_.setAttribute('y', y);
+
+ if (goog.userAgent.IE || goog.userAgent.EDGE) {
+ // IE/Edge doesn't notice that the x/y offsets have changed.
+ // Force an update.
+ this.update(this.scale_);
+ }
+};
+
+/**
+ * Create the DOM for the grid described by options.
+ * @param {string} rnd A random ID to append to the pattern's ID.
+ * @param {!Object} gridOptions The object containing grid configuration.
+ * @param {!SVGElement} defs The root SVG element for this workspace's defs.
+ * @return {!SVGElement} The SVG element for the grid pattern.
+ * @package
+ */
+Blockly.Grid.createDom = function(rnd, gridOptions, defs) {
+ /*
+
+
+
+
+ */
+ var gridPattern = Blockly.utils.createSvgElement('pattern',
+ {'id': 'blocklyGridPattern' + rnd,
+ 'patternUnits': 'userSpaceOnUse'}, defs);
+ if (gridOptions['length'] > 0 && gridOptions['spacing'] > 0) {
+ Blockly.utils.createSvgElement('line',
+ {'stroke': gridOptions['colour']}, gridPattern);
+ if (gridOptions['length'] > 1) {
+ Blockly.utils.createSvgElement('line',
+ {'stroke': gridOptions['colour']}, gridPattern);
+ }
+ // x1, y1, x1, x2 properties will be set later in update.
+ }
+ return gridPattern;
+};
diff --git a/core/inject.js b/core/inject.js
index cc24a5fe0..ff196202e 100644
--- a/core/inject.js
+++ b/core/inject.js
@@ -28,6 +28,7 @@ goog.provide('Blockly.inject');
goog.require('Blockly.BlockDragSurfaceSvg');
goog.require('Blockly.Css');
+goog.require('Blockly.Grid');
goog.require('Blockly.Options');
goog.require('Blockly.WorkspaceSvg');
goog.require('Blockly.WorkspaceDragSurfaceSvg');
@@ -164,27 +165,8 @@ Blockly.createDom_ = function(container, options) {
Blockly.utils.createSvgElement('path',
{'d': 'M 0 0 L 10 10 M 10 0 L 0 10', 'stroke': '#cc0'}, disabledPattern);
options.disabledPatternId = disabledPattern.id;
- /*
-
-
-
-
- */
- var gridPattern = Blockly.utils.createSvgElement('pattern',
- {'id': 'blocklyGridPattern' + rnd,
- 'patternUnits': 'userSpaceOnUse'}, defs);
- if (options.gridOptions['length'] > 0 && options.gridOptions['spacing'] > 0) {
- Blockly.utils.createSvgElement('line',
- {'stroke': options.gridOptions['colour']},
- gridPattern);
- if (options.gridOptions['length'] > 1) {
- Blockly.utils.createSvgElement('line',
- {'stroke': options.gridOptions['colour']},
- gridPattern);
- }
- // x1, y1, x1, x2 properties will be set later in updateGridPattern_.
- }
- options.gridPattern = gridPattern;
+
+ options.gridPattern = Blockly.Grid.createDom(rnd, options.gridOptions, defs);
return svg;
};
diff --git a/core/workspace_svg.js b/core/workspace_svg.js
index 461163ed2..38e63aefb 100644
--- a/core/workspace_svg.js
+++ b/core/workspace_svg.js
@@ -31,6 +31,7 @@ goog.provide('Blockly.WorkspaceSvg');
goog.require('Blockly.ConnectionDB');
goog.require('Blockly.constants');
goog.require('Blockly.Gesture');
+goog.require('Blockly.Grid');
goog.require('Blockly.Options');
goog.require('Blockly.ScrollbarPair');
goog.require('Blockly.Touch');
@@ -93,6 +94,14 @@ Blockly.WorkspaceSvg = function(options, opt_blockDragSurface, opt_wsDragSurface
*/
this.audioManager_ = new Blockly.WorkspaceAudio(options.parentWorkspace);
+ /**
+ * This workspace's grid object or null.
+ * @type {Blockly.Grid}
+ * @private
+ */
+ this.grid_ = this.options.gridPattern ?
+ new Blockly.Grid(options.gridPattern, options.gridOptions) : null;
+
this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,
Blockly.Variables.flyoutCategory);
this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME,
@@ -342,9 +351,9 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
{'height': '100%', 'width': '100%', 'class': opt_backgroundClass},
this.svgGroup_);
- if (opt_backgroundClass == 'blocklyMainBackground') {
+ if (opt_backgroundClass == 'blocklyMainBackground' && this.grid_) {
this.svgBackground_.style.fill =
- 'url(#' + this.options.gridPattern.id + ')';
+ 'url(#' + this.grid_.getPatternId() + ')';
}
}
/** @type {SVGElement} */
@@ -380,7 +389,9 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
*/
this.toolbox_ = new Blockly.Toolbox(this);
}
- this.updateGridPattern_();
+ if (this.grid_) {
+ this.grid_.update(this.scale);
+ }
this.recordDeleteAreas();
return this.svgGroup_;
};
@@ -428,6 +439,11 @@ Blockly.WorkspaceSvg.prototype.dispose = function() {
this.audioManager_ = null;
}
+ if (this.grid_) {
+ this.grid_.dispose();
+ this.grid_ = null;
+ }
+
if (this.toolboxCategoryCallbacks_) {
this.toolboxCategoryCallbacks_ = null;
}
@@ -1395,7 +1411,9 @@ Blockly.WorkspaceSvg.prototype.setScale = function(newScale) {
newScale = this.options.zoomOptions.minScale;
}
this.scale = newScale;
- this.updateGridPattern_();
+ if (this.grid_) {
+ this.grid_.update(this.scale);
+ }
if (this.scrollbar) {
this.scrollbar.resize();
} else {
@@ -1408,43 +1426,6 @@ Blockly.WorkspaceSvg.prototype.setScale = function(newScale) {
}
};
-/**
- * Updates the grid pattern.
- * @private
- */
-Blockly.WorkspaceSvg.prototype.updateGridPattern_ = function() {
- if (!this.options.gridPattern) {
- return; // No grid.
- }
- // MSIE freaks if it sees a 0x0 pattern, so set empty patterns to 100x100.
- var safeSpacing = (this.options.gridOptions['spacing'] * this.scale) || 100;
- this.options.gridPattern.setAttribute('width', safeSpacing);
- this.options.gridPattern.setAttribute('height', safeSpacing);
- var half = Math.floor(this.options.gridOptions['spacing'] / 2) + 0.5;
- var start = half - this.options.gridOptions['length'] / 2;
- var end = half + this.options.gridOptions['length'] / 2;
- var line1 = this.options.gridPattern.firstChild;
- var line2 = line1 && line1.nextSibling;
- half *= this.scale;
- start *= this.scale;
- end *= this.scale;
- if (line1) {
- line1.setAttribute('stroke-width', this.scale);
- line1.setAttribute('x1', start);
- line1.setAttribute('y1', half);
- line1.setAttribute('x2', end);
- line1.setAttribute('y2', half);
- }
- if (line2) {
- line2.setAttribute('stroke-width', this.scale);
- line2.setAttribute('x1', half);
- line2.setAttribute('y1', start);
- line2.setAttribute('x2', half);
- line2.setAttribute('y2', end);
- }
-};
-
-
/**
* Return an object with all the metrics required to size scrollbars for a
* top level workspace. The following properties are computed:
@@ -1560,14 +1541,8 @@ Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_ = function(xyRatio) {
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 || goog.userAgent.EDGE) {
- // IE/Edge doesn't notice that the x/y offsets have changed.
- // Force an update.
- this.updateGridPattern_();
- }
+ if (this.grid_) {
+ this.grid_.moveTo(x, y);
}
};
@@ -1729,6 +1704,15 @@ Blockly.WorkspaceSvg.prototype.getAudioManager = function() {
return this.audioManager_;
};
+/**
+ * Get the grid object for this workspace, or null if there is none.
+ * @return {Blockly.Grid} The grid object for this workspace.
+ * @package
+ */
+Blockly.WorkspaceSvg.prototype.getGrid = function() {
+ return this.grid_;
+};
+
// Export symbols that would otherwise be renamed by Closure compiler.
Blockly.WorkspaceSvg.prototype['setVisible'] =
Blockly.WorkspaceSvg.prototype.setVisible;