Move bump objects function into a separate module (#5453)

* Move bump objects function into a separate module

* Fix types

* Update core/bump_objects.js

Fix missing newline.

Co-authored-by: Christopher Allen <cpcallen+github@gmail.com>

Co-authored-by: Christopher Allen <cpcallen+github@gmail.com>
This commit is contained in:
Rachel Fenichel
2021-09-14 10:02:38 -07:00
committed by GitHub
parent ce8e7921a2
commit f4430e9e47
4 changed files with 84 additions and 59 deletions

View File

@@ -24,6 +24,7 @@ const InsertionMarkerManager = goog.require('Blockly.InsertionMarkerManager');
/* eslint-disable-next-line no-unused-vars */
const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg');
const blockAnimation = goog.require('Blockly.blockAnimations');
const bumpObjects = goog.require('Blockly.bumpObjects');
const common = goog.require('Blockly.common');
const dom = goog.require('Blockly.utils.dom');
const events = goog.require('Blockly.Events');
@@ -293,7 +294,7 @@ BlockDragger.prototype.endDrag = function(e, currentDragDeltaXY) {
} else {
// Blocks dragged directly from a flyout may need to be bumped into
// bounds.
Blockly.bumpObjectIntoBounds_(
bumpObjects.bumpIntoBounds(
this.draggingBlock_.workspace,
this.workspace_.getMetricsManager().getScrollMetrics(true),
this.draggingBlock_);

73
core/bump_objects.js Normal file
View File

@@ -0,0 +1,73 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Utilities for bumping objects back into worksapce bounds.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.module('Blockly.bumpObjects');
/* eslint-disable-next-line no-unused-vars */
const IBoundedElement = goog.requireType('Blockly.IBoundedElement');
/* eslint-disable-next-line no-unused-vars */
const MetricsManager = goog.requireType('Blockly.MetricsManager');
/* eslint-disable-next-line no-unused-vars */
const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg');
const mathUtils = goog.require('Blockly.utils.math');
/**
* Bumps the given object that has passed out of bounds.
* @param {!WorkspaceSvg} workspace The workspace containing the object.
* @param {!MetricsManager.ContainerRegion} scrollMetrics Scroll metrics
* in workspace coordinates.
* @param {!IBoundedElement} object The object to bump.
* @return {boolean} True if block was bumped.
*/
const bumpObjectIntoBounds = function(workspace, scrollMetrics, object) {
// Compute new top/left position for object.
const objectMetrics = object.getBoundingRectangle();
const height = objectMetrics.bottom - objectMetrics.top;
const width = objectMetrics.right - objectMetrics.left;
const topClamp = scrollMetrics.top;
const scrollMetricsBottom = scrollMetrics.top + scrollMetrics.height;
const bottomClamp = scrollMetricsBottom - height;
// If the object is taller than the workspace we want to
// top-align the block
const newYPosition =
mathUtils.clamp(topClamp, objectMetrics.top, bottomClamp);
const deltaY = newYPosition - objectMetrics.top;
// Note: Even in RTL mode the "anchor" of the object is the
// top-left corner of the object.
let leftClamp = scrollMetrics.left;
const scrollMetricsRight = scrollMetrics.left + scrollMetrics.width;
let rightClamp = scrollMetricsRight - width;
if (workspace.RTL) {
// If the object is wider than the workspace and we're in RTL
// mode we want to right-align the block, which means setting
// the left clamp to match.
leftClamp = Math.min(rightClamp, leftClamp);
} else {
// If the object is wider than the workspace and we're in LTR
// mode we want to left-align the block, which means setting
// the right clamp to match.
rightClamp = Math.max(leftClamp, rightClamp);
}
const newXPosition =
mathUtils.clamp(leftClamp, objectMetrics.left, rightClamp);
const deltaX = newXPosition - objectMetrics.left;
if (deltaX || deltaY) {
object.moveBy(deltaX, deltaY);
return true;
}
return false;
};
exports.bumpIntoBounds = bumpObjectIntoBounds;

View File

@@ -14,6 +14,7 @@ goog.provide('Blockly.inject');
goog.require('Blockly.BlockDragSurfaceSvg');
goog.require('Blockly.browserEvents');
goog.require('Blockly.bumpObjects');
goog.require('Blockly.common');
goog.require('Blockly.Css');
goog.require('Blockly.DropDownDiv');
@@ -27,7 +28,6 @@ goog.require('Blockly.Tooltip');
goog.require('Blockly.utils');
goog.require('Blockly.utils.aria');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.math');
goog.require('Blockly.utils.Svg');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.Workspace');
@@ -239,7 +239,7 @@ Blockly.bumpTopObjectsIntoBounds_ = function(workspace) {
var scrollMetricsInWsCoords = metricsManager.getScrollMetrics(true);
var topBlocks = workspace.getTopBoundedElements();
for (var i = 0, block; (block = topBlocks[i]); i++) {
Blockly.bumpObjectIntoBounds_(workspace, scrollMetricsInWsCoords, block);
goog.module.get('Blockly.bumpObjects').bumpIntoBounds(workspace, scrollMetricsInWsCoords, block);
}
};
@@ -268,9 +268,10 @@ Blockly.bumpIntoBoundsHandler_ = function(workspace) {
var oldGroup = Blockly.Events.getGroup();
Blockly.Events.setGroup(e.group);
var wasBumped = Blockly.bumpObjectIntoBounds_(
workspace, scrollMetricsInWsCoords,
/** @type {!Blockly.IBoundedElement} */ (object));
var wasBumped = goog.module.get('Blockly.bumpObjects')
.bumpIntoBounds(
workspace, scrollMetricsInWsCoords,
/** @type {!Blockly.IBoundedElement} */ (object));
if (wasBumped && !e.group) {
console.warn('Moved object in bounds but there was no' +
@@ -288,57 +289,6 @@ Blockly.bumpIntoBoundsHandler_ = function(workspace) {
};
};
/**
* Bumps the given object that has passed out of bounds.
* @param {!Blockly.WorkspaceSvg} workspace The workspace containing the object.
* @param {!Blockly.MetricsManager.ContainerRegion} scrollMetrics Scroll metrics
* in workspace coordinates.
* @param {!Blockly.IBoundedElement} object The object to bump.
* @return {boolean} True if block was bumped.
* @package
*/
Blockly.bumpObjectIntoBounds_ = function(workspace, scrollMetrics, object) {
// Compute new top/left position for object.
var objectMetrics = object.getBoundingRectangle();
var height = objectMetrics.bottom - objectMetrics.top;
var width = objectMetrics.right - objectMetrics.left;
var topClamp = scrollMetrics.top;
var scrollMetricsBottom = scrollMetrics.top + scrollMetrics.height;
var bottomClamp = scrollMetricsBottom - height;
// If the object is taller than the workspace we want to
// top-align the block
var newYPosition =
Blockly.utils.math.clamp(topClamp, objectMetrics.top, bottomClamp);
var deltaY = newYPosition - objectMetrics.top;
// Note: Even in RTL mode the "anchor" of the object is the
// top-left corner of the object.
var leftClamp = scrollMetrics.left;
var scrollMetricsRight = scrollMetrics.left + scrollMetrics.width;
var rightClamp = scrollMetricsRight - width;
if (workspace.RTL) {
// If the object is wider than the workspace and we're in RTL
// mode we want to right-align the block, which means setting
// the left clamp to match.
leftClamp = Math.min(rightClamp, leftClamp);
} else {
// If the object is wider than the workspace and we're in LTR
// mode we want to left-align the block, which means setting
// the right clamp to match.
rightClamp = Math.max(leftClamp, rightClamp);
}
var newXPosition =
Blockly.utils.math.clamp(leftClamp, objectMetrics.left, rightClamp);
var deltaX = newXPosition - objectMetrics.left;
if (deltaX || deltaY) {
object.moveBy(deltaX, deltaY);
return true;
}
return false;
};
/**
* Initialize Blockly with various handlers.
* @param {!Blockly.WorkspaceSvg} mainWorkspace Newly created main workspace.

View File

@@ -10,7 +10,7 @@ goog.addDependency('../../blocks/variables_dynamic.js', ['Blockly.Constants.Vari
goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.ASTNode', 'Blockly.Blocks', 'Blockly.Connection', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Tooltip', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.inputTypes', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.idGenerator', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'], ['Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.common', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.bumpObjects', 'Blockly.common', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Selected', 'Blockly.FieldLabel', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Xml', 'Blockly.blockAnimations', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.ComponentManager', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Events.VarCreate', 'Blockly.Procedures', 'Blockly.ShortcutRegistry', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.clipboard', 'Blockly.common', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.dialog', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.toolbox']);
goog.addDependency('../../core/blockly_options.js', ['Blockly.BlocklyOptions'], [], {'lang': 'es6', 'module': 'goog'});
@@ -18,6 +18,7 @@ goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {'lang': 'es6
goog.addDependency('../../core/browser_events.js', ['Blockly.browserEvents'], ['Blockly.Touch', 'Blockly.utils.global'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/bubble.js', ['Blockly.Bubble'], ['Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/bubble_dragger.js', ['Blockly.BubbleDragger'], ['Blockly.Bubble', 'Blockly.ComponentManager', 'Blockly.Events', 'Blockly.Events.CommentMove', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/bump_objects.js', ['Blockly.bumpObjects'], ['Blockly.utils.math'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/clipboard.js', ['Blockly.clipboard'], ['Blockly.Events'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.browserEvents', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/common.js', ['Blockly.common'], [], {'lang': 'es6', 'module': 'goog'});
@@ -86,7 +87,7 @@ goog.addDependency('../../core/generator.js', ['Blockly.Generator'], ['Blockly.c
goog.addDependency('../../core/gesture.js', ['Blockly.Gesture'], ['Blockly.BlockDragger', 'Blockly.BubbleDragger', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.WorkspaceDragger', 'Blockly.blockAnimations', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/grid.js', ['Blockly.Grid'], ['Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/icon.js', ['Blockly.Icon'], ['Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/inject.js', ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Grid', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent']);
goog.addDependency('../../core/inject.js', ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Grid', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.browserEvents', 'Blockly.bumpObjects', 'Blockly.common', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.userAgent']);
goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.FieldLabel', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.inputTypes'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/input_types.js', ['Blockly.inputTypes'], ['Blockly.connectionTypes'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.ComponentManager', 'Blockly.Events', 'Blockly.blockAnimations', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.internalConstants'], {'lang': 'es6', 'module': 'goog'});