diff --git a/core/block_svg.js b/core/block_svg.js index 783d4fff3..021c83dbc 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -264,7 +264,8 @@ Blockly.BlockSvg.terminateDrag = function() { delete selected.draggedBubbles_; selected.setDragging_(false); selected.render(); - // Ensure that any stap and bump are part of this move's event group. + selected.workspace.setResizesEnabled(true); + // Ensure that any snap and bump are part of this move's event group. var group = Blockly.Events.getGroup(); setTimeout(function() { Blockly.Events.setGroup(group); @@ -276,8 +277,6 @@ Blockly.BlockSvg.terminateDrag = function() { selected.bumpNeighbours_(); Blockly.Events.setGroup(false); }, Blockly.BUMP_DELAY); - // Fire an event to allow scrollbars to resize. - selected.workspace.resizeContents(); } } Blockly.dragMode_ = Blockly.DRAG_NONE; @@ -872,6 +871,7 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) { // Switch to unrestricted dragging. Blockly.dragMode_ = Blockly.DRAG_FREE; Blockly.longStop_(); + this.workspace.setResizesEnabled(false); if (this.parentBlock_) { // Push this block to the very top of the stack. this.unplug(); diff --git a/core/flyout.js b/core/flyout.js index c872f9252..48e1c5a39 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -1109,6 +1109,8 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) { block.onMouseDown_(e); Blockly.dragMode_ = Blockly.DRAG_FREE; block.setDragging_(true); + // Disable workspace resizing. Reenable at the end of the drag. + flyout.targetWorkspace_.setResizesEnabled(false); }; }; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 64067912b..8cdb06b6e 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -110,6 +110,14 @@ Blockly.WorkspaceSvg.prototype.isMutator = false; */ Blockly.WorkspaceSvg.prototype.dragMode_ = Blockly.DRAG_NONE; +/** + * Whether this workspace has resizes enabled. + * Disable during batch operations for a performance improvement. + * @type {boolean} + * @private + */ +Blockly.WorkspaceSvg.prototype.resizesEnabled_ = true; + /** * Current horizontal scrolling offset. * @type {number} @@ -396,12 +404,15 @@ Blockly.WorkspaceSvg.prototype.updateScreenCalculations_ = function() { }; /** - * Resize the parts of the workspace that change when the workspace + * If enabled, resize the parts of the workspace that change when the workspace * contents (e.g. block positions) change. This will also scroll the * workspace contents if needed. * @package */ Blockly.WorkspaceSvg.prototype.resizeContents = function() { + if (!this.resizesEnabled_) { + return; + } if (this.scrollbar) { // TODO(picklesrus): Once rachel-fenichel's scrollbar refactoring // is complete, call the method that only resizes scrollbar @@ -1420,6 +1431,32 @@ Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_ = function(xyRatio) { } } }; + +/** + * Update whether this workspace has resizes enabled. + * If enabled, workspace will resize when appropriate. + * If disabled, workspace will not resize until re-enabled. + * Use to avoid resizing during a batch operation, for performance. + * @param {boolean} enabled Whether resizes should be enabled. + */ +Blockly.WorkspaceSvg.prototype.setResizesEnabled = function(enabled) { + var reenabled = (!this.resizesEnabled_ && enabled); + this.resizesEnabled_ = enabled; + if (reenabled) { + // Newly enabled. Trigger a resize. + this.resizeContents(); + } +}; + +/** + * Dispose of all blocks in workspace, with an optimization to prevent resizes. + */ +Blockly.WorkspaceSvg.prototype.clear = function() { + this.setResizesEnabled(false); + Blockly.WorkspaceSvg.superClass_.clear.call(this); + this.setResizesEnabled(true); +}; + // 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 0ebd31e0b..63a6b952d 100644 --- a/core/xml.js +++ b/core/xml.js @@ -296,6 +296,11 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) { if (!existingGroup) { Blockly.Events.setGroup(true); } + + // Disable workspace resizes as an optimization. + if (workspace.setResizesEnabled) { + workspace.setResizesEnabled(false); + } for (var i = 0; i < childCount; i++) { var xmlChild = xml.childNodes[i]; var name = xmlChild.nodeName.toLowerCase(); @@ -320,6 +325,10 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) { Blockly.Field.stopCache(); workspace.updateVariableList(false); + // Re-enable workspace resizing. + if (workspace.setResizesEnabled) { + workspace.setResizesEnabled(true); + } }; /**