mirror of
https://github.com/google/blockly.git
synced 2026-01-09 01:50:11 +01:00
3
.clang-format
Normal file
3
.clang-format
Normal file
@@ -0,0 +1,3 @@
|
||||
Language: JavaScript
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 80
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -3,7 +3,7 @@
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on: push
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
.*
|
||||
*.soy
|
||||
*.komodoproject
|
||||
/deploy
|
||||
deploy
|
||||
/static/appengine/
|
||||
/static/closure/
|
||||
/static/demos/plane/soy/*.jar
|
||||
/static/demos/plane/xlf/
|
||||
/static/externs/
|
||||
/static/msg/json/
|
||||
/static/node_modules/
|
||||
/static/scripts/
|
||||
/static/typings/
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to deploy on GAE.
|
||||
|
||||
APP=./app.yaml
|
||||
if ! [ -f $APP ] ; then
|
||||
echo $APP not found 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT=blockly-demo
|
||||
VERSION=37
|
||||
|
||||
echo 'Beginning deployment...'
|
||||
gcloud app deploy --project $PROJECT --version $VERSION --no-promote
|
||||
echo 'Deployment finished.'
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -21,26 +21,28 @@ this.BLOCKLY_DIR = (function(root) {
|
||||
|
||||
this.BLOCKLY_BOOT = function(root) {
|
||||
// Execute after Closure has loaded.
|
||||
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.Workspace', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.deprecation', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es5'});
|
||||
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.Workspace', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.inputTypes', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'], ['Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
|
||||
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.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Procedures', 'Blockly.ShortcutRegistry', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour'], {});
|
||||
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.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Xml', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.browserEvents', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/blockly.js', ['Blockly'], ['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.connectionTypes', 'Blockly.constants', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {});
|
||||
goog.addDependency('../../core/bubble.js', ['Blockly.Bubble'], ['Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/browser_events.js', ['Blockly.browserEvents'], ['Blockly.Touch'], {});
|
||||
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'], {});
|
||||
goog.addDependency('../../core/bubble_dragger.js', ['Blockly.BubbleDragger'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.CommentMove', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/connection.js', ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.deprecation'], {});
|
||||
goog.addDependency('../../core/connection_checker.js', ['Blockly.ConnectionChecker'], ['Blockly.constants', 'Blockly.registry'], {});
|
||||
goog.addDependency('../../core/connection_db.js', ['Blockly.ConnectionDB'], ['Blockly.RenderedConnection', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/constants.js', ['Blockly.constants'], [], {});
|
||||
goog.addDependency('../../core/contextmenu.js', ['Blockly.ContextMenu'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.Msg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems'], ['Blockly.constants'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/contextmenu_registry.js', ['Blockly.ContextMenuRegistry'], ['Blockly.ContextMenuItems'], {'lang': 'es5'});
|
||||
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'], {});
|
||||
goog.addDependency('../../core/connection.js', ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Xml', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.deprecation'], {});
|
||||
goog.addDependency('../../core/connection_checker.js', ['Blockly.ConnectionChecker'], ['Blockly.Connection', 'Blockly.IConnectionChecker', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.registry'], {});
|
||||
goog.addDependency('../../core/connection_db.js', ['Blockly.ConnectionDB'], ['Blockly.RenderedConnection', 'Blockly.connectionTypes', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/connection_types.js', ['Blockly.connectionTypes'], [], {});
|
||||
goog.addDependency('../../core/constants.js', ['Blockly.constants'], ['Blockly.connectionTypes'], {});
|
||||
goog.addDependency('../../core/contextmenu.js', ['Blockly.ContextMenu'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.Msg', 'Blockly.WidgetDiv', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems'], ['Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.constants', 'Blockly.inputTypes'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/contextmenu_registry.js', ['Blockly.ContextMenuRegistry'], [], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/css.js', ['Blockly.Css'], [], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/dropdowndiv.js', ['Blockly.DropDownDiv'], ['Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.style'], {});
|
||||
goog.addDependency('../../core/events/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/dropdowndiv.js', ['Blockly.DropDownDiv'], ['Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.style'], {});
|
||||
goog.addDependency('../../core/events/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.Xml', 'Blockly.connectionTypes', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/events/events.js', ['Blockly.Events'], ['Blockly.registry', 'Blockly.utils'], {});
|
||||
goog.addDependency('../../core/events/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {});
|
||||
goog.addDependency('../../core/events/events_block_drag.js', ['Blockly.Events.BlockDrag'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {});
|
||||
@@ -55,34 +57,34 @@ goog.addDependency('../../core/events/events_viewport.js', ['Blockly.Events.View
|
||||
goog.addDependency('../../core/events/ui_events.js', ['Blockly.Events.Ui', 'Blockly.Events.UiBase'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/events/variable_events.js', ['Blockly.Events.VarBase', 'Blockly.Events.VarCreate', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/events/workspace_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/events/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/events/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/extensions.js', ['Blockly.Extensions'], ['Blockly.utils'], {});
|
||||
goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.Tooltip', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/field_angle.js', ['Blockly.FieldAngle'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.FieldTextInput', 'Blockly.fieldRegistry', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_checkbox.js', ['Blockly.FieldCheckbox'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_colour.js', ['Blockly.FieldColour'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils.IdGenerator', 'Blockly.utils.KeyCodes', 'Blockly.utils.Size', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_dropdown.js', ['Blockly.FieldDropdown'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.string', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.Tooltip', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/field_angle.js', ['Blockly.FieldAngle'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.FieldTextInput', 'Blockly.browserEvents', 'Blockly.fieldRegistry', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_checkbox.js', ['Blockly.FieldCheckbox'], ['Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_colour.js', ['Blockly.FieldColour'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.browserEvents', 'Blockly.fieldRegistry', 'Blockly.utils.IdGenerator', 'Blockly.utils.KeyCodes', 'Blockly.utils.Size', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_dropdown.js', ['Blockly.FieldDropdown'], ['Blockly.Field', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.string', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_image.js', ['Blockly.FieldImage'], ['Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_label.js', ['Blockly.FieldLabel'], ['Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_label.js', ['Blockly.FieldLabel'], ['Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_label_serializable.js', ['Blockly.FieldLabelSerializable'], ['Blockly.FieldLabel', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_multilineinput.js', ['Blockly.FieldMultilineInput'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.FieldTextInput', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/field_multilineinput.js', ['Blockly.FieldMultilineInput'], ['Blockly.Css', 'Blockly.FieldTextInput', 'Blockly.utils', 'Blockly.utils.KeyCodes', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/field_number.js', ['Blockly.FieldNumber'], ['Blockly.FieldTextInput', 'Blockly.fieldRegistry', 'Blockly.utils.aria', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/field_registry.js', ['Blockly.fieldRegistry'], ['Blockly.registry'], {});
|
||||
goog.addDependency('../../core/field_textinput.js', ['Blockly.FieldTextInput'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.Size', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_variable.js', ['Blockly.FieldVariable'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.Xml', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/flyout_base.js', ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.VarCreate', 'Blockly.FlyoutCursor', 'Blockly.Gesture', 'Blockly.Marker', 'Blockly.Scrollbar', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/flyout_button.js', ['Blockly.FlyoutButton'], ['Blockly.Css', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/flyout_dragger.js', ['Blockly.FlyoutDragger'], ['Blockly.WorkspaceDragger', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/flyout_horizontal.js', ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/flyout_vertical.js', ['Blockly.VerticalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_textinput.js', ['Blockly.FieldTextInput'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.browserEvents', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/field_variable.js', ['Blockly.FieldVariable'], ['Blockly.Events.BlockChange', 'Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.Xml', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/flyout_base.js', ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.VarCreate', 'Blockly.FlyoutMetricsManager', 'Blockly.Gesture', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/flyout_button.js', ['Blockly.FlyoutButton'], ['Blockly.Css', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/flyout_horizontal.js', ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/flyout_vertical.js', ['Blockly.VerticalFlyout'], ['Blockly.Block', 'Blockly.Flyout', 'Blockly.Scrollbar', 'Blockly.WidgetDiv', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/generator.js', ['Blockly.Generator'], ['Blockly.Block', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/gesture.js', ['Blockly.Gesture'], ['Blockly.ASTNode', 'Blockly.BlockDragger', 'Blockly.BubbleDragger', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'Blockly.blockAnimations', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/gesture.js', ['Blockly.Gesture'], ['Blockly.BlockDragger', 'Blockly.BubbleDragger', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'Blockly.blockAnimations', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/grid.js', ['Blockly.Grid'], ['Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/icon.js', ['Blockly.Icon'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
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.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations', 'Blockly.constants'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/interfaces/i_accessibility.js', ['Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IBlocklyActionable'], [], {});
|
||||
goog.addDependency('../../core/icon.js', ['Blockly.Icon'], ['Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
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.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'Blockly.constants', 'Blockly.fieldRegistry', 'Blockly.inputTypes'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/input_types.js', ['Blockly.inputTypes'], ['Blockly.connectionTypes'], {});
|
||||
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations', 'Blockly.connectionTypes', 'Blockly.constants'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/interfaces/i_accessibility.js', ['Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IKeyboardAccessible'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_bounded_element.js', ['Blockly.IBoundedElement'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_bubble.js', ['Blockly.IBubble'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_connection_checker.js', ['Blockly.IConnectionChecker'], [], {});
|
||||
@@ -91,50 +93,54 @@ goog.addDependency('../../core/interfaces/i_copyable.js', ['Blockly.ICopyable'],
|
||||
goog.addDependency('../../core/interfaces/i_deletable.js', ['Blockly.IDeletable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_deletearea.js', ['Blockly.IDeleteArea'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_flyout.js', ['Blockly.IFlyout'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_metrics_manager.js', ['Blockly.IMetricsManager'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_movable.js', ['Blockly.IMovable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_plugin.js', ['Blockly.IPlugin'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_positionable.js', ['Blockly.IPositionable'], ['Blockly.IPlugin'], {});
|
||||
goog.addDependency('../../core/interfaces/i_registrable.js', ['Blockly.IRegistrable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_registrable_field.js', ['Blockly.IRegistrableField'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_selectable.js', ['Blockly.ISelectable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_styleable.js', ['Blockly.IStyleable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_toolbox.js', ['Blockly.IToolbox'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_toolbox_item.js', ['Blockly.ICollapsibleToolboxItem', 'Blockly.ISelectableToolboxItem', 'Blockly.IToolboxItem'], [], {});
|
||||
goog.addDependency('../../core/keyboard_nav/ast_node.js', ['Blockly.ASTNode'], ['Blockly.constants', 'Blockly.utils.Coordinate'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/basic_cursor.js', ['Blockly.BasicCursor'], ['Blockly.ASTNode', 'Blockly.Cursor'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/cursor.js', ['Blockly.Cursor'], ['Blockly.ASTNode', 'Blockly.Marker', 'Blockly.navigation', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/flyout_cursor.js', ['Blockly.FlyoutCursor'], ['Blockly.Cursor', 'Blockly.navigation', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/marker.js', ['Blockly.Marker'], ['Blockly.ASTNode', 'Blockly.navigation'], {});
|
||||
goog.addDependency('../../core/keyboard_nav/navigation.js', ['Blockly.navigation'], ['Blockly.ASTNode', 'Blockly.constants', 'Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/interfaces/i_workspace_plugin.js', ['Blockly.IWorkspacePlugin'], [], {});
|
||||
goog.addDependency('../../core/keyboard_nav/ast_node.js', ['Blockly.ASTNode'], ['Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.Coordinate'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/basic_cursor.js', ['Blockly.BasicCursor'], ['Blockly.ASTNode', 'Blockly.Cursor', 'Blockly.registry'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/cursor.js', ['Blockly.Cursor'], ['Blockly.ASTNode', 'Blockly.Marker', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/keyboard_nav/marker.js', ['Blockly.Marker'], ['Blockly.ASTNode'], {});
|
||||
goog.addDependency('../../core/keyboard_nav/tab_navigate_cursor.js', ['Blockly.TabNavigateCursor'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/marker_manager.js', ['Blockly.MarkerManager'], ['Blockly.Cursor', 'Blockly.Marker'], {});
|
||||
goog.addDependency('../../core/menu.js', ['Blockly.Menu'], ['Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.style'], {});
|
||||
goog.addDependency('../../core/menu.js', ['Blockly.Menu'], ['Blockly.browserEvents', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.style'], {});
|
||||
goog.addDependency('../../core/menuitem.js', ['Blockly.MenuItem'], ['Blockly.utils.IdGenerator', 'Blockly.utils.aria', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/metrics_manager.js', ['Blockly.FlyoutMetricsManager', 'Blockly.MetricsManager'], ['Blockly.IMetricsManager', 'Blockly.registry', 'Blockly.utils.Size', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/msg.js', ['Blockly.Msg'], ['Blockly.utils.global'], {});
|
||||
goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.toolbox', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/names.js', ['Blockly.Names'], ['Blockly.Msg', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.IdGenerator', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.registry', 'Blockly.utils.IdGenerator', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/plugin_manager.js', ['Blockly.PluginManager'], [], {});
|
||||
goog.addDependency('../../core/procedures.js', ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.Names', 'Blockly.Workspace', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/registry.js', ['Blockly.registry'], [], {});
|
||||
goog.addDependency('../../core/rendered_connection.js', ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/common/block_rendering.js', ['Blockly.blockRendering'], ['Blockly.registry', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/common/constants.js', ['Blockly.blockRendering.ConstantProvider'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.svgPaths', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/common/debugger.js', ['Blockly.blockRendering.Debug'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/common/drawer.js', ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/rendered_connection.js', ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/common/block_rendering.js', ['Blockly.blockRendering'], ['Blockly.registry'], {});
|
||||
goog.addDependency('../../core/renderers/common/constants.js', ['Blockly.blockRendering.ConstantProvider'], ['Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.svgPaths', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/common/debugger.js', ['Blockly.blockRendering.Debug'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.Types', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/common/drawer.js', ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.Types', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/renderers/common/i_path_object.js', ['Blockly.blockRendering.IPathObject'], [], {});
|
||||
goog.addDependency('../../core/renderers/common/info.js', ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/renderers/common/marker_svg.js', ['Blockly.blockRendering.MarkerSvg'], ['Blockly.ASTNode', 'Blockly.Events.MarkerMove', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/renderers/common/info.js', ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.inputTypes'], {});
|
||||
goog.addDependency('../../core/renderers/common/marker_svg.js', ['Blockly.blockRendering.MarkerSvg'], ['Blockly.ASTNode', 'Blockly.Events', 'Blockly.Events.MarkerMove', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/renderers/common/path_object.js', ['Blockly.blockRendering.PathObject'], ['Blockly.Theme', 'Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.IPathObject', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/renderers/common/renderer.js', ['Blockly.blockRendering.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.IPathObject', 'Blockly.blockRendering.MarkerSvg', 'Blockly.blockRendering.PathObject', 'Blockly.blockRendering.RenderInfo', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/renderers/common/renderer.js', ['Blockly.blockRendering.Renderer'], ['Blockly.IRegistrable', 'Blockly.InsertionMarkerManager', 'Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Debug', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.IPathObject', 'Blockly.blockRendering.MarkerSvg', 'Blockly.blockRendering.PathObject', 'Blockly.blockRendering.RenderInfo', 'Blockly.connectionTypes', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/renderers/geras/constants.js', ['Blockly.geras.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.object'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/geras/drawer.js', ['Blockly.geras.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.geras.Highlighter', 'Blockly.geras.RenderInfo', 'Blockly.utils.object', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/renderers/geras/drawer.js', ['Blockly.geras.Drawer'], ['Blockly.blockRendering.Drawer', 'Blockly.geras.Highlighter', 'Blockly.geras.RenderInfo', 'Blockly.utils.object', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/renderers/geras/highlight_constants.js', ['Blockly.geras.HighlightConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.svgPaths'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/geras/highlighter.js', ['Blockly.geras.Highlighter'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/renderers/geras/info.js', ['Blockly.geras', 'Blockly.geras.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.geras.InlineInput', 'Blockly.geras.StatementInput', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/measurables/inputs.js', ['Blockly.geras.InlineInput', 'Blockly.geras.StatementInput'], ['Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/path_object.js', ['Blockly.geras.PathObject'], ['Blockly.Theme', 'Blockly.blockRendering.PathObject', 'Blockly.geras.ConstantProvider', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/highlighter.js', ['Blockly.geras.Highlighter'], ['Blockly.blockRendering.Types', 'Blockly.utils.svgPaths'], {});
|
||||
goog.addDependency('../../core/renderers/geras/info.js', ['Blockly.geras', 'Blockly.geras.RenderInfo'], ['Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.geras.InlineInput', 'Blockly.geras.StatementInput', 'Blockly.inputTypes', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/measurables/inputs.js', ['Blockly.geras.InlineInput', 'Blockly.geras.StatementInput'], ['Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.StatementInput', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/path_object.js', ['Blockly.geras.PathObject'], ['Blockly.Theme', 'Blockly.blockRendering.PathObject', 'Blockly.geras.ConstantProvider', 'Blockly.utils.Svg', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/geras/renderer.js', ['Blockly.geras.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.geras.ConstantProvider', 'Blockly.geras.Drawer', 'Blockly.geras.HighlightConstantProvider', 'Blockly.geras.PathObject', 'Blockly.geras.RenderInfo', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/base.js', ['Blockly.blockRendering.Measurable'], ['Blockly.blockRendering.Types'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/connections.js', ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/inputs.js', ['Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputConnection', 'Blockly.blockRendering.StatementInput'], ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/inputs.js', ['Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputConnection', 'Blockly.blockRendering.StatementInput'], ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/row_elements.js', ['Blockly.blockRendering.Field', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.Icon', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.JaggedEdge', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.SquareCorner'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/rows.js', ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow'], ['Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InputConnection', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/measurables/types.js', ['Blockly.blockRendering.Types'], [], {});
|
||||
@@ -142,22 +148,22 @@ goog.addDependency('../../core/renderers/minimalist/constants.js', ['Blockly.min
|
||||
goog.addDependency('../../core/renderers/minimalist/drawer.js', ['Blockly.minimalist.Drawer'], ['Blockly.blockRendering.Drawer', 'Blockly.minimalist.RenderInfo', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/minimalist/info.js', ['Blockly.minimalist', 'Blockly.minimalist.RenderInfo'], ['Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/minimalist/renderer.js', ['Blockly.minimalist.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.minimalist.ConstantProvider', 'Blockly.minimalist.Drawer', 'Blockly.minimalist.RenderInfo', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/thrasos/info.js', ['Blockly.thrasos', 'Blockly.thrasos.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/thrasos/info.js', ['Blockly.thrasos', 'Blockly.thrasos.RenderInfo'], ['Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/thrasos/renderer.js', ['Blockly.thrasos.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.thrasos.RenderInfo', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/constants.js', ['Blockly.zelos.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.svgPaths'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/zelos/drawer.js', ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.Types', 'Blockly.utils.object', 'Blockly.zelos.RenderInfo'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/info.js', ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.utils.object', 'Blockly.zelos.BottomRow', 'Blockly.zelos.RightConnectionShape', 'Blockly.zelos.StatementInput', 'Blockly.zelos.TopRow'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/constants.js', ['Blockly.zelos.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.svgPaths'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/renderers/zelos/drawer.js', ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.Drawer', 'Blockly.utils.object', 'Blockly.utils.svgPaths', 'Blockly.zelos.RenderInfo'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/info.js', ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.FieldImage', 'Blockly.FieldLabel', 'Blockly.FieldTextInput', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Types', 'Blockly.constants', 'Blockly.inputTypes', 'Blockly.utils.object', 'Blockly.zelos.BottomRow', 'Blockly.zelos.RightConnectionShape', 'Blockly.zelos.TopRow'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/marker_svg.js', ['Blockly.zelos.MarkerSvg'], ['Blockly.blockRendering.MarkerSvg', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/measurables/inputs.js', ['Blockly.zelos.StatementInput'], ['Blockly.blockRendering.StatementInput', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/measurables/row_elements.js', ['Blockly.zelos.RightConnectionShape'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/measurables/rows.js', ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/measurables/rows.js', ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.TopRow', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos.PathObject'], ['Blockly.blockRendering.PathObject', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.constants', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo'], {});
|
||||
goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer'], {});
|
||||
goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.utils.KeyCodes'], {});
|
||||
goog.addDependency('../../core/shortcut_registry.js', ['Blockly.ShortcutRegistry'], ['Blockly.ShortcutItems', 'Blockly.navigation', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo'], {});
|
||||
goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.ContextMenuItems', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.ShortcutItems', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer'], {});
|
||||
goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Events', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.Gesture', 'Blockly.ShortcutRegistry', 'Blockly.utils.KeyCodes'], {});
|
||||
goog.addDependency('../../core/shortcut_registry.js', ['Blockly.ShortcutRegistry'], ['Blockly.utils.KeyCodes', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/theme/classic.js', ['Blockly.Themes.Classic'], ['Blockly.Theme'], {});
|
||||
goog.addDependency('../../core/theme/dark.js', ['Blockly.Themes.Dark'], ['Blockly.Theme'], {});
|
||||
goog.addDependency('../../core/theme/deuteranopia.js', ['Blockly.Themes.Deuteranopia'], ['Blockly.Theme'], {});
|
||||
@@ -169,12 +175,12 @@ goog.addDependency('../../core/theme_manager.js', ['Blockly.ThemeManager'], ['Bl
|
||||
goog.addDependency('../../core/toolbox/category.js', ['Blockly.ToolboxCategory'], ['Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/toolbox/collapsible_category.js', ['Blockly.CollapsibleToolboxCategory'], ['Blockly.ToolboxCategory', 'Blockly.ToolboxItem', 'Blockly.ToolboxSeparator', 'Blockly.registry', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/toolbox/separator.js', ['Blockly.ToolboxSeparator'], ['Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.ToolboxItemSelect', 'Blockly.Touch', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.ToolboxItemSelect', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'], [], {});
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.utils.string'], {});
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.utils.string'], {});
|
||||
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string'], {});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events.TrashcanOpen', 'Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IPositionable', 'Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {});
|
||||
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {});
|
||||
@@ -193,7 +199,7 @@ goog.addDependency('../../core/utils/string.js', ['Blockly.utils.string'], [], {
|
||||
goog.addDependency('../../core/utils/style.js', ['Blockly.utils.style'], ['Blockly.utils.Coordinate', 'Blockly.utils.Size'], {});
|
||||
goog.addDependency('../../core/utils/svg.js', ['Blockly.utils.Svg'], [], {});
|
||||
goog.addDependency('../../core/utils/svg_paths.js', ['Blockly.utils.svgPaths'], [], {});
|
||||
goog.addDependency('../../core/utils/toolbox.js', ['Blockly.utils.toolbox'], ['Blockly.constants'], {});
|
||||
goog.addDependency('../../core/utils/toolbox.js', ['Blockly.utils.toolbox'], ['Blockly.Xml', 'Blockly.constants'], {});
|
||||
goog.addDependency('../../core/utils/useragent.js', ['Blockly.utils.userAgent'], ['Blockly.utils.global'], {});
|
||||
goog.addDependency('../../core/utils/xml.js', ['Blockly.utils.xml'], [], {});
|
||||
goog.addDependency('../../core/variable_map.js', ['Blockly.VariableMap'], ['Blockly.Events', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename', 'Blockly.Msg', 'Blockly.utils', 'Blockly.utils.object'], {});
|
||||
@@ -201,17 +207,17 @@ goog.addDependency('../../core/variable_model.js', ['Blockly.VariableModel'], ['
|
||||
goog.addDependency('../../core/variables.js', ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/variables_dynamic.js', ['Blockly.VariablesDynamic'], ['Blockly.Blocks', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/warning.js', ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/widgetdiv.js', ['Blockly.WidgetDiv'], ['Blockly.utils.style'], {});
|
||||
goog.addDependency('../../core/workspace.js', ['Blockly.Workspace'], ['Blockly.ConnectionChecker', 'Blockly.Events', 'Blockly.Options', 'Blockly.VariableMap', 'Blockly.utils', 'Blockly.utils.math'], {});
|
||||
goog.addDependency('../../core/widgetdiv.js', ['Blockly.WidgetDiv'], ['Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/workspace.js', ['Blockly.Workspace'], ['Blockly.ConnectionChecker', 'Blockly.Events', 'Blockly.Options', 'Blockly.VariableMap', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.math'], {});
|
||||
goog.addDependency('../../core/workspace_audio.js', ['Blockly.WorkspaceAudio'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.userAgent'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/workspace_comment.js', ['Blockly.WorkspaceComment'], ['Blockly.Events', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/workspace_comment_render_svg.js', ['Blockly.WorkspaceCommentSvg.render'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCommentSvg'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.Events.Selected', 'Blockly.WorkspaceComment', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/workspace_drag_surface_svg.js', ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger'], ['Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.VarCreate', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.MetricsManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.PluginManager', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.constants', 'Blockly.inputTypes', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.IPositionable', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
|
||||
goog.addDependency("base.js", [], []);
|
||||
|
||||
// Load Blockly.
|
||||
|
||||
File diff suppressed because one or more lines are too long
372
core/block.js
372
core/block.js
@@ -15,25 +15,36 @@ goog.provide('Blockly.Block');
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.Blocks');
|
||||
goog.require('Blockly.Connection');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockDelete');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.Extensions');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
goog.require('Blockly.Input');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.inputTypes');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.string');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.Workspace');
|
||||
|
||||
goog.requireType('Blockly.Comment');
|
||||
goog.requireType('Blockly.Events.Abstract');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IASTNodeLocation');
|
||||
goog.requireType('Blockly.Mutator');
|
||||
goog.requireType('Blockly.utils.Size');
|
||||
goog.requireType('Blockly.VariableModel');
|
||||
|
||||
|
||||
/**
|
||||
@@ -220,7 +231,8 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
|
||||
// Fire a create event.
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(this));
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(
|
||||
this));
|
||||
}
|
||||
|
||||
} finally {
|
||||
@@ -254,12 +266,13 @@ Blockly.Block.CommentModel;
|
||||
* The language-neutral id given to the collapsed input.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.Block.COLLAPSED_INPUT_NAME = '_TEMP_COLLAPSED_INPUT';
|
||||
Blockly.Block.COLLAPSED_INPUT_NAME = Blockly.constants.COLLAPSED_INPUT_NAME;
|
||||
|
||||
/**
|
||||
* The language-neutral id given to the collapsed field.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.Block.COLLAPSED_FIELD_NAME = '_TEMP_COLLAPSED_FIELD';
|
||||
Blockly.Block.COLLAPSED_FIELD_NAME = Blockly.constants.COLLAPSED_FIELD_NAME;
|
||||
|
||||
/**
|
||||
* Optional text data that round-trips between blocks and XML.
|
||||
@@ -359,7 +372,8 @@ Blockly.Block.prototype.dispose = function(healStack) {
|
||||
|
||||
this.unplug(healStack);
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockDelete(this));
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_DELETE))(
|
||||
this));
|
||||
}
|
||||
Blockly.Events.disable();
|
||||
|
||||
@@ -491,7 +505,8 @@ Blockly.Block.prototype.getOnlyValueConnection_ = function() {
|
||||
var connection = null;
|
||||
for (var i = 0; i < this.inputList.length; i++) {
|
||||
var thisConnection = this.inputList[i].connection;
|
||||
if (thisConnection && thisConnection.type == Blockly.INPUT_VALUE &&
|
||||
if (thisConnection &&
|
||||
thisConnection.type == Blockly.connectionTypes.INPUT_VALUE &&
|
||||
thisConnection.targetConnection) {
|
||||
if (connection) {
|
||||
return null; // More than one value input found.
|
||||
@@ -652,7 +667,8 @@ Blockly.Block.prototype.getPreviousBlock = function() {
|
||||
*/
|
||||
Blockly.Block.prototype.getFirstStatementConnection = function() {
|
||||
for (var i = 0, input; (input = this.inputList[i]); i++) {
|
||||
if (input.connection && input.connection.type == Blockly.NEXT_STATEMENT) {
|
||||
if (input.connection &&
|
||||
input.connection.type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
return input.connection;
|
||||
}
|
||||
}
|
||||
@@ -1132,7 +1148,7 @@ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
|
||||
'connection.');
|
||||
}
|
||||
this.previousConnection =
|
||||
this.makeConnection_(Blockly.PREVIOUS_STATEMENT);
|
||||
this.makeConnection_(Blockly.connectionTypes.PREVIOUS_STATEMENT);
|
||||
}
|
||||
this.previousConnection.setCheck(opt_check);
|
||||
} else {
|
||||
@@ -1159,7 +1175,8 @@ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
|
||||
opt_check = null;
|
||||
}
|
||||
if (!this.nextConnection) {
|
||||
this.nextConnection = this.makeConnection_(Blockly.NEXT_STATEMENT);
|
||||
this.nextConnection =
|
||||
this.makeConnection_(Blockly.connectionTypes.NEXT_STATEMENT);
|
||||
}
|
||||
this.nextConnection.setCheck(opt_check);
|
||||
} else {
|
||||
@@ -1191,7 +1208,8 @@ Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) {
|
||||
throw Error('Remove previous connection prior to adding output ' +
|
||||
'connection.');
|
||||
}
|
||||
this.outputConnection = this.makeConnection_(Blockly.OUTPUT_VALUE);
|
||||
this.outputConnection =
|
||||
this.makeConnection_(Blockly.connectionTypes.OUTPUT_VALUE);
|
||||
}
|
||||
this.outputConnection.setCheck(opt_check);
|
||||
} else {
|
||||
@@ -1211,7 +1229,7 @@ Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) {
|
||||
*/
|
||||
Blockly.Block.prototype.setInputsInline = function(newBoolean) {
|
||||
if (this.inputsInline != newBoolean) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this, 'inline', null, this.inputsInline, newBoolean));
|
||||
this.inputsInline = newBoolean;
|
||||
}
|
||||
@@ -1228,15 +1246,15 @@ Blockly.Block.prototype.getInputsInline = function() {
|
||||
}
|
||||
// Not defined explicitly. Figure out what would look best.
|
||||
for (var i = 1; i < this.inputList.length; i++) {
|
||||
if (this.inputList[i - 1].type == Blockly.DUMMY_INPUT &&
|
||||
this.inputList[i].type == Blockly.DUMMY_INPUT) {
|
||||
if (this.inputList[i - 1].type == Blockly.inputTypes.DUMMY &&
|
||||
this.inputList[i].type == Blockly.inputTypes.DUMMY) {
|
||||
// Two dummy inputs in a row. Don't inline them.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var i = 1; i < this.inputList.length; i++) {
|
||||
if (this.inputList[i - 1].type == Blockly.INPUT_VALUE &&
|
||||
this.inputList[i].type == Blockly.DUMMY_INPUT) {
|
||||
if (this.inputList[i - 1].type == Blockly.inputTypes.VALUE &&
|
||||
this.inputList[i].type == Blockly.inputTypes.DUMMY) {
|
||||
// Dummy input after a value input. Inline them.
|
||||
return true;
|
||||
}
|
||||
@@ -1274,7 +1292,7 @@ Blockly.Block.prototype.isEnabled = function() {
|
||||
*/
|
||||
Blockly.Block.prototype.setEnabled = function(enabled) {
|
||||
if (this.isEnabled() != enabled) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this, 'disabled', null, this.disabled, !enabled));
|
||||
this.disabled = !enabled;
|
||||
}
|
||||
@@ -1311,7 +1329,7 @@ Blockly.Block.prototype.isCollapsed = function() {
|
||||
*/
|
||||
Blockly.Block.prototype.setCollapsed = function(collapsed) {
|
||||
if (this.collapsed_ != collapsed) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this, 'collapsed', null, this.collapsed_, collapsed));
|
||||
this.collapsed_ = collapsed;
|
||||
}
|
||||
@@ -1372,7 +1390,7 @@ Blockly.Block.prototype.toString = function(opt_maxLength, opt_emptyToken) {
|
||||
break;
|
||||
case Blockly.ASTNode.types.FIELD:
|
||||
var field = /** @type {Blockly.Field} */ (node.getLocation());
|
||||
if (field.name != Blockly.Block.COLLAPSED_FIELD_NAME) {
|
||||
if (field.name != Blockly.constants.COLLAPSED_FIELD_NAME) {
|
||||
text.push(field.getText());
|
||||
}
|
||||
break;
|
||||
@@ -1433,7 +1451,7 @@ Blockly.Block.prototype.toString = function(opt_maxLength, opt_emptyToken) {
|
||||
* @return {!Blockly.Input} The input object created.
|
||||
*/
|
||||
Blockly.Block.prototype.appendValueInput = function(name) {
|
||||
return this.appendInput_(Blockly.INPUT_VALUE, name);
|
||||
return this.appendInput_(Blockly.inputTypes.VALUE, name);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1443,7 +1461,7 @@ Blockly.Block.prototype.appendValueInput = function(name) {
|
||||
* @return {!Blockly.Input} The input object created.
|
||||
*/
|
||||
Blockly.Block.prototype.appendStatementInput = function(name) {
|
||||
return this.appendInput_(Blockly.NEXT_STATEMENT, name);
|
||||
return this.appendInput_(Blockly.inputTypes.STATEMENT, name);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1453,7 +1471,7 @@ Blockly.Block.prototype.appendStatementInput = function(name) {
|
||||
* @return {!Blockly.Input} The input object created.
|
||||
*/
|
||||
Blockly.Block.prototype.appendDummyInput = function(opt_name) {
|
||||
return this.appendInput_(Blockly.DUMMY_INPUT, opt_name || '');
|
||||
return this.appendInput_(Blockly.inputTypes.DUMMY, opt_name || '');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1623,117 +1641,212 @@ Blockly.Block.prototype.mixin = function(mixinObj, opt_disableCheck) {
|
||||
Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign,
|
||||
warningPrefix) {
|
||||
var tokens = Blockly.utils.tokenizeInterpolation(message);
|
||||
// Interpolate the arguments. Build a list of elements.
|
||||
var indexDup = [];
|
||||
var indexCount = 0;
|
||||
var elements = [];
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (typeof token == 'number') {
|
||||
if (token <= 0 || token > args.length) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message index %' + token + ' out of range.');
|
||||
}
|
||||
if (indexDup[token]) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message index %' + token + ' duplicated.');
|
||||
}
|
||||
indexDup[token] = true;
|
||||
indexCount++;
|
||||
elements.push(args[token - 1]);
|
||||
} else {
|
||||
token = token.trim();
|
||||
if (token) {
|
||||
elements.push(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indexCount != args.length) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message does not reference all ' + args.length + ' arg(s).');
|
||||
}
|
||||
// Add last dummy input if needed.
|
||||
if (elements.length && (typeof elements[elements.length - 1] == 'string' ||
|
||||
Blockly.utils.string.startsWith(
|
||||
elements[elements.length - 1]['type'], 'field_'))) {
|
||||
var dummyInput = {type: 'input_dummy'};
|
||||
if (lastDummyAlign) {
|
||||
dummyInput['align'] = lastDummyAlign;
|
||||
}
|
||||
elements.push(dummyInput);
|
||||
}
|
||||
// Lookup of alignment constants.
|
||||
var alignmentLookup = {
|
||||
'LEFT': Blockly.ALIGN_LEFT,
|
||||
'RIGHT': Blockly.ALIGN_RIGHT,
|
||||
'CENTRE': Blockly.ALIGN_CENTRE,
|
||||
'CENTER': Blockly.ALIGN_CENTRE
|
||||
};
|
||||
// Populate block with inputs and fields.
|
||||
var fieldStack = [];
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var element = elements[i];
|
||||
if (typeof element == 'string') {
|
||||
fieldStack.push([element, undefined]);
|
||||
} else {
|
||||
var field = null;
|
||||
var input = null;
|
||||
do {
|
||||
var altRepeat = false;
|
||||
if (typeof element == 'string') {
|
||||
field = new Blockly.FieldLabel(element);
|
||||
} else {
|
||||
switch (element['type']) {
|
||||
case 'input_value':
|
||||
input = this.appendValueInput(element['name']);
|
||||
break;
|
||||
case 'input_statement':
|
||||
input = this.appendStatementInput(element['name']);
|
||||
break;
|
||||
case 'input_dummy':
|
||||
input = this.appendDummyInput(element['name']);
|
||||
break;
|
||||
default:
|
||||
// This should handle all field JSON parsing, including
|
||||
// options that can be applied to any field type.
|
||||
field = Blockly.fieldRegistry.fromJson(element);
|
||||
this.validateTokens_(tokens, args.length);
|
||||
var elements = this.interpolateArguments_(tokens, args, lastDummyAlign);
|
||||
|
||||
// Unknown field.
|
||||
if (!field && element['alt']) {
|
||||
element = element['alt'];
|
||||
altRepeat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (altRepeat);
|
||||
if (field) {
|
||||
fieldStack.push([field, element['name']]);
|
||||
} else if (input) {
|
||||
if (element['check']) {
|
||||
input.setCheck(element['check']);
|
||||
}
|
||||
if (element['align']) {
|
||||
var alignment = alignmentLookup[element['align'].toUpperCase()];
|
||||
if (alignment === undefined) {
|
||||
console.warn(warningPrefix + 'Illegal align value: ',
|
||||
element['align']);
|
||||
} else {
|
||||
input.setAlign(alignment);
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < fieldStack.length; j++) {
|
||||
input.appendField(fieldStack[j][0], fieldStack[j][1]);
|
||||
// An array of [field, fieldName] tuples.
|
||||
var fieldStack = [];
|
||||
for (var i = 0, element; (element = elements[i]); i++) {
|
||||
if (this.isInputKeyword_(element['type'])) {
|
||||
var input = this.inputFromJson_(element, warningPrefix);
|
||||
// Should never be null, but just in case.
|
||||
if (input) {
|
||||
for (var j = 0, tuple; (tuple = fieldStack[j]); j++) {
|
||||
input.appendField(tuple[0], tuple[1]);
|
||||
}
|
||||
fieldStack.length = 0;
|
||||
}
|
||||
} else {
|
||||
// All other types, including ones starting with 'input_' get routed here.
|
||||
var field = this.fieldFromJson_(element);
|
||||
if (field) {
|
||||
fieldStack.push([field, element['name']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates that the tokens are within the correct bounds, with no duplicates,
|
||||
* and that all of the arguments are referred to. Throws errors if any of these
|
||||
* things are not true.
|
||||
* @param {!Array<string|number>} tokens An array of tokens to validate
|
||||
* @param {number} argsCount The number of args that need to be referred to.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.validateTokens_ = function(tokens, argsCount) {
|
||||
var visitedArgsHash = [];
|
||||
var visitedArgsCount = 0;
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (typeof token != 'number') {
|
||||
continue;
|
||||
}
|
||||
if (token < 1 || token > argsCount) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message index %' + token + ' out of range.');
|
||||
}
|
||||
if (visitedArgsHash[token]) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message index %' + token + ' duplicated.');
|
||||
}
|
||||
visitedArgsHash[token] = true;
|
||||
visitedArgsCount++;
|
||||
}
|
||||
if (visitedArgsCount != argsCount) {
|
||||
throw Error('Block "' + this.type + '": ' +
|
||||
'Message does not reference all ' + argsCount + ' arg(s).');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts args in place of numerical tokens. String args are converted to json
|
||||
* that defines a label field. If necessary an extra dummy input is added to
|
||||
* the end of the elements.
|
||||
* @param {!Array<!string|number>} tokens The tokens to interpolate
|
||||
* @param {!Array<!Object|string>} args The arguments to insert.
|
||||
* @param {string|undefined} lastDummyAlign The alignment the added dummy input
|
||||
* should have, if we are required to add one.
|
||||
* @return {!Array<!Object>} The JSON definitions of field and inputs to add
|
||||
* to the block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.interpolateArguments_ =
|
||||
function(tokens, args, lastDummyAlign) {
|
||||
var elements = [];
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var element = tokens[i];
|
||||
if (typeof element == 'number') {
|
||||
element = args[element - 1];
|
||||
}
|
||||
// Args can be strings, which is why this isn't elseif.
|
||||
if (typeof element == 'string') {
|
||||
element = this.stringToFieldJson_(element);
|
||||
if (!element) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
elements.push(element);
|
||||
}
|
||||
|
||||
var length = elements.length;
|
||||
if (length && !this.isInputKeyword_(elements[length - 1]['type'])) {
|
||||
var dummyInput = {'type': 'input_dummy'};
|
||||
if (lastDummyAlign) {
|
||||
dummyInput['align'] = lastDummyAlign;
|
||||
}
|
||||
elements.push(dummyInput);
|
||||
}
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a field from the json definition of a field. If a field with the
|
||||
* given type cannot be found, this attempts to create a different field using
|
||||
* the 'alt' property of the json definition (if it exists).
|
||||
* @param {{alt:(string|undefined)}} element The element to try to turn into a
|
||||
* field.
|
||||
* @return {?Blockly.Field} The field defined by the JSON, or null if one
|
||||
* couldn't be created.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.fieldFromJson_ = function(element) {
|
||||
var field = Blockly.fieldRegistry.fromJson(element);
|
||||
if (!field && element['alt']) {
|
||||
if (typeof element['alt'] == 'string') {
|
||||
var json = this.stringToFieldJson_(element['alt']);
|
||||
return json ? this.fieldFromJson_(json) : null;
|
||||
}
|
||||
return this.fieldFromJson_(element['alt']);
|
||||
}
|
||||
return field;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an input from the json definition of an input. Sets the input's check
|
||||
* and alignment if they are provided.
|
||||
* @param {!Object} element The JSON to turn into an input.
|
||||
* @param {string} warningPrefix The prefix to add to warnings to help the
|
||||
* developer debug.
|
||||
* @return {?Blockly.Input} The input that has been created, or null if one
|
||||
* could not be created for some reason (should never happen).
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.inputFromJson_ = function(element, warningPrefix) {
|
||||
var alignmentLookup = {
|
||||
'LEFT': Blockly.constants.ALIGN.LEFT,
|
||||
'RIGHT': Blockly.constants.ALIGN.RIGHT,
|
||||
'CENTRE': Blockly.constants.ALIGN.CENTRE,
|
||||
'CENTER': Blockly.constants.ALIGN.CENTRE
|
||||
};
|
||||
|
||||
var input = null;
|
||||
switch (element['type']) {
|
||||
case 'input_value':
|
||||
input = this.appendValueInput(element['name']);
|
||||
break;
|
||||
case 'input_statement':
|
||||
input = this.appendStatementInput(element['name']);
|
||||
break;
|
||||
case 'input_dummy':
|
||||
input = this.appendDummyInput(element['name']);
|
||||
break;
|
||||
}
|
||||
// Should never be hit because of interpolate_'s checks, but just in case.
|
||||
if (!input) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (element['check']) {
|
||||
input.setCheck(element['check']);
|
||||
}
|
||||
if (element['align']) {
|
||||
var alignment = alignmentLookup[element['align'].toUpperCase()];
|
||||
if (alignment === undefined) {
|
||||
console.warn(warningPrefix + 'Illegal align value: ',
|
||||
element['align']);
|
||||
} else {
|
||||
input.setAlign(alignment);
|
||||
}
|
||||
}
|
||||
return input;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given string matches one of the input keywords.
|
||||
* @param {string} str The string to check.
|
||||
* @return {boolean} True if the given string matches one of the input keywords,
|
||||
* false otherwise.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.isInputKeyword_ = function(str) {
|
||||
return str == 'input_value' ||
|
||||
str == 'input_statement' ||
|
||||
str == 'input_dummy';
|
||||
};
|
||||
|
||||
/**
|
||||
* Turns a string into the JSON definition of a label field. If the string
|
||||
* becomes an empty string when trimmed, this returns null.
|
||||
* @param {string} str String to turn into the JSON definition of a label field.
|
||||
* @return {?{text: string, type: string}} The JSON definition or null.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.stringToFieldJson_ = function(str) {
|
||||
str = str.trim();
|
||||
if (str) {
|
||||
return {
|
||||
'type': 'field_label',
|
||||
'text': str,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a value input, statement input or local variable to this block.
|
||||
* @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or
|
||||
* Blockly.DUMMY_INPUT.
|
||||
* @param {number} type One of Blockly.inputTypes.
|
||||
* @param {string} name Language-neutral identifier which may used to find this
|
||||
* input again. Should be unique to this block.
|
||||
* @return {!Blockly.Input} The input object created.
|
||||
@@ -1741,10 +1854,11 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign,
|
||||
*/
|
||||
Blockly.Block.prototype.appendInput_ = function(type, name) {
|
||||
var connection = null;
|
||||
if (type == Blockly.INPUT_VALUE || type == Blockly.NEXT_STATEMENT) {
|
||||
if (type == Blockly.inputTypes.VALUE ||
|
||||
type == Blockly.inputTypes.STATEMENT) {
|
||||
connection = this.makeConnection_(type);
|
||||
}
|
||||
if (type == Blockly.NEXT_STATEMENT) {
|
||||
if (type == Blockly.inputTypes.STATEMENT) {
|
||||
this.statementInputCount++;
|
||||
}
|
||||
var input = new Blockly.Input(type, name, this, connection);
|
||||
@@ -1825,7 +1939,7 @@ Blockly.Block.prototype.moveNumberedInputBefore = function(
|
||||
Blockly.Block.prototype.removeInput = function(name, opt_quiet) {
|
||||
for (var i = 0, input; (input = this.inputList[i]); i++) {
|
||||
if (input.name == name) {
|
||||
if (input.type == Blockly.NEXT_STATEMENT) {
|
||||
if (input.type == Blockly.inputTypes.STATEMENT) {
|
||||
this.statementInputCount--;
|
||||
}
|
||||
input.dispose();
|
||||
@@ -1882,7 +1996,7 @@ Blockly.Block.prototype.setCommentText = function(text) {
|
||||
if (this.commentModel.text == text) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this, 'comment', null, this.commentModel.text, text));
|
||||
this.commentModel.text = text;
|
||||
this.comment = text; // For backwards compatibility.
|
||||
@@ -1925,7 +2039,7 @@ Blockly.Block.prototype.moveBy = function(dx, dy) {
|
||||
if (this.parentBlock_) {
|
||||
throw Error('Block has parent.');
|
||||
}
|
||||
var event = new Blockly.Events.BlockMove(this);
|
||||
var event = new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(this);
|
||||
this.xy_.translate(dx, dy);
|
||||
event.recordNew();
|
||||
Blockly.Events.fire(event);
|
||||
|
||||
@@ -15,6 +15,8 @@ goog.provide('Blockly.blockAnimations');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
|
||||
|
||||
/**
|
||||
* PID of disconnect UI animation. There can only be one at a time.
|
||||
|
||||
@@ -13,14 +13,20 @@
|
||||
goog.provide('Blockly.BlockDragger');
|
||||
|
||||
goog.require('Blockly.blockAnimations');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockDrag');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.InsertionMarkerManager');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a block dragger. It moves blocks around the workspace when they
|
||||
@@ -184,8 +190,8 @@ Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY,
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.fireDragStartEvent_ = function() {
|
||||
var event = new Blockly.Events.BlockDrag(this.draggingBlock_, true,
|
||||
this.draggingBlock_.getDescendants(false));
|
||||
var event = new (Blockly.Events.get(Blockly.Events.BLOCK_DRAG))(
|
||||
this.draggingBlock_, true, this.draggingBlock_.getDescendants(false));
|
||||
Blockly.Events.fire(event);
|
||||
};
|
||||
|
||||
@@ -261,8 +267,8 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.fireDragEndEvent_ = function() {
|
||||
var event = new Blockly.Events.BlockDrag(this.draggingBlock_, false,
|
||||
this.draggingBlock_.getDescendants(false));
|
||||
var event = new (Blockly.Events.get(Blockly.Events.BLOCK_DRAG))(
|
||||
this.draggingBlock_, false, this.draggingBlock_.getDescendants(false));
|
||||
Blockly.Events.fire(event);
|
||||
};
|
||||
|
||||
@@ -271,7 +277,8 @@ Blockly.BlockDragger.prototype.fireDragEndEvent_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
|
||||
var event = new Blockly.Events.BlockMove(this.draggingBlock_);
|
||||
var event = new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(
|
||||
this.draggingBlock_);
|
||||
event.oldCoordinate = this.startXY_;
|
||||
event.recordNew();
|
||||
Blockly.Events.fire(event);
|
||||
|
||||
@@ -16,29 +16,44 @@ goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.Block');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.blockRendering.IPathObject');
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.ContextMenu');
|
||||
goog.require('Blockly.ContextMenuRegistry');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.Selected');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.RenderedConnection');
|
||||
goog.require('Blockly.TabNavigateCursor');
|
||||
goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Debug');
|
||||
goog.requireType('Blockly.Comment');
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IBoundedElement');
|
||||
goog.requireType('Blockly.ICopyable');
|
||||
goog.requireType('Blockly.Input');
|
||||
goog.requireType('Blockly.Mutator');
|
||||
goog.requireType('Blockly.Theme');
|
||||
goog.requireType('Blockly.Warning');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -148,7 +163,7 @@ Blockly.BlockSvg.prototype.warningTextDb_ = null;
|
||||
|
||||
/**
|
||||
* Constant for identifying rows that are to be rendered inline.
|
||||
* Don't collide with Blockly.INPUT_VALUE and friends.
|
||||
* Don't collide with Blockly.inputTypes.
|
||||
* @const
|
||||
*/
|
||||
Blockly.BlockSvg.INLINE = -1;
|
||||
@@ -214,7 +229,7 @@ Blockly.BlockSvg.prototype.initSvg = function() {
|
||||
this.pathObject.updateMovable(this.isMovable());
|
||||
var svg = this.getSvgRoot();
|
||||
if (!this.workspace.options.readOnly && !this.eventsInit_ && svg) {
|
||||
Blockly.bindEventWithChecks_(
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
svg, 'mousedown', this, this.onMouseDown_);
|
||||
}
|
||||
this.eventsInit_ = true;
|
||||
@@ -300,7 +315,8 @@ Blockly.BlockSvg.prototype.select = function() {
|
||||
Blockly.Events.enable();
|
||||
}
|
||||
}
|
||||
var event = new Blockly.Events.Selected(oldId, this.id, this.workspace.id);
|
||||
var event = new (Blockly.Events.get(Blockly.Events.SELECTED))(oldId, this.id,
|
||||
this.workspace.id);
|
||||
Blockly.Events.fire(event);
|
||||
Blockly.selected = this;
|
||||
this.addSelect();
|
||||
@@ -313,7 +329,8 @@ Blockly.BlockSvg.prototype.unselect = function() {
|
||||
if (Blockly.selected != this) {
|
||||
return;
|
||||
}
|
||||
var event = new Blockly.Events.Selected(this.id, null, this.workspace.id);
|
||||
var event = new (Blockly.Events.get(Blockly.Events.SELECTED))(this.id, null,
|
||||
this.workspace.id);
|
||||
event.workspaceId = this.workspace.id;
|
||||
Blockly.Events.fire(event);
|
||||
Blockly.selected = null;
|
||||
@@ -454,7 +471,7 @@ Blockly.BlockSvg.prototype.moveBy = function(dx, dy) {
|
||||
}
|
||||
var eventsEnabled = Blockly.Events.isEnabled();
|
||||
if (eventsEnabled) {
|
||||
var event = new Blockly.Events.BlockMove(this);
|
||||
var event = new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(this);
|
||||
}
|
||||
var xy = this.getRelativeToSurfaceXY();
|
||||
this.translate(xy.x + dx, xy.y + dy);
|
||||
@@ -645,8 +662,8 @@ Blockly.BlockSvg.prototype.setCollapsed = function(collapsed) {
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.updateCollapsed_ = function() {
|
||||
var collapsed = this.isCollapsed();
|
||||
var collapsedInputName = Blockly.Block.COLLAPSED_INPUT_NAME;
|
||||
var collapsedFieldName = Blockly.Block.COLLAPSED_FIELD_NAME;
|
||||
var collapsedInputName = Blockly.constants.COLLAPSED_INPUT_NAME;
|
||||
var collapsedFieldName = Blockly.constants.COLLAPSED_FIELD_NAME;
|
||||
|
||||
for (var i = 0, input; (input = this.inputList[i]); i++) {
|
||||
if (input.name != collapsedInputName) {
|
||||
@@ -655,6 +672,7 @@ Blockly.BlockSvg.prototype.updateCollapsed_ = function() {
|
||||
}
|
||||
|
||||
if (!collapsed) {
|
||||
this.updateDisabled();
|
||||
this.removeInput(collapsedInputName);
|
||||
return;
|
||||
}
|
||||
@@ -684,11 +702,12 @@ Blockly.BlockSvg.prototype.tab = function(start, forward) {
|
||||
var tabCursor = new Blockly.TabNavigateCursor();
|
||||
tabCursor.setCurNode(Blockly.ASTNode.createFieldNode(start));
|
||||
var currentNode = tabCursor.getCurNode();
|
||||
var actionName = forward ?
|
||||
Blockly.navigation.actionNames.NEXT : Blockly.navigation.actionNames.PREVIOUS;
|
||||
|
||||
tabCursor.onBlocklyAction(
|
||||
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */ ({name: actionName}));
|
||||
if (forward) {
|
||||
tabCursor.next();
|
||||
} else {
|
||||
tabCursor.prev();
|
||||
}
|
||||
|
||||
var nextNode = tabCursor.getCurNode();
|
||||
if (nextNode && nextNode !== currentNode) {
|
||||
@@ -899,10 +918,6 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
Blockly.ContextMenu.hide();
|
||||
}
|
||||
|
||||
if (this.workspace.keyboardAccessibilityMode) {
|
||||
Blockly.navigation.moveCursorOnBlockDelete(this);
|
||||
}
|
||||
|
||||
if (animate && this.rendered) {
|
||||
this.unplug(healStack);
|
||||
Blockly.blockAnimations.disposeUiEffect(this);
|
||||
@@ -1361,8 +1376,7 @@ Blockly.BlockSvg.prototype.moveNumberedInputBefore = function(
|
||||
|
||||
/**
|
||||
* Add a value input, statement input or local variable to this block.
|
||||
* @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or
|
||||
* Blockly.DUMMY_INPUT.
|
||||
* @param {number} type One of Blockly.inputTypes.
|
||||
* @param {string} name Language-neutral identifier which may used to find this
|
||||
* input again. Should be unique to this block.
|
||||
* @return {!Blockly.Input} The input object created.
|
||||
@@ -1576,8 +1590,8 @@ Blockly.BlockSvg.prototype.positionNearConnection = function(sourceConnection,
|
||||
targetConnection) {
|
||||
// We only need to position the new block if it's before the existing one,
|
||||
// otherwise its position is set by the previous block.
|
||||
if (sourceConnection.type == Blockly.NEXT_STATEMENT ||
|
||||
sourceConnection.type == Blockly.INPUT_VALUE) {
|
||||
if (sourceConnection.type == Blockly.connectionTypes.NEXT_STATEMENT ||
|
||||
sourceConnection.type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
var dx = targetConnection.x - sourceConnection.x;
|
||||
var dy = targetConnection.y - sourceConnection.y;
|
||||
|
||||
@@ -1652,7 +1666,8 @@ Blockly.BlockSvg.prototype.updateMarkers_ = function() {
|
||||
this.workspace.getCursor().draw();
|
||||
}
|
||||
if (this.workspace.keyboardAccessibilityMode && this.pathObject.markerSvg) {
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).draw();
|
||||
// TODO(#4592): Update all markers on the block.
|
||||
this.workspace.getMarker(Blockly.MarkerManager.LOCAL_MARKER).draw();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
277
core/blockly.js
277
core/blockly.js
@@ -16,23 +16,47 @@
|
||||
*/
|
||||
goog.provide('Blockly');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.FinishedLoading');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.Ui');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.UiBase');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.VarCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.inject');
|
||||
goog.require('Blockly.inputTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Procedures');
|
||||
goog.require('Blockly.ShortcutRegistry');
|
||||
goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.colour');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Variables');
|
||||
goog.require('Blockly.WidgetDiv');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.ICopyable');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
* Blockly core version.
|
||||
@@ -99,19 +123,20 @@ Blockly.cache3dSupported_ = null;
|
||||
*/
|
||||
Blockly.parentContainer = null;
|
||||
|
||||
/**
|
||||
* Blockly opaque event data used to unbind events when using
|
||||
* `Blockly.bindEvent_` and `Blockly.bindEventWithChecks_`.
|
||||
* @typedef {!Array.<!Array>}
|
||||
*/
|
||||
Blockly.EventData;
|
||||
|
||||
/**
|
||||
* 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_);
|
||||
};
|
||||
@@ -139,6 +164,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.
|
||||
@@ -146,13 +172,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();
|
||||
};
|
||||
@@ -383,149 +409,6 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. When calling the function, verifies that
|
||||
* it belongs to the touch stream that is currently being processed, and splits
|
||||
* multitouch events into multiple events as needed.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
|
||||
* should not block execution of other event handlers on this touch or
|
||||
* other simultaneous touches. False by default.
|
||||
* @param {boolean=} opt_noPreventDefault True if triggering on this event
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
opt_noCaptureIdentifier, opt_noPreventDefault) {
|
||||
var handled = false;
|
||||
var wrapFunc = function(e) {
|
||||
var captureIdentifier = !opt_noCaptureIdentifier;
|
||||
// Handle each touch point separately. If the event was a mouse event, this
|
||||
// will hand back an array with one element, which we're fine handling.
|
||||
var events = Blockly.Touch.splitEventByTouches(e);
|
||||
for (var i = 0, event; (event = events[i]); i++) {
|
||||
if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
|
||||
continue;
|
||||
}
|
||||
Blockly.Touch.setClientFromTouch(event);
|
||||
if (thisObject) {
|
||||
func.call(thisObject, event);
|
||||
} else {
|
||||
func(event);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
wrapFunc(e);
|
||||
// Calling preventDefault stops the browser from scrolling/zooming the
|
||||
// page.
|
||||
var preventDef = !opt_noPreventDefault;
|
||||
if (handled && preventDef) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind an event to a function call. Handles multitouch events by using the
|
||||
* coordinates of the first changed touch, and doesn't do any safety checks for
|
||||
* simultaneous event processing. In most cases prefer is to use
|
||||
* `Blockly.bindEventWithChecks_`.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @return {!Blockly.EventData} Opaque data that can be passed to unbindEvent_.
|
||||
*/
|
||||
Blockly.bindEvent_ = function(node, name, thisObject, func) {
|
||||
var wrapFunc = function(e) {
|
||||
if (thisObject) {
|
||||
func.call(thisObject, e);
|
||||
} else {
|
||||
func(e);
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
// Punt on multitouch events.
|
||||
if (e.changedTouches && e.changedTouches.length == 1) {
|
||||
// Map the touch event's properties to the event.
|
||||
var touchPoint = e.changedTouches[0];
|
||||
e.clientX = touchPoint.clientX;
|
||||
e.clientY = touchPoint.clientY;
|
||||
}
|
||||
wrapFunc(e);
|
||||
|
||||
// Stop the browser from scrolling/zooming the page.
|
||||
e.preventDefault();
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind one or more events event from a function call.
|
||||
* @param {!Array.<!Array>} bindData Opaque data from bindEvent_.
|
||||
* This list is emptied during the course of calling this function.
|
||||
* @return {!Function} The function call.
|
||||
*/
|
||||
Blockly.unbindEvent_ = function(bindData) {
|
||||
while (bindData.length) {
|
||||
var bindDatum = bindData.pop();
|
||||
var node = bindDatum[0];
|
||||
var name = bindDatum[1];
|
||||
var func = bindDatum[2];
|
||||
node.removeEventListener(name, func, false);
|
||||
}
|
||||
return func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Is the given string a number (includes negative and decimals).
|
||||
* @param {string} str Input string.
|
||||
@@ -627,3 +510,89 @@ Blockly.checkBlockColourConstant_ = function(
|
||||
Blockly.setParentContainer = function(container) {
|
||||
Blockly.parentContainer = container;
|
||||
};
|
||||
|
||||
/** Aliases. */
|
||||
|
||||
/**
|
||||
* @see Blockly.browserEvents.bind
|
||||
*/
|
||||
Blockly.bindEvent_ = Blockly.browserEvents.bind;
|
||||
|
||||
/**
|
||||
* @see Blockly.browserEvents.unbind
|
||||
*/
|
||||
Blockly.unbindEvent_ = Blockly.browserEvents.unbind;
|
||||
|
||||
/**
|
||||
* @see Blockly.browserEvents.conditionalBind
|
||||
*/
|
||||
Blockly.bindEventWithChecks_ = Blockly.browserEvents.conditionalBind;
|
||||
|
||||
/**
|
||||
* @see Blockly.constants.ALIGN.LEFT
|
||||
*/
|
||||
Blockly.ALIGN_LEFT = Blockly.constants.ALIGN.LEFT;
|
||||
|
||||
/**
|
||||
* @see Blockly.constants.ALIGN.CENTRE
|
||||
*/
|
||||
Blockly.ALIGN_CENTRE = Blockly.constants.ALIGN.CENTRE;
|
||||
|
||||
/**
|
||||
* @see Blockly.constants.ALIGN.RIGHT
|
||||
*/
|
||||
Blockly.ALIGN_RIGHT = Blockly.constants.ALIGN.RIGHT;
|
||||
|
||||
|
||||
/**
|
||||
* Aliases for constants used for connection and input types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Blockly.connectionTypes.INPUT_VALUE
|
||||
*/
|
||||
Blockly.INPUT_VALUE = Blockly.connectionTypes.INPUT_VALUE;
|
||||
|
||||
/**
|
||||
* @see Blockly.connectionTypes.OUTPUT_VALUE
|
||||
*/
|
||||
Blockly.OUTPUT_VALUE = Blockly.connectionTypes.OUTPUT_VALUE;
|
||||
|
||||
/**
|
||||
* @see Blockly.connectionTypes.NEXT_STATEMENT
|
||||
*/
|
||||
Blockly.NEXT_STATEMENT = Blockly.connectionTypes.NEXT_STATEMENT;
|
||||
|
||||
/**
|
||||
* @see Blockly.connectionTypes.PREVIOUS_STATEMENT
|
||||
*/
|
||||
Blockly.PREVIOUS_STATEMENT = Blockly.connectionTypes.PREVIOUS_STATEMENT;
|
||||
|
||||
/**
|
||||
* @see Blockly.inputTypes.DUMMY_INPUT
|
||||
*/
|
||||
Blockly.DUMMY_INPUT = Blockly.inputTypes.DUMMY;
|
||||
|
||||
/**
|
||||
* Aliases for toolbox positions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Blockly.utils.toolbox.Position.TOP
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_TOP = Blockly.utils.toolbox.Position.TOP;
|
||||
|
||||
/**
|
||||
* @see Blockly.utils.toolbox.Position.BOTTOM
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_BOTTOM = Blockly.utils.toolbox.Position.BOTTOM;
|
||||
|
||||
/**
|
||||
* @see Blockly.utils.toolbox.Position.LEFT
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_LEFT = Blockly.utils.toolbox.Position.LEFT;
|
||||
|
||||
/**
|
||||
* @see Blockly.utils.toolbox.Position.RIGHT
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_RIGHT = Blockly.utils.toolbox.Position.RIGHT;
|
||||
|
||||
174
core/browser_events.js
Normal file
174
core/browser_events.js
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Browser event handling.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.browserEvents');
|
||||
|
||||
goog.require('Blockly.Touch');
|
||||
|
||||
|
||||
/**
|
||||
* Blockly opaque event data used to unbind events when using
|
||||
* `Blockly.browserEvents.bind` and
|
||||
* `Blockly.browserEvents.conditionalBind`.
|
||||
* @typedef {!Array.<!Array>}
|
||||
*/
|
||||
Blockly.browserEvents.Data;
|
||||
|
||||
/**
|
||||
* Bind an event handler that can be ignored if it is not part of the active
|
||||
* touch stream.
|
||||
* Use this for events that either start or continue a multi-part gesture (e.g.
|
||||
* mousedown or mousemove, which may be part of a drag or click).
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
|
||||
* should not block execution of other event handlers on this touch or
|
||||
* other simultaneous touches. False by default.
|
||||
* @param {boolean=} opt_noPreventDefault True if triggering on this event
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
* @return {!Blockly.browserEvents.Data} Opaque data that can be passed to
|
||||
* unbindEvent_.
|
||||
* @public
|
||||
*/
|
||||
Blockly.browserEvents.conditionalBind = function(
|
||||
node, name, thisObject, func, opt_noCaptureIdentifier,
|
||||
opt_noPreventDefault) {
|
||||
var handled = false;
|
||||
var wrapFunc = function(e) {
|
||||
var captureIdentifier = !opt_noCaptureIdentifier;
|
||||
// Handle each touch point separately. If the event was a mouse event, this
|
||||
// will hand back an array with one element, which we're fine handling.
|
||||
var events = Blockly.Touch.splitEventByTouches(e);
|
||||
for (var i = 0, event; (event = events[i]); i++) {
|
||||
if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
|
||||
continue;
|
||||
}
|
||||
Blockly.Touch.setClientFromTouch(event);
|
||||
if (thisObject) {
|
||||
func.call(thisObject, event);
|
||||
} else {
|
||||
func(event);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
wrapFunc(e);
|
||||
// Calling preventDefault stops the browser from scrolling/zooming the
|
||||
// page.
|
||||
var preventDef = !opt_noPreventDefault;
|
||||
if (handled && preventDef) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind an event handler that should be called regardless of whether it is part
|
||||
* of the active touch stream.
|
||||
* Use this for events that are not part of a multi-part gesture (e.g.
|
||||
* mouseover for tooltips).
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @return {!Blockly.browserEvents.Data} Opaque data that can be passed to
|
||||
* unbindEvent_.
|
||||
* @public
|
||||
*/
|
||||
Blockly.browserEvents.bind = function(node, name, thisObject, func) {
|
||||
var wrapFunc = function(e) {
|
||||
if (thisObject) {
|
||||
func.call(thisObject, e);
|
||||
} else {
|
||||
func(e);
|
||||
}
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
}
|
||||
} else {
|
||||
node.addEventListener(name, wrapFunc, false);
|
||||
bindData.push([node, name, wrapFunc]);
|
||||
|
||||
// Add equivalent touch event.
|
||||
if (name in Blockly.Touch.TOUCH_MAP) {
|
||||
var touchWrapFunc = function(e) {
|
||||
// Punt on multitouch events.
|
||||
if (e.changedTouches && e.changedTouches.length == 1) {
|
||||
// Map the touch event's properties to the event.
|
||||
var touchPoint = e.changedTouches[0];
|
||||
e.clientX = touchPoint.clientX;
|
||||
e.clientY = touchPoint.clientY;
|
||||
}
|
||||
wrapFunc(e);
|
||||
|
||||
// Stop the browser from scrolling/zooming the page.
|
||||
e.preventDefault();
|
||||
};
|
||||
for (var i = 0, type; (type = Blockly.Touch.TOUCH_MAP[name][i]); i++) {
|
||||
node.addEventListener(type, touchWrapFunc, false);
|
||||
bindData.push([node, type, touchWrapFunc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind one or more events event from a function call.
|
||||
* @param {!Blockly.browserEvents.Data} bindData Opaque data from bindEvent_.
|
||||
* This list is emptied during the course of calling this function.
|
||||
* @return {!Function} The function call.
|
||||
* @public
|
||||
*/
|
||||
Blockly.browserEvents.unbind = function(bindData) {
|
||||
while (bindData.length) {
|
||||
var bindDatum = bindData.pop();
|
||||
var node = bindDatum[0];
|
||||
var name = bindDatum[1];
|
||||
var func = bindDatum[2];
|
||||
node.removeEventListener(name, func, false);
|
||||
}
|
||||
return func;
|
||||
};
|
||||
112
core/bubble.js
112
core/bubble.js
@@ -12,18 +12,24 @@
|
||||
|
||||
goog.provide('Blockly.Bubble');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Workspace');
|
||||
|
||||
goog.requireType('Blockly.BlockDragSurfaceSvg');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.IBubble');
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.MetricsManager');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -61,14 +67,14 @@ Blockly.Bubble = function(
|
||||
|
||||
/**
|
||||
* Mouse down on bubbleBack_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownBubbleWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse down on resizeGroup_ event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseDownResizeWrapper_ = null;
|
||||
@@ -132,14 +138,14 @@ Blockly.Bubble.ANCHOR_RADIUS = 8;
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
@@ -150,11 +156,11 @@ Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
*/
|
||||
Blockly.Bubble.unbindDragEvents_ = function() {
|
||||
if (Blockly.Bubble.onMouseUpWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_);
|
||||
Blockly.browserEvents.unbind(Blockly.Bubble.onMouseUpWrapper_);
|
||||
Blockly.Bubble.onMouseUpWrapper_ = null;
|
||||
}
|
||||
if (Blockly.Bubble.onMouseMoveWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_);
|
||||
Blockly.browserEvents.unbind(Blockly.Bubble.onMouseMoveWrapper_);
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = null;
|
||||
}
|
||||
};
|
||||
@@ -237,8 +243,8 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
[...content goes here...]
|
||||
</g>
|
||||
*/
|
||||
this.bubbleGroup_ = Blockly.utils.dom.createSvgElement(
|
||||
Blockly.utils.Svg.G, {}, null);
|
||||
this.bubbleGroup_ =
|
||||
Blockly.utils.dom.createSvgElement(Blockly.utils.Svg.G, {}, null);
|
||||
var filter = {
|
||||
'filter': 'url(#' +
|
||||
this.workspace_.getRenderer().getConstants().embossFilterId + ')'
|
||||
@@ -294,10 +300,10 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
}
|
||||
|
||||
if (!this.workspace_.options.readOnly) {
|
||||
this.onMouseDownBubbleWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseDownBubbleWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_);
|
||||
if (this.resizeGroup_) {
|
||||
this.onMouseDownResizeWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseDownResizeWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_);
|
||||
}
|
||||
}
|
||||
@@ -382,9 +388,9 @@ Blockly.Bubble.prototype.resizeMouseDown_ = function(e) {
|
||||
new Blockly.utils.Coordinate(
|
||||
this.workspace_.RTL ? -this.width_ : this.width_, this.height_));
|
||||
|
||||
Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
Blockly.Bubble.onMouseUpWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
document, 'mouseup', this, Blockly.Bubble.bubbleMouseUp_);
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(
|
||||
Blockly.Bubble.onMouseMoveWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
document, 'mousemove', this, this.resizeMouseMove_);
|
||||
Blockly.hideChaff();
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
@@ -454,14 +460,10 @@ Blockly.Bubble.prototype.setAnchorLocation = function(xy) {
|
||||
*/
|
||||
Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
// Get the metrics in workspace units.
|
||||
var metrics = this.workspace_.getMetrics();
|
||||
metrics.viewLeft /= this.workspace_.scale;
|
||||
metrics.viewWidth /= this.workspace_.scale;
|
||||
metrics.viewTop /= this.workspace_.scale;
|
||||
metrics.viewHeight /= this.workspace_.scale;
|
||||
var viewMetrics = this.workspace_.getMetricsManager().getViewMetrics(true);
|
||||
|
||||
var optimalLeft = this.getOptimalRelativeLeft_(metrics);
|
||||
var optimalTop = this.getOptimalRelativeTop_(metrics);
|
||||
var optimalLeft = this.getOptimalRelativeLeft_(viewMetrics);
|
||||
var optimalTop = this.getOptimalRelativeTop_(viewMetrics);
|
||||
var bbox = this.shape_.getBBox();
|
||||
|
||||
var topPosition = {
|
||||
@@ -476,10 +478,10 @@ Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
var closerPosition = bbox.width < bbox.height ? endPosition : bottomPosition;
|
||||
var fartherPosition = bbox.width < bbox.height ? bottomPosition : endPosition;
|
||||
|
||||
var topPositionOverlap = this.getOverlap_(topPosition, metrics);
|
||||
var startPositionOverlap = this.getOverlap_(startPosition, metrics);
|
||||
var closerPositionOverlap = this.getOverlap_(closerPosition, metrics);
|
||||
var fartherPositionOverlap = this.getOverlap_(fartherPosition, metrics);
|
||||
var topPositionOverlap = this.getOverlap_(topPosition, viewMetrics);
|
||||
var startPositionOverlap = this.getOverlap_(startPosition, viewMetrics);
|
||||
var closerPositionOverlap = this.getOverlap_(closerPosition, viewMetrics);
|
||||
var fartherPositionOverlap = this.getOverlap_(fartherPosition, viewMetrics);
|
||||
|
||||
// Set the position to whichever position shows the most of the bubble,
|
||||
// with tiebreaks going in the order: top > start > close > far.
|
||||
@@ -513,12 +515,12 @@ Blockly.Bubble.prototype.layoutBubble_ = function() {
|
||||
* workspace (what percentage of the bubble is visible).
|
||||
* @param {!{x: number, y: number}} relativeMin The position of the top-left
|
||||
* corner of the bubble relative to the anchor point.
|
||||
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
|
||||
* bubble will appear in.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The view metrics
|
||||
* of the workspace the bubble will appear in.
|
||||
* @return {number} The percentage of the bubble that is visible.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, metrics) {
|
||||
Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, viewMetrics) {
|
||||
// The position of the top-left corner of the bubble in workspace units.
|
||||
var bubbleMin = {
|
||||
x: this.workspace_.RTL ? (this.anchorXY_.x - relativeMin.x - this.width_) :
|
||||
@@ -534,11 +536,11 @@ Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, metrics) {
|
||||
// calculation.
|
||||
|
||||
// The position of the top-left corner of the workspace.
|
||||
var workspaceMin = {x: metrics.viewLeft, y: metrics.viewTop};
|
||||
var workspaceMin = {x: viewMetrics.left, y: viewMetrics.top};
|
||||
// The position of the bottom-right corner of the workspace.
|
||||
var workspaceMax = {
|
||||
x: metrics.viewLeft + metrics.viewWidth,
|
||||
y: metrics.viewTop + metrics.viewHeight
|
||||
x: viewMetrics.left + viewMetrics.width,
|
||||
y: viewMetrics.top + viewMetrics.height
|
||||
};
|
||||
|
||||
var overlapWidth = Math.min(bubbleMax.x, workspaceMax.x) -
|
||||
@@ -555,17 +557,17 @@ Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, metrics) {
|
||||
* Calculate what the optimal horizontal position of the top-left corner of the
|
||||
* bubble is (relative to the anchor point) so that the most area of the
|
||||
* bubble is shown.
|
||||
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
|
||||
* bubble will appear in.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The view metrics
|
||||
* of the workspace the bubble will appear in.
|
||||
* @return {number} The optimal horizontal position of the top-left corner
|
||||
* of the bubble.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
|
||||
Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(viewMetrics) {
|
||||
var relativeLeft = -this.width_ / 4;
|
||||
|
||||
// No amount of sliding left or right will give us a better overlap.
|
||||
if (this.width_ > metrics.viewWidth) {
|
||||
if (this.width_ > viewMetrics.width) {
|
||||
return relativeLeft;
|
||||
}
|
||||
|
||||
@@ -574,16 +576,16 @@ Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
|
||||
var bubbleRight = this.anchorXY_.x - relativeLeft;
|
||||
var bubbleLeft = bubbleRight - this.width_;
|
||||
|
||||
var workspaceRight = metrics.viewLeft + metrics.viewWidth;
|
||||
var workspaceLeft = metrics.viewLeft +
|
||||
var workspaceRight = viewMetrics.left + viewMetrics.width;
|
||||
var workspaceLeft = viewMetrics.left +
|
||||
// Thickness in workspace units.
|
||||
(Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale);
|
||||
} else {
|
||||
var bubbleLeft = relativeLeft + this.anchorXY_.x;
|
||||
var bubbleRight = bubbleLeft + this.width_;
|
||||
|
||||
var workspaceLeft = metrics.viewLeft;
|
||||
var workspaceRight = metrics.viewLeft + metrics.viewWidth -
|
||||
var workspaceLeft = viewMetrics.left;
|
||||
var workspaceRight = viewMetrics.left + viewMetrics.width -
|
||||
// Thickness in workspace units.
|
||||
(Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale);
|
||||
}
|
||||
@@ -613,24 +615,24 @@ Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
|
||||
* Calculate what the optimal vertical position of the top-left corner of
|
||||
* the bubble is (relative to the anchor point) so that the most area of the
|
||||
* bubble is shown.
|
||||
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
|
||||
* bubble will appear in.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The view metrics
|
||||
* of the workspace the bubble will appear in.
|
||||
* @return {number} The optimal vertical position of the top-left corner
|
||||
* of the bubble.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.getOptimalRelativeTop_ = function(metrics) {
|
||||
Blockly.Bubble.prototype.getOptimalRelativeTop_ = function(viewMetrics) {
|
||||
var relativeTop = -this.height_ / 4;
|
||||
|
||||
// No amount of sliding up or down will give us a better overlap.
|
||||
if (this.height_ > metrics.viewHeight) {
|
||||
if (this.height_ > viewMetrics.height) {
|
||||
return relativeTop;
|
||||
}
|
||||
|
||||
var bubbleTop = this.anchorXY_.y + relativeTop;
|
||||
var bubbleBottom = bubbleTop + this.height_;
|
||||
var workspaceTop = metrics.viewTop;
|
||||
var workspaceBottom = metrics.viewTop + metrics.viewHeight -
|
||||
var workspaceTop = viewMetrics.top;
|
||||
var workspaceBottom = viewMetrics.top + viewMetrics.height -
|
||||
// Thickness in workspace units.
|
||||
(Blockly.Scrollbar.scrollbarThickness / this.workspace_.scale);
|
||||
|
||||
@@ -820,10 +822,10 @@ Blockly.Bubble.prototype.setColour = function(hexColour) {
|
||||
*/
|
||||
Blockly.Bubble.prototype.dispose = function() {
|
||||
if (this.onMouseDownBubbleWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownBubbleWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseDownBubbleWrapper_);
|
||||
}
|
||||
if (this.onMouseDownResizeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseDownResizeWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseDownResizeWrapper_);
|
||||
}
|
||||
Blockly.Bubble.unbindDragEvents_();
|
||||
Blockly.utils.dom.removeNode(this.bubbleGroup_);
|
||||
@@ -887,8 +889,7 @@ Blockly.Bubble.prototype.setAutoLayout = function(enable) {
|
||||
*/
|
||||
Blockly.Bubble.textToDom = function(text) {
|
||||
var paragraph = Blockly.utils.dom.createSvgElement(
|
||||
Blockly.utils.Svg.TEXT,
|
||||
{
|
||||
Blockly.utils.Svg.TEXT, {
|
||||
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
|
||||
'y': Blockly.Bubble.BORDER_WIDTH
|
||||
},
|
||||
@@ -906,16 +907,18 @@ Blockly.Bubble.textToDom = function(text) {
|
||||
|
||||
/**
|
||||
* Creates a bubble that can not be edited.
|
||||
* @param {!SVGTextElement} paragraphElement The text element for the non editable bubble.
|
||||
* @param {!SVGTextElement} paragraphElement The text element for the non
|
||||
* editable bubble.
|
||||
* @param {!Blockly.BlockSvg} block The block that the bubble is attached to.
|
||||
* @param {!Blockly.utils.Coordinate} iconXY The coordinate of the icon.
|
||||
* @return {!Blockly.Bubble} The non editable bubble.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Bubble.createNonEditableBubble = function(paragraphElement, block, iconXY) {
|
||||
Blockly.Bubble.createNonEditableBubble = function(
|
||||
paragraphElement, block, iconXY) {
|
||||
var bubble = new Blockly.Bubble(
|
||||
/** @type {!Blockly.WorkspaceSvg} */ (block.workspace),
|
||||
paragraphElement, block.pathObject.svgPath,
|
||||
/** @type {!Blockly.WorkspaceSvg} */ (block.workspace), paragraphElement,
|
||||
block.pathObject.svgPath,
|
||||
/** @type {!Blockly.utils.Coordinate} */ (iconXY), null, null);
|
||||
// Expose this bubble's block's ID on its top-level SVG group.
|
||||
bubble.setSvgId(block.id);
|
||||
@@ -923,9 +926,8 @@ Blockly.Bubble.createNonEditableBubble = function(paragraphElement, block, iconX
|
||||
// Right-align the paragraph.
|
||||
// This cannot be done until the bubble is rendered on screen.
|
||||
var maxWidth = paragraphElement.getBBox().width;
|
||||
for (var i = 0, textElement;
|
||||
(textElement = paragraphElement.childNodes[i]); i++) {
|
||||
|
||||
for (var i = 0, textElement; (textElement = paragraphElement.childNodes[i]);
|
||||
i++) {
|
||||
textElement.setAttribute('text-anchor', 'end');
|
||||
textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH);
|
||||
}
|
||||
|
||||
@@ -12,14 +12,19 @@
|
||||
|
||||
goog.provide('Blockly.BubbleDragger');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Bubble');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.CommentMove');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
|
||||
goog.requireType('Blockly.BlockDragSurfaceSvg');
|
||||
goog.requireType('Blockly.IBubble');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -226,7 +231,7 @@ Blockly.BubbleDragger.prototype.endBubbleDrag = function(
|
||||
*/
|
||||
Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() {
|
||||
if (this.draggingBubble_.isComment) {
|
||||
var event = new Blockly.Events.CommentMove(
|
||||
var event = new (Blockly.Events.get(Blockly.Events.COMMENT_MOVE))(
|
||||
/** @type {!Blockly.WorkspaceCommentSvg} */ (this.draggingBubble_));
|
||||
event.setOldCoordinate(this.startXY_);
|
||||
event.recordNew();
|
||||
|
||||
@@ -12,19 +12,28 @@
|
||||
|
||||
goog.provide('Blockly.Comment');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Bubble');
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BubbleOpen');
|
||||
goog.require('Blockly.Icon');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Warning');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
goog.requireType('Blockly.utils.Size');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a comment.
|
||||
@@ -55,28 +64,28 @@ Blockly.Comment = function(block) {
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseUpWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Wheel event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onWheelWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Change event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onChangeWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Input event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onInputWrapper_ = null;
|
||||
@@ -161,21 +170,23 @@ Blockly.Comment.prototype.createEditor_ = function() {
|
||||
// Ideally this would be hooked to the focus event for the comment.
|
||||
// However doing so in Firefox swallows the cursor for unknown reasons.
|
||||
// So this is hooked to mouseup instead. No big deal.
|
||||
this.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseUpWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
textarea, 'mouseup', this, this.startEdit_, true, true);
|
||||
// Don't zoom with mousewheel.
|
||||
this.onWheelWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onWheelWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
textarea, 'wheel', this, function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
this.onChangeWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onChangeWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
textarea, 'change', this, function(_e) {
|
||||
if (this.cachedText_ != this.model_.text) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.cachedText_, this.model_.text));
|
||||
Blockly.Events.fire(
|
||||
new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this.block_, 'comment', null, this.cachedText_,
|
||||
this.model_.text));
|
||||
}
|
||||
});
|
||||
this.onInputWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onInputWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
textarea, 'input', this, function(_e) {
|
||||
this.model_.text = textarea.value;
|
||||
});
|
||||
@@ -235,8 +246,8 @@ Blockly.Comment.prototype.setVisible = function(visible) {
|
||||
if (visible == this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.fire(
|
||||
new Blockly.Events.BubbleOpen(this.block_, visible, 'comment'));
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BUBBLE_OPEN))(
|
||||
this.block_, visible, 'comment'));
|
||||
this.model_.pinned = visible;
|
||||
if (visible) {
|
||||
this.createBubble_();
|
||||
@@ -297,19 +308,19 @@ Blockly.Comment.prototype.createNonEditableBubble_ = function() {
|
||||
*/
|
||||
Blockly.Comment.prototype.disposeBubble_ = function() {
|
||||
if (this.onMouseUpWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseUpWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseUpWrapper_);
|
||||
this.onMouseUpWrapper_ = null;
|
||||
}
|
||||
if (this.onWheelWrapper_) {
|
||||
Blockly.unbindEvent_(this.onWheelWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onWheelWrapper_);
|
||||
this.onWheelWrapper_ = null;
|
||||
}
|
||||
if (this.onChangeWrapper_) {
|
||||
Blockly.unbindEvent_(this.onChangeWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onChangeWrapper_);
|
||||
this.onChangeWrapper_ = null;
|
||||
}
|
||||
if (this.onInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onInputWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onInputWrapper_);
|
||||
this.onInputWrapper_ = null;
|
||||
}
|
||||
this.bubble_.dispose();
|
||||
|
||||
@@ -12,14 +12,19 @@
|
||||
|
||||
goog.provide('Blockly.Connection');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.requireType('Blockly.IConnectionChecker');
|
||||
goog.requireType('Blockly.Input');
|
||||
|
||||
|
||||
/**
|
||||
@@ -120,7 +125,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
||||
shadowDom = /** @type {!Element} */ (Blockly.Xml.blockToDom(orphanBlock));
|
||||
orphanBlock.dispose(false);
|
||||
orphanBlock = null;
|
||||
} else if (parentConnection.type == Blockly.INPUT_VALUE) {
|
||||
} else if (parentConnection.type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
// Value connections.
|
||||
// If female block is already connected, disconnect and bump the male.
|
||||
if (!orphanBlock.outputConnection) {
|
||||
@@ -135,7 +140,8 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
||||
orphanBlock.outputConnection.connect(connection);
|
||||
orphanBlock = null;
|
||||
}
|
||||
} else if (parentConnection.type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (
|
||||
parentConnection.type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
// Statement connections.
|
||||
// Statement blocks may be inserted into the middle of a stack.
|
||||
// Split the stack.
|
||||
@@ -186,7 +192,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
||||
|
||||
var event;
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
event = new Blockly.Events.BlockMove(childBlock);
|
||||
event = new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(childBlock);
|
||||
}
|
||||
// Establish the connections.
|
||||
Blockly.Connection.connectReciprocally_(parentConnection, childConnection);
|
||||
@@ -232,8 +238,8 @@ Blockly.Connection.prototype.getSourceBlock = function() {
|
||||
* @return {boolean} True if connection faces down or right.
|
||||
*/
|
||||
Blockly.Connection.prototype.isSuperior = function() {
|
||||
return this.type == Blockly.INPUT_VALUE ||
|
||||
this.type == Blockly.NEXT_STATEMENT;
|
||||
return this.type == Blockly.connectionTypes.INPUT_VALUE ||
|
||||
this.type == Blockly.connectionTypes.NEXT_STATEMENT;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -380,7 +386,8 @@ Blockly.Connection.singleConnection_ = function(block, orphanBlock) {
|
||||
for (var i = 0; i < block.inputList.length; i++) {
|
||||
var thisConnection = block.inputList[i].connection;
|
||||
var typeChecker = output.getConnectionChecker();
|
||||
if (thisConnection && thisConnection.type == Blockly.INPUT_VALUE &&
|
||||
if (thisConnection &&
|
||||
thisConnection.type == Blockly.connectionTypes.INPUT_VALUE &&
|
||||
typeChecker.canConnect(output, thisConnection, false)) {
|
||||
if (connection) {
|
||||
return null; // More than one connection.
|
||||
@@ -464,7 +471,7 @@ Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
|
||||
childBlock) {
|
||||
var event;
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
event = new Blockly.Events.BlockMove(childBlock);
|
||||
event = new (Blockly.Events.get(Blockly.Events.BLOCK_MOVE))(childBlock);
|
||||
}
|
||||
var otherConnection = this.targetConnection;
|
||||
otherConnection.targetConnection = null;
|
||||
|
||||
@@ -13,11 +13,14 @@
|
||||
|
||||
goog.provide('Blockly.ConnectionChecker');
|
||||
|
||||
goog.require('Blockly.Connection');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.IConnectionChecker');
|
||||
goog.require('Blockly.registry');
|
||||
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.IConnectionChecker');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
|
||||
|
||||
/**
|
||||
@@ -197,9 +200,9 @@ Blockly.ConnectionChecker.prototype.doDragChecks = function(a, b, distance) {
|
||||
}
|
||||
|
||||
switch (b.type) {
|
||||
case Blockly.PREVIOUS_STATEMENT:
|
||||
case Blockly.connectionTypes.PREVIOUS_STATEMENT:
|
||||
return this.canConnectToPrevious_(a, b);
|
||||
case Blockly.OUTPUT_VALUE: {
|
||||
case Blockly.connectionTypes.OUTPUT_VALUE: {
|
||||
// Don't offer to connect an already connected left (male) value plug to
|
||||
// an available right (female) value plug.
|
||||
if ((b.isConnected() &&
|
||||
@@ -209,7 +212,7 @@ Blockly.ConnectionChecker.prototype.doDragChecks = function(a, b, distance) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Blockly.INPUT_VALUE: {
|
||||
case Blockly.connectionTypes.INPUT_VALUE: {
|
||||
// Offering to connect the left (male) of a value block to an already
|
||||
// connected value pair is ok, we'll splice it in.
|
||||
// However, don't offer to splice into an immovable block.
|
||||
@@ -220,7 +223,7 @@ Blockly.ConnectionChecker.prototype.doDragChecks = function(a, b, distance) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Blockly.NEXT_STATEMENT: {
|
||||
case Blockly.connectionTypes.NEXT_STATEMENT: {
|
||||
// Don't let a block with no next connection bump other blocks out of the
|
||||
// stack. But covering up a shadow block or stack of shadow blocks is
|
||||
// fine. Similarly, replacing a terminal statement with another terminal
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
|
||||
goog.provide('Blockly.ConnectionDB');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.RenderedConnection');
|
||||
|
||||
goog.requireType('Blockly.IConnectionChecker');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
@@ -288,9 +291,13 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
|
||||
Blockly.ConnectionDB.init = function(checker) {
|
||||
// Create four databases, one for each connection type.
|
||||
var dbList = [];
|
||||
dbList[Blockly.INPUT_VALUE] = new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.OUTPUT_VALUE] = new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.NEXT_STATEMENT] = new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.PREVIOUS_STATEMENT] = new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.connectionTypes.INPUT_VALUE] =
|
||||
new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.connectionTypes.OUTPUT_VALUE] =
|
||||
new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.connectionTypes.NEXT_STATEMENT] =
|
||||
new Blockly.ConnectionDB(checker);
|
||||
dbList[Blockly.connectionTypes.PREVIOUS_STATEMENT] =
|
||||
new Blockly.ConnectionDB(checker);
|
||||
return dbList;
|
||||
};
|
||||
|
||||
29
core/connection_types.js
Normal file
29
core/connection_types.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview An enum for the possible types of connections.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.connectionTypes');
|
||||
|
||||
/**
|
||||
* Enum for the type of a connection or input.
|
||||
* @enum {number}
|
||||
*/
|
||||
Blockly.connectionTypes = {
|
||||
// A right-facing value input. E.g. 'set item to' or 'return'.
|
||||
INPUT_VALUE: 1,
|
||||
// A left-facing value output. E.g. 'random fraction'.
|
||||
OUTPUT_VALUE: 2,
|
||||
// A down-facing block stack. E.g. 'if-do' or 'else'.
|
||||
NEXT_STATEMENT: 3,
|
||||
// An up-facing block stack. E.g. 'break out of loop'.
|
||||
PREVIOUS_STATEMENT: 4
|
||||
};
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
goog.provide('Blockly.constants');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
|
||||
|
||||
/**
|
||||
* The multiplier for scroll wheel deltas using the line delta mode.
|
||||
* @type {number}
|
||||
@@ -110,52 +113,14 @@ Blockly.SPRITE = {
|
||||
// Constants below this point are not intended to be changed.
|
||||
|
||||
/**
|
||||
* ENUM for a right-facing value input. E.g. 'set item to' or 'return'.
|
||||
* @const
|
||||
* Enum for alignment of inputs.
|
||||
* @enum {number}
|
||||
*/
|
||||
Blockly.INPUT_VALUE = 1;
|
||||
|
||||
/**
|
||||
* ENUM for a left-facing value output. E.g. 'random fraction'.
|
||||
* @const
|
||||
*/
|
||||
Blockly.OUTPUT_VALUE = 2;
|
||||
|
||||
/**
|
||||
* ENUM for a down-facing block stack. E.g. 'if-do' or 'else'.
|
||||
* @const
|
||||
*/
|
||||
Blockly.NEXT_STATEMENT = 3;
|
||||
|
||||
/**
|
||||
* ENUM for an up-facing block stack. E.g. 'break out of loop'.
|
||||
* @const
|
||||
*/
|
||||
Blockly.PREVIOUS_STATEMENT = 4;
|
||||
|
||||
/**
|
||||
* ENUM for an dummy input. Used to add field(s) with no input.
|
||||
* @const
|
||||
*/
|
||||
Blockly.DUMMY_INPUT = 5;
|
||||
|
||||
/**
|
||||
* ENUM for left alignment.
|
||||
* @const
|
||||
*/
|
||||
Blockly.ALIGN_LEFT = -1;
|
||||
|
||||
/**
|
||||
* ENUM for centre alignment.
|
||||
* @const
|
||||
*/
|
||||
Blockly.ALIGN_CENTRE = 0;
|
||||
|
||||
/**
|
||||
* ENUM for right alignment.
|
||||
* @const
|
||||
*/
|
||||
Blockly.ALIGN_RIGHT = 1;
|
||||
Blockly.constants.ALIGN = {
|
||||
LEFT: -1,
|
||||
CENTRE: 0,
|
||||
RIGHT: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* ENUM for no drag operation.
|
||||
@@ -187,35 +152,14 @@ Blockly.DRAG_FREE = 2;
|
||||
* @const
|
||||
*/
|
||||
Blockly.OPPOSITE_TYPE = [];
|
||||
Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE] = Blockly.OUTPUT_VALUE;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE] = Blockly.INPUT_VALUE;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT] = Blockly.PREVIOUS_STATEMENT;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT] = Blockly.NEXT_STATEMENT;
|
||||
|
||||
|
||||
/**
|
||||
* ENUM for toolbox and flyout at top of screen.
|
||||
* @const
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_TOP = 0;
|
||||
|
||||
/**
|
||||
* ENUM for toolbox and flyout at bottom of screen.
|
||||
* @const
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_BOTTOM = 1;
|
||||
|
||||
/**
|
||||
* ENUM for toolbox and flyout at left of screen.
|
||||
* @const
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_LEFT = 2;
|
||||
|
||||
/**
|
||||
* ENUM for toolbox and flyout at right of screen.
|
||||
* @const
|
||||
*/
|
||||
Blockly.TOOLBOX_AT_RIGHT = 3;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.INPUT_VALUE] =
|
||||
Blockly.connectionTypes.OUTPUT_VALUE;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.OUTPUT_VALUE] =
|
||||
Blockly.connectionTypes.INPUT_VALUE;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.NEXT_STATEMENT] =
|
||||
Blockly.connectionTypes.PREVIOUS_STATEMENT;
|
||||
Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.PREVIOUS_STATEMENT] =
|
||||
Blockly.connectionTypes.NEXT_STATEMENT;
|
||||
|
||||
/**
|
||||
* ENUM representing that an event is not in any delete areas.
|
||||
@@ -275,3 +219,15 @@ Blockly.RENAME_VARIABLE_ID = 'RENAME_VARIABLE_ID';
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.DELETE_VARIABLE_ID = 'DELETE_VARIABLE_ID';
|
||||
|
||||
/**
|
||||
* The language-neutral id given to the collapsed input.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.constants.COLLAPSED_INPUT_NAME = '_TEMP_COLLAPSED_INPUT';
|
||||
|
||||
/**
|
||||
* The language-neutral id given to the collapsed field.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.constants.COLLAPSED_FIELD_NAME = '_TEMP_COLLAPSED_FIELD';
|
||||
|
||||
@@ -16,19 +16,27 @@
|
||||
*/
|
||||
goog.provide('Blockly.ContextMenu');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Menu');
|
||||
goog.require('Blockly.MenuItem');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.WidgetDiv');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Which block is the context menu attached to?
|
||||
@@ -147,8 +155,9 @@ Blockly.ContextMenu.createWidget_ = function(menu) {
|
||||
Blockly.utils.dom.addClass(
|
||||
/** @type {!Element} */ (menuDom), 'blocklyContextMenu');
|
||||
// Prevent system context menu when right-clicking a Blockly context menu.
|
||||
Blockly.bindEventWithChecks_(/** @type {!EventTarget} */ (menuDom),
|
||||
'contextmenu', null, Blockly.utils.noEvent);
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
/** @type {!EventTarget} */ (menuDom), 'contextmenu', null,
|
||||
Blockly.utils.noEvent);
|
||||
// Focus only after the initial render to avoid issue #1329.
|
||||
menu.focus();
|
||||
};
|
||||
@@ -196,7 +205,8 @@ Blockly.ContextMenu.callbackFactory = function(block, xml) {
|
||||
Blockly.Events.enable();
|
||||
}
|
||||
if (Blockly.Events.isEnabled() && !newBlock.isShadow()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock));
|
||||
Blockly.Events.fire(
|
||||
new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock));
|
||||
}
|
||||
newBlock.select();
|
||||
};
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
*/
|
||||
goog.provide('Blockly.ContextMenuItems');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.ContextMenuRegistry');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.inputTypes');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
|
||||
|
||||
/** Option to undo previous action. */
|
||||
Blockly.ContextMenuItems.registerUndo = function() {
|
||||
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
||||
@@ -63,7 +68,7 @@ Blockly.ContextMenuItems.registerRedo = function() {
|
||||
};
|
||||
Blockly.ContextMenuRegistry.registry.register(redoOption);
|
||||
};
|
||||
|
||||
|
||||
/** Option to clean up blocks. */
|
||||
Blockly.ContextMenuItems.registerCleanup = function() {
|
||||
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
||||
@@ -89,7 +94,7 @@ Blockly.ContextMenuItems.registerCleanup = function() {
|
||||
};
|
||||
Blockly.ContextMenuRegistry.registry.register(cleanOption);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a callback to collapse or expand top blocks.
|
||||
* @param {boolean} shouldCollapse Whether a block should collapse.
|
||||
@@ -141,7 +146,7 @@ Blockly.ContextMenuItems.registerCollapse = function() {
|
||||
};
|
||||
Blockly.ContextMenuRegistry.registry.register(collapseOption);
|
||||
};
|
||||
|
||||
|
||||
/** Option to expand all blocks. */
|
||||
Blockly.ContextMenuItems.registerExpand = function() {
|
||||
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
||||
@@ -174,7 +179,7 @@ Blockly.ContextMenuItems.registerExpand = function() {
|
||||
};
|
||||
Blockly.ContextMenuRegistry.registry.register(expandOption);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a block and its children to a list of deletable blocks.
|
||||
* @param {!Blockly.BlockSvg} block to delete.
|
||||
@@ -192,7 +197,7 @@ Blockly.ContextMenuItems.addDeletableBlocks_ = function(block, deleteList) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a list of blocks that can be deleted in the given workspace.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace to delete all blocks from.
|
||||
@@ -207,7 +212,7 @@ Blockly.ContextMenuItems.getDeletableBlocks_ = function(workspace) {
|
||||
}
|
||||
return deleteList;
|
||||
};
|
||||
|
||||
|
||||
/** Deletes the given blocks. Used to delete all blocks in the workspace.
|
||||
* @param {!Array.<!Blockly.BlockSvg>} deleteList list of blocks to delete.
|
||||
* @param {string} eventGroup event group id with which all delete events should be associated.
|
||||
@@ -227,7 +232,7 @@ Blockly.ContextMenuItems.deleteNext_ = function(deleteList, eventGroup) {
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
};
|
||||
|
||||
|
||||
/** Option to delete all blocks. */
|
||||
Blockly.ContextMenuItems.registerDeleteAll = function() {
|
||||
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
||||
@@ -369,8 +374,8 @@ Blockly.ContextMenuItems.registerInline = function() {
|
||||
if (!block.isInFlyout && block.isMovable() && !block.isCollapsed()) {
|
||||
for (var i = 1; i < block.inputList.length; i++) {
|
||||
// Only display this option if there are two value or dummy inputs next to each other.
|
||||
if (block.inputList[i - 1].type != Blockly.NEXT_STATEMENT &&
|
||||
block.inputList[i].type != Blockly.NEXT_STATEMENT) {
|
||||
if (block.inputList[i - 1].type != Blockly.inputTypes.STATEMENT &&
|
||||
block.inputList[i].type != Blockly.inputTypes.STATEMENT) {
|
||||
return 'enabled';
|
||||
}
|
||||
}
|
||||
@@ -533,4 +538,5 @@ Blockly.ContextMenuItems.registerDefaultOptions = function() {
|
||||
Blockly.ContextMenuItems.registerWorkspaceOptions_();
|
||||
Blockly.ContextMenuItems.registerBlockOptions_();
|
||||
};
|
||||
|
||||
|
||||
Blockly.ContextMenuItems.registerDefaultOptions();
|
||||
|
||||
@@ -16,15 +16,17 @@
|
||||
*/
|
||||
goog.provide('Blockly.ContextMenuRegistry');
|
||||
|
||||
goog.require('Blockly.ContextMenuItems');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for the registry of context menu items. This is intended to be a singleton. You should
|
||||
* not create a new instance, and only access this class from Blockly.ContextMenuRegistry.registry.
|
||||
* Class for the registry of context menu items. This is intended to be a
|
||||
* singleton. You should not create a new instance, and only access this class
|
||||
* from Blockly.ContextMenuRegistry.registry.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.ContextMenuRegistry = function() {
|
||||
|
||||
// Singleton instance should be registered once.
|
||||
Blockly.ContextMenuRegistry.registry = this;
|
||||
|
||||
@@ -34,7 +36,6 @@ Blockly.ContextMenuRegistry = function() {
|
||||
* @private
|
||||
*/
|
||||
this.registry_ = {};
|
||||
Blockly.ContextMenuItems.registerDefaultOptions();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -83,7 +84,8 @@ Blockly.ContextMenuRegistry.RegistryItem;
|
||||
Blockly.ContextMenuRegistry.ContextMenuOption;
|
||||
|
||||
/**
|
||||
* Singleton instance of this class. All interactions with this class should be done on this object.
|
||||
* Singleton instance of this class. All interactions with this class should be
|
||||
* done on this object.
|
||||
* @type {?Blockly.ContextMenuRegistry}
|
||||
*/
|
||||
Blockly.ContextMenuRegistry.registry = null;
|
||||
|
||||
@@ -17,10 +17,13 @@ goog.provide('Blockly.DropDownDiv');
|
||||
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.style');
|
||||
|
||||
goog.requireType('Blockly.utils.Rect');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.utils.Size');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -148,7 +151,7 @@ Blockly.DropDownDiv.BoundsInfo;
|
||||
* }}
|
||||
*/
|
||||
Blockly.DropDownDiv.PositionMetrics;
|
||||
|
||||
|
||||
/**
|
||||
* Create and insert the DOM element for this div.
|
||||
* @package
|
||||
|
||||
@@ -22,12 +22,14 @@ goog.provide('Blockly.Events.Move'); // Deprecated.
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Abstract');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.xml');
|
||||
// TODO: Fix recursive dependency.
|
||||
// goog.require('Blockly.Xml');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
|
||||
|
||||
/**
|
||||
@@ -200,7 +202,7 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
||||
var dom = Blockly.Xml.textToDom(/** @type {string} */ (value) || '<mutation/>');
|
||||
block.domToMutation(dom);
|
||||
}
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.CHANGE))(
|
||||
block, 'mutation', null, oldMutation, value));
|
||||
break;
|
||||
default:
|
||||
@@ -544,12 +546,13 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
||||
} else {
|
||||
var blockConnection = block.outputConnection || block.previousConnection;
|
||||
var parentConnection;
|
||||
var connectionType = blockConnection.type;
|
||||
if (inputName) {
|
||||
var input = parentBlock.getInput(inputName);
|
||||
if (input) {
|
||||
parentConnection = input.connection;
|
||||
}
|
||||
} else if (blockConnection.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
} else if (connectionType == Blockly.connectionTypes.PREVIOUS_STATEMENT) {
|
||||
parentConnection = parentBlock.nextConnection;
|
||||
}
|
||||
if (parentConnection) {
|
||||
|
||||
@@ -19,6 +19,10 @@ goog.provide('Blockly.Events');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Events.Abstract');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
* Group ID for new events. Grouped events are indivisible.
|
||||
@@ -196,11 +200,22 @@ Blockly.Events.COMMENT_MOVE = 'comment_move';
|
||||
Blockly.Events.FINISHED_LOADING = 'finished_loading';
|
||||
|
||||
/**
|
||||
* List of events that cause objects to be bumped back into the visible
|
||||
* portion of the workspace (only used for non-movable workspaces).
|
||||
* Type of events that cause objects to be bumped back into the visible
|
||||
* portion of the workspace.
|
||||
*
|
||||
* Not to be confused with bumping so that disconnected connections to do
|
||||
* not appear connected.
|
||||
* Not to be confused with bumping so that disconnected connections do not
|
||||
* appear connected.
|
||||
* @typedef {!Blockly.Events.BlockCreate|!Blockly.Events.BlockMove|
|
||||
* !Blockly.Events.CommentCreate|!Blockly.Events.CommentMove}
|
||||
*/
|
||||
Blockly.Events.BumpEvent;
|
||||
|
||||
/**
|
||||
* List of events that cause objects to be bumped back into the visible
|
||||
* portion of the workspace.
|
||||
*
|
||||
* Not to be confused with bumping so that disconnected connections do not
|
||||
* appear connected.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.BUMP_EVENTS = [
|
||||
@@ -395,8 +410,7 @@ Blockly.Events.getDescendantIds = function(block) {
|
||||
* @throws {Error} if an event type is not found in the registry.
|
||||
*/
|
||||
Blockly.Events.fromJson = function(json, workspace) {
|
||||
var eventClass = Blockly.registry.getClass(Blockly.registry.Type.EVENT,
|
||||
json.type);
|
||||
var eventClass = Blockly.Events.get(json.type);
|
||||
if (!eventClass) {
|
||||
throw Error('Unknown event type.');
|
||||
}
|
||||
@@ -406,6 +420,16 @@ Blockly.Events.fromJson = function(json, workspace) {
|
||||
return event;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the class for a specific event type from the registry.
|
||||
* @param {string} eventType The type of the event to get.
|
||||
* @return {?function(new:Blockly.Events.Abstract, ...?)} The event class with
|
||||
* the given type or null if none exists.
|
||||
*/
|
||||
Blockly.Events.get = function(eventType) {
|
||||
return Blockly.registry.getClass(Blockly.registry.Type.EVENT, eventType);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable/disable a block depending on whether it is properly connected.
|
||||
* Use this on applications where all blocks should be connected to a top block.
|
||||
|
||||
@@ -15,6 +15,8 @@ goog.provide('Blockly.Events.Abstract');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for an event.
|
||||
|
||||
@@ -17,6 +17,9 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a block drag event.
|
||||
* @param {!Blockly.Block=} opt_block The top block in the stack that is being
|
||||
|
||||
@@ -17,6 +17,9 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a bubble open event.
|
||||
* @param {Blockly.BlockSvg} opt_block The associated block. Undefined for a
|
||||
|
||||
@@ -17,6 +17,9 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a click event.
|
||||
* @param {?Blockly.Block=} opt_block The affected block. Null for click events
|
||||
|
||||
@@ -17,6 +17,11 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.ASTNode');
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a marker move event.
|
||||
* @param {?Blockly.Block=} opt_block The affected block. Null if current node
|
||||
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a selected event.
|
||||
* @param {?string=} opt_oldElementId The id of the previously selected
|
||||
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a theme change event.
|
||||
* @param {string=} opt_themeName The theme name. Undefined for a blank event.
|
||||
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a toolbox item select event.
|
||||
* @param {?string=} opt_oldItem The previously selected toolbox item. Undefined
|
||||
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a trashcan open event.
|
||||
* @param {boolean=} opt_isOpen Whether the trashcan flyout is opening (false if
|
||||
|
||||
@@ -17,6 +17,7 @@ goog.require('Blockly.Events.UiBase');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a viewport change event.
|
||||
* @param {number=} opt_top Top-edge of the visible portion of the workspace,
|
||||
@@ -27,11 +28,13 @@ goog.require('Blockly.utils.object');
|
||||
* event.
|
||||
* @param {string=} opt_workspaceId The workspace identifier for this event.
|
||||
* Undefined for a blank event.
|
||||
* @param {number=} opt_oldScale The old scale of the workspace. Undefined for a
|
||||
* blank event.
|
||||
* @extends {Blockly.Events.UiBase}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.ViewportChange = function(opt_top, opt_left, opt_scale,
|
||||
opt_workspaceId) {
|
||||
opt_workspaceId, opt_oldScale) {
|
||||
Blockly.Events.ViewportChange.superClass_.constructor.call(this, opt_workspaceId);
|
||||
|
||||
/**
|
||||
@@ -53,6 +56,12 @@ Blockly.Events.ViewportChange = function(opt_top, opt_left, opt_scale,
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale = opt_scale;
|
||||
|
||||
/**
|
||||
* The old scale of the workspace.
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.oldScale = opt_oldScale;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.Events.ViewportChange,
|
||||
Blockly.Events.UiBase);
|
||||
@@ -72,6 +81,7 @@ Blockly.Events.ViewportChange.prototype.toJson = function() {
|
||||
json['viewTop'] = this.viewTop;
|
||||
json['viewLeft'] = this.viewLeft;
|
||||
json['scale'] = this.scale;
|
||||
json['oldScale'] = this.oldScale;
|
||||
return json;
|
||||
};
|
||||
|
||||
@@ -84,6 +94,7 @@ Blockly.Events.ViewportChange.prototype.fromJson = function(json) {
|
||||
this.viewTop = json['viewTop'];
|
||||
this.viewLeft = json['viewLeft'];
|
||||
this.scale = json['scale'];
|
||||
this.oldScale = json['oldScale'];
|
||||
};
|
||||
|
||||
Blockly.registry.register(Blockly.registry.Type.EVENT,
|
||||
|
||||
@@ -18,6 +18,9 @@ goog.require('Blockly.Events.Abstract');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a UI event.
|
||||
* UI events are events that don't need to be sent over the wire for multi-user
|
||||
|
||||
@@ -20,6 +20,8 @@ goog.require('Blockly.Events.Abstract');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.VariableModel');
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for a variable event.
|
||||
|
||||
@@ -17,6 +17,8 @@ goog.require('Blockly.Events.Abstract');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a finished loading event.
|
||||
|
||||
@@ -22,8 +22,7 @@ goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.xml');
|
||||
// TODO: Fix recursive dependency.
|
||||
// goog.require('Blockly.Xml');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
|
||||
/**
|
||||
@@ -127,6 +126,7 @@ Blockly.Events.CommentChange.prototype.type = Blockly.Events.COMMENT_CHANGE;
|
||||
*/
|
||||
Blockly.Events.CommentChange.prototype.toJson = function() {
|
||||
var json = Blockly.Events.CommentChange.superClass_.toJson.call(this);
|
||||
json['oldContents'] = this.oldContents_;
|
||||
json['newContents'] = this.newContents_;
|
||||
return json;
|
||||
};
|
||||
@@ -137,7 +137,8 @@ Blockly.Events.CommentChange.prototype.toJson = function() {
|
||||
*/
|
||||
Blockly.Events.CommentChange.prototype.fromJson = function(json) {
|
||||
Blockly.Events.CommentChange.superClass_.fromJson.call(this, json);
|
||||
this.newContents_ = json['newValue'];
|
||||
this.oldContents_ = json['oldContents'];
|
||||
this.newContents_ = json['newContents'];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -359,6 +360,10 @@ Blockly.Events.CommentMove.prototype.setOldCoordinate = function(xy) {
|
||||
// TODO (#1266): "Full" and "minimal" serialization.
|
||||
Blockly.Events.CommentMove.prototype.toJson = function() {
|
||||
var json = Blockly.Events.CommentMove.superClass_.toJson.call(this);
|
||||
if (this.oldCoordinate_) {
|
||||
json['oldCoordinate'] = Math.round(this.oldCoordinate_.x) + ',' +
|
||||
Math.round(this.oldCoordinate_.y);
|
||||
}
|
||||
if (this.newCoordinate_) {
|
||||
json['newCoordinate'] = Math.round(this.newCoordinate_.x) + ',' +
|
||||
Math.round(this.newCoordinate_.y);
|
||||
@@ -373,6 +378,11 @@ Blockly.Events.CommentMove.prototype.toJson = function() {
|
||||
Blockly.Events.CommentMove.prototype.fromJson = function(json) {
|
||||
Blockly.Events.CommentMove.superClass_.fromJson.call(this, json);
|
||||
|
||||
if (json['oldCoordinate']) {
|
||||
var xy = json['oldCoordinate'].split(',');
|
||||
this.oldCoordinate_ =
|
||||
new Blockly.utils.Coordinate(Number(xy[0]), Number(xy[1]));
|
||||
}
|
||||
if (json['newCoordinate']) {
|
||||
var xy = json['newCoordinate'].split(',');
|
||||
this.newCoordinate_ =
|
||||
|
||||
@@ -21,6 +21,8 @@ goog.provide('Blockly.Extensions');
|
||||
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
|
||||
|
||||
/**
|
||||
* The set of all registered extensions, keyed by extension name/id.
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
|
||||
goog.provide('Blockly.Field');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Gesture');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.utils');
|
||||
@@ -26,12 +29,17 @@ goog.require('Blockly.utils.style');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.IKeyboardAccessible');
|
||||
goog.requireType('Blockly.Input');
|
||||
goog.requireType('Blockly.IRegistrable');
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,7 +54,7 @@ goog.requireType('Blockly.ShortcutRegistry');
|
||||
* @constructor
|
||||
* @implements {Blockly.IASTNodeLocationSvg}
|
||||
* @implements {Blockly.IASTNodeLocationWithBlock}
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
* @implements {Blockly.IKeyboardAccessible}
|
||||
* @implements {Blockly.IRegistrable}
|
||||
*/
|
||||
Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
@@ -126,7 +134,7 @@ Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
|
||||
/**
|
||||
* Mouse down event listener data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.mouseDownWrapper_ = null;
|
||||
@@ -376,9 +384,8 @@ Blockly.Field.prototype.createTextElement_ = function() {
|
||||
*/
|
||||
Blockly.Field.prototype.bindEvents_ = function() {
|
||||
Blockly.Tooltip.bindMouseEvents(this.getClickTarget_());
|
||||
this.mouseDownWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
|
||||
this.mouseDownWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -414,7 +421,7 @@ Blockly.Field.prototype.dispose = function() {
|
||||
Blockly.Tooltip.unbindMouseEvents(this.getClickTarget_());
|
||||
|
||||
if (this.mouseDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.mouseDownWrapper_);
|
||||
Blockly.browserEvents.unbind(this.mouseDownWrapper_);
|
||||
}
|
||||
|
||||
Blockly.utils.dom.removeNode(this.fieldGroup_);
|
||||
@@ -826,7 +833,7 @@ Blockly.Field.prototype.setValue = function(newValue) {
|
||||
}
|
||||
|
||||
if (source && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
source, 'field', this.name || null, oldValue, newValue));
|
||||
}
|
||||
this.doValueUpdate_(newValue);
|
||||
@@ -1024,13 +1031,12 @@ Blockly.Field.prototype.isTabNavigable = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard accessibility mode is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} _action The action to be handled.
|
||||
* @return {boolean} True if the field handled the action, false otherwise.
|
||||
* @package
|
||||
* Handles the given keyboard shortcut.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} _shortcut The shortcut to be handled.
|
||||
* @return {boolean} True if the shortcut has been handled, false otherwise.
|
||||
* @public
|
||||
*/
|
||||
Blockly.Field.prototype.onBlocklyAction = function(_action) {
|
||||
Blockly.Field.prototype.onShortcut = function(_shortcut) {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -1077,6 +1083,7 @@ Blockly.Field.prototype.updateMarkers_ = function() {
|
||||
workspace.getCursor().draw();
|
||||
}
|
||||
if (workspace.keyboardAccessibilityMode && this.markerSvg_) {
|
||||
workspace.getMarker(Blockly.navigation.MARKER_NAME).draw();
|
||||
// TODO(#4592): Update all markers on the field.
|
||||
workspace.getMarker(Blockly.MarkerManager.LOCAL_MARKER).draw();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
goog.provide('Blockly.FieldAngle');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
@@ -88,21 +89,21 @@ Blockly.FieldAngle = function(opt_value, opt_validator, opt_config) {
|
||||
|
||||
/**
|
||||
* Wrapper click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.clickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Surface click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.clickSurfaceWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Surface mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.moveSurfaceWrapper_ = null;
|
||||
@@ -331,16 +332,14 @@ Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
// mousemove even if it's not in the middle of a drag. In future we may
|
||||
// change this behaviour.
|
||||
this.clickWrapper_ =
|
||||
Blockly.bindEventWithChecks_(svg, 'click', this, this.hide_);
|
||||
Blockly.browserEvents.conditionalBind(svg, 'click', this, this.hide_);
|
||||
// On touch devices, the picker's value is only updated with a drag. Add
|
||||
// a click handler on the drag surface to update the value if the surface
|
||||
// is clicked.
|
||||
this.clickSurfaceWrapper_ =
|
||||
Blockly.bindEventWithChecks_(circle, 'click', this, this.onMouseMove_,
|
||||
true, true);
|
||||
this.moveSurfaceWrapper_ =
|
||||
Blockly.bindEventWithChecks_(circle, 'mousemove', this, this.onMouseMove_,
|
||||
true, true);
|
||||
this.clickSurfaceWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
circle, 'click', this, this.onMouseMove_, true, true);
|
||||
this.moveSurfaceWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
circle, 'mousemove', this, this.onMouseMove_, true, true);
|
||||
return svg;
|
||||
};
|
||||
|
||||
@@ -350,15 +349,15 @@ Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.dropdownDispose_ = function() {
|
||||
if (this.clickWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
Blockly.browserEvents.unbind(this.clickWrapper_);
|
||||
this.clickWrapper_ = null;
|
||||
}
|
||||
if (this.clickSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.clickSurfaceWrapper_);
|
||||
Blockly.browserEvents.unbind(this.clickSurfaceWrapper_);
|
||||
this.clickSurfaceWrapper_ = null;
|
||||
}
|
||||
if (this.moveSurfaceWrapper_) {
|
||||
Blockly.unbindEvent_(this.moveSurfaceWrapper_);
|
||||
Blockly.browserEvents.unbind(this.moveSurfaceWrapper_);
|
||||
this.moveSurfaceWrapper_ = null;
|
||||
}
|
||||
this.gauge_ = null;
|
||||
|
||||
@@ -12,13 +12,12 @@
|
||||
|
||||
goog.provide('Blockly.FieldCheckbox');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Size');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
goog.provide('Blockly.FieldColour');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.colour');
|
||||
goog.require('Blockly.utils.dom');
|
||||
@@ -27,7 +27,6 @@ goog.require('Blockly.utils.KeyCodes');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Size');
|
||||
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
|
||||
/**
|
||||
* Class for a colour input field.
|
||||
@@ -62,35 +61,35 @@ Blockly.FieldColour = function(opt_value, opt_validator, opt_config) {
|
||||
|
||||
/**
|
||||
* Mouse click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onClickWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse move event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseMoveWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse enter event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseEnterWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Mouse leave event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseLeaveWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownWrapper_ = null;
|
||||
@@ -189,7 +188,7 @@ Blockly.FieldColour.prototype.initView = function() {
|
||||
Blockly.FieldColour.prototype.applyColour = function() {
|
||||
if (!this.getConstants().FIELD_COLOUR_FULL_BLOCK) {
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.style.fill = this.getValue();
|
||||
this.borderRect_.style.fill = /** @type {string} */ (this.getValue());
|
||||
}
|
||||
} else {
|
||||
this.sourceBlock_.pathObject.svgPath.setAttribute('fill', this.getValue());
|
||||
@@ -219,7 +218,7 @@ Blockly.FieldColour.prototype.doClassValidation_ = function(opt_newValue) {
|
||||
Blockly.FieldColour.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.style.fill = newValue;
|
||||
this.borderRect_.style.fill = /** @type {string} */ (newValue);
|
||||
} else if (this.sourceBlock_ && this.sourceBlock_.rendered) {
|
||||
this.sourceBlock_.pathObject.svgPath.setAttribute('fill', newValue);
|
||||
this.sourceBlock_.pathObject.svgPath.setAttribute('stroke', '#fff');
|
||||
@@ -382,35 +381,6 @@ Blockly.FieldColour.prototype.onKeyDown_ = function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard accessibility mode is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the field handled the action, false otherwise.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldColour.prototype.onBlocklyAction = function(action) {
|
||||
if (this.picker_) {
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.moveHighlightBy_(0, -1);
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.moveHighlightBy_(0, 1);
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.OUT:
|
||||
this.moveHighlightBy_(-1, 0);
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.IN:
|
||||
this.moveHighlightBy_(1, 0);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Blockly.FieldColour.superClass_.onBlocklyAction.call(this, action);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move the currently highlighted position by dx and dy.
|
||||
* @param {number} dx Change of x
|
||||
@@ -586,16 +556,16 @@ Blockly.FieldColour.prototype.dropdownCreate_ = function() {
|
||||
}
|
||||
|
||||
// Configure event handler on the table to listen for any event in a cell.
|
||||
this.onClickWrapper_ = Blockly.bindEventWithChecks_(table,
|
||||
'click', this, this.onClick_, true);
|
||||
this.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(table,
|
||||
'mousemove', this, this.onMouseMove_, true);
|
||||
this.onMouseEnterWrapper_ = Blockly.bindEventWithChecks_(table,
|
||||
'mouseenter', this, this.onMouseEnter_, true);
|
||||
this.onMouseLeaveWrapper_ = Blockly.bindEventWithChecks_(table,
|
||||
'mouseleave', this, this.onMouseLeave_, true);
|
||||
this.onKeyDownWrapper_ = Blockly.bindEventWithChecks_(table,
|
||||
'keydown', this, this.onKeyDown_);
|
||||
this.onClickWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
table, 'click', this, this.onClick_, true);
|
||||
this.onMouseMoveWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
table, 'mousemove', this, this.onMouseMove_, true);
|
||||
this.onMouseEnterWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
table, 'mouseenter', this, this.onMouseEnter_, true);
|
||||
this.onMouseLeaveWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
table, 'mouseleave', this, this.onMouseLeave_, true);
|
||||
this.onKeyDownWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
table, 'keydown', this, this.onKeyDown_);
|
||||
|
||||
return table;
|
||||
};
|
||||
@@ -606,23 +576,23 @@ Blockly.FieldColour.prototype.dropdownCreate_ = function() {
|
||||
*/
|
||||
Blockly.FieldColour.prototype.dropdownDispose_ = function() {
|
||||
if (this.onClickWrapper_) {
|
||||
Blockly.unbindEvent_(this.onClickWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onClickWrapper_);
|
||||
this.onClickWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseMoveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseMoveWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseMoveWrapper_);
|
||||
this.onMouseMoveWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseEnterWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseEnterWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseEnterWrapper_);
|
||||
this.onMouseEnterWrapper_ = null;
|
||||
}
|
||||
if (this.onMouseLeaveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseLeaveWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseLeaveWrapper_);
|
||||
this.onMouseLeaveWrapper_ = null;
|
||||
}
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onKeyDownWrapper_);
|
||||
this.onKeyDownWrapper_ = null;
|
||||
}
|
||||
this.picker_ = null;
|
||||
|
||||
@@ -14,25 +14,19 @@
|
||||
|
||||
goog.provide('Blockly.FieldDropdown');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
goog.require('Blockly.Menu');
|
||||
goog.require('Blockly.MenuItem');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.string');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable dropdown field.
|
||||
@@ -157,6 +151,20 @@ Blockly.FieldDropdown.fromJson = function(options) {
|
||||
return new Blockly.FieldDropdown(options['options'], undefined, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the field's value based on the given XML element. Should only be
|
||||
* called by Blockly.Xml.
|
||||
* @param {!Element} fieldElement The element containing info about the
|
||||
* field's state.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.fromXml = function(fieldElement) {
|
||||
if (this.isOptionListDynamic()) {
|
||||
this.getOptions(false);
|
||||
}
|
||||
this.setValue(fieldElement.textContent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
@@ -738,28 +746,4 @@ Blockly.FieldDropdown.validateOptions_ = function(options) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard accessibility mode is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the field handled the action, false otherwise.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.onBlocklyAction = function(action) {
|
||||
if (this.menu_) {
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.menu_.highlightPrevious();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.menu_.highlightNext();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Blockly.FieldDropdown.superClass_.onBlocklyAction.call(this, action);
|
||||
};
|
||||
|
||||
|
||||
Blockly.fieldRegistry.register('field_dropdown', Blockly.FieldDropdown);
|
||||
|
||||
@@ -18,7 +18,6 @@ goog.require('Blockly.fieldRegistry');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Size');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
goog.provide('Blockly.FieldMultilineInput');
|
||||
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.FieldTextInput');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.KeyCodes');
|
||||
goog.require('Blockly.utils.object');
|
||||
@@ -51,10 +49,33 @@ Blockly.FieldMultilineInput = function(opt_value, opt_validator, opt_config) {
|
||||
* @type {SVGGElement}
|
||||
*/
|
||||
this.textGroup_ = null;
|
||||
|
||||
/**
|
||||
* Defines the maximum number of lines of field.
|
||||
* If exceeded, scrolling functionality is enabled.
|
||||
* @type {number}
|
||||
* @protected
|
||||
*/
|
||||
this.maxLines_ = Infinity;
|
||||
|
||||
/**
|
||||
* Whether Y overflow is currently occuring.
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.isOverflowedY_ = false;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FieldMultilineInput,
|
||||
Blockly.FieldTextInput);
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.configure_ = function(config) {
|
||||
Blockly.FieldMultilineInput.superClass_.configure_.call(this, config);
|
||||
config.maxLines && this.setMaxLines(config.maxLines);
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a FieldMultilineInput from a JSON arg object,
|
||||
* dereferencing any string table references.
|
||||
@@ -121,17 +142,20 @@ Blockly.FieldMultilineInput.prototype.getDisplayText_ = function() {
|
||||
}
|
||||
var lines = textLines.split('\n');
|
||||
textLines = '';
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var displayLinesNumber = this.isOverflowedY_ ? this.maxLines_ : lines.length;
|
||||
for (var i = 0; i < displayLinesNumber; i++) {
|
||||
var text = lines[i];
|
||||
if (text.length > this.maxDisplayLength) {
|
||||
// Truncate displayed string and add an ellipsis ('...').
|
||||
text = text.substring(0, this.maxDisplayLength - 4) + '...';
|
||||
} else if (this.isOverflowedY_ && i === displayLinesNumber - 1) {
|
||||
text = text.substring(0, text.length - 3) + '...';
|
||||
}
|
||||
// Replace whitespace with non-breaking spaces so the text doesn't collapse.
|
||||
text = text.replace(/\s/g, Blockly.Field.NBSP);
|
||||
|
||||
textLines += text;
|
||||
if (i !== lines.length - 1) {
|
||||
if (i !== displayLinesNumber - 1) {
|
||||
textLines += '\n';
|
||||
}
|
||||
}
|
||||
@@ -142,6 +166,20 @@ Blockly.FieldMultilineInput.prototype.getDisplayText_ = function() {
|
||||
return textLines;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by setValue if the text input is valid. Updates the value of the
|
||||
* field, and updates the text of the field if it is not currently being
|
||||
* edited (i.e. handled by the htmlInput_). Is being redefined here to update
|
||||
* overflow state of the field.
|
||||
* @param {*} newValue The value to be saved. The default validator guarantees
|
||||
* that this is a string.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.doValueUpdate_ = function(newValue) {
|
||||
Blockly.FieldMultilineInput.superClass_.doValueUpdate_.call(this, newValue);
|
||||
this.isOverflowedY_ = this.value_.split('\n').length > this.maxLines_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the text of the textElement.
|
||||
* @protected
|
||||
@@ -170,6 +208,15 @@ Blockly.FieldMultilineInput.prototype.render_ = function() {
|
||||
y += lineHeight;
|
||||
}
|
||||
|
||||
if (this.isBeingEdited_) {
|
||||
var htmlInput = /** @type {!HTMLElement} */(this.htmlInput_);
|
||||
if (this.isOverflowedY_) {
|
||||
Blockly.utils.dom.addClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
||||
} else {
|
||||
Blockly.utils.dom.removeClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
||||
}
|
||||
}
|
||||
|
||||
this.updateSize_();
|
||||
|
||||
if (this.isBeingEdited_) {
|
||||
@@ -211,6 +258,34 @@ Blockly.FieldMultilineInput.prototype.updateSize_ = function() {
|
||||
totalHeight += this.getConstants().FIELD_TEXT_HEIGHT +
|
||||
(i > 0 ? this.getConstants().FIELD_BORDER_RECT_Y_PADDING : 0);
|
||||
}
|
||||
if (this.isBeingEdited_) {
|
||||
// The default width is based on the longest line in the display text,
|
||||
// but when it's being edited, width should be calculated based on the
|
||||
// absolute longest line, even if it would be truncated after editing.
|
||||
// Otherwise we would get wrong editor width when there are more
|
||||
// lines than this.maxLines_.
|
||||
var actualEditorLines = this.value_.split('\n');
|
||||
var dummyTextElement = Blockly.utils.dom.createSvgElement(
|
||||
Blockly.utils.Svg.TEXT,{'class': 'blocklyText blocklyMultilineText'});
|
||||
var fontSize = this.getConstants().FIELD_TEXT_FONTSIZE;
|
||||
var fontWeight = this.getConstants().FIELD_TEXT_FONTWEIGHT;
|
||||
var fontFamily = this.getConstants().FIELD_TEXT_FONTFAMILY;
|
||||
|
||||
for (var i = 0; i < actualEditorLines.length; i++) {
|
||||
if (actualEditorLines[i].length > this.maxDisplayLength) {
|
||||
actualEditorLines[i] = actualEditorLines[i].substring(0, this.maxDisplayLength);
|
||||
}
|
||||
dummyTextElement.textContent = actualEditorLines[i];
|
||||
var lineWidth = Blockly.utils.dom.getFastTextWidth(
|
||||
dummyTextElement, fontSize, fontWeight, fontFamily);
|
||||
if (lineWidth > totalWidth) {
|
||||
totalWidth = lineWidth;
|
||||
}
|
||||
}
|
||||
|
||||
var scrollbarWidth = this.htmlInput_.offsetWidth - this.htmlInput_.clientWidth;
|
||||
totalWidth += scrollbarWidth;
|
||||
}
|
||||
if (this.borderRect_) {
|
||||
totalHeight += this.getConstants().FIELD_BORDER_RECT_Y_PADDING * 2;
|
||||
totalWidth += this.getConstants().FIELD_BORDER_RECT_X_PADDING * 2;
|
||||
@@ -223,6 +298,21 @@ Blockly.FieldMultilineInput.prototype.updateSize_ = function() {
|
||||
this.positionBorderRect_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the inline free-text editor on top of the text.
|
||||
* Overrides the default behaviour to force rerender in order to
|
||||
* correct block size, based on editor text.
|
||||
* @param {Event=} _opt_e Optional mouse event that triggered the field to open,
|
||||
* or undefined if triggered programmatically.
|
||||
* @param {boolean=} opt_quietInput True if editor should be created without
|
||||
* focus. Defaults to false.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.showEditor_ = function(_opt_e, opt_quietInput) {
|
||||
Blockly.FieldMultilineInput.superClass_.showEditor_.call(this, _opt_e, opt_quietInput);
|
||||
this.forceRerender();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the text input editor widget.
|
||||
* @return {!HTMLTextAreaElement} The newly created text input editor.
|
||||
@@ -266,6 +356,26 @@ Blockly.FieldMultilineInput.prototype.widgetCreate_ = function() {
|
||||
return htmlInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the maxLines config for this field.
|
||||
* @param {number} maxLines Defines the maximum number of lines allowed,
|
||||
* before scrolling functionality is enabled.
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.setMaxLines = function(maxLines) {
|
||||
if (typeof maxLines === 'number' && maxLines > 0 && maxLines !== this.maxLines_) {
|
||||
this.maxLines_ = maxLines;
|
||||
this.forceRerender();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the maxLines config of this field.
|
||||
* @return {number} The maxLines config value.
|
||||
*/
|
||||
Blockly.FieldMultilineInput.prototype.getMaxLines = function() {
|
||||
return this.maxLines_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle key down to the editor. Override the text input definition of this
|
||||
* so as to not close the editor when enter is typed in.
|
||||
@@ -289,6 +399,9 @@ Blockly.Css.register([
|
||||
'overflow: hidden;',
|
||||
'height: 100%;',
|
||||
'text-align: left;',
|
||||
'}',
|
||||
'.blocklyHtmlTextAreaInputOverflowedY {',
|
||||
'overflow-y: scroll;',
|
||||
'}'
|
||||
/* eslint-enable indent */
|
||||
]);
|
||||
|
||||
@@ -16,6 +16,7 @@ goog.provide('Blockly.fieldRegistry');
|
||||
|
||||
goog.require('Blockly.registry');
|
||||
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IRegistrableField');
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
goog.provide('Blockly.FieldTextInput');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
@@ -23,9 +25,11 @@ goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.KeyCodes');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable text field.
|
||||
@@ -59,14 +63,14 @@ Blockly.FieldTextInput = function(opt_value, opt_validator, opt_config) {
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownWrapper_ = null;
|
||||
|
||||
/**
|
||||
* Key input event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyInputWrapper_ = null;
|
||||
@@ -199,7 +203,7 @@ Blockly.FieldTextInput.prototype.doValueInvalid_ = function(_invalidValue) {
|
||||
// Revert value when the text becomes invalid.
|
||||
this.value_ = this.htmlInput_.untypedDefaultValue_;
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
this.sourceBlock_, 'field', this.name || null, oldValue, this.value_));
|
||||
}
|
||||
}
|
||||
@@ -418,13 +422,11 @@ Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
// Trap Enter without IME and Esc to hide.
|
||||
this.onKeyDownWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'keydown', this, this.onHtmlInputKeyDown_);
|
||||
this.onKeyDownWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
htmlInput, 'keydown', this, this.onHtmlInputKeyDown_);
|
||||
// Resize after every input change.
|
||||
this.onKeyInputWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'input', this, this.onHtmlInputChange_);
|
||||
this.onKeyInputWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
htmlInput, 'input', this, this.onHtmlInputChange_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -433,11 +435,11 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() {
|
||||
if (this.onKeyDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onKeyDownWrapper_);
|
||||
this.onKeyDownWrapper_ = null;
|
||||
}
|
||||
if (this.onKeyInputWrapper_) {
|
||||
Blockly.unbindEvent_(this.onKeyInputWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onKeyInputWrapper_);
|
||||
this.onKeyInputWrapper_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
|
||||
goog.provide('Blockly.FieldVariable');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.FieldDropdown');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
@@ -25,6 +27,9 @@ goog.require('Blockly.VariableModel');
|
||||
goog.require('Blockly.Variables');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Menu');
|
||||
goog.requireType('Blockly.MenuItem');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,29 +13,36 @@
|
||||
goog.provide('Blockly.Flyout');
|
||||
|
||||
goog.require('Blockly.Block');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.blockRendering');
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.VarCreate');
|
||||
goog.require('Blockly.FlyoutCursor');
|
||||
goog.require('Blockly.FlyoutMetricsManager');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Gesture');
|
||||
goog.require('Blockly.Marker');
|
||||
goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.ScrollbarPair');
|
||||
goog.require('Blockly.Tooltip');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
goog.require('Blockly.utils.xml');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.FlyoutButton');
|
||||
goog.requireType('Blockly.IDeleteArea');
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.Options');
|
||||
goog.requireType('Blockly.utils.Rect');
|
||||
|
||||
|
||||
/**
|
||||
@@ -44,14 +51,10 @@ goog.requireType('Blockly.utils.Metrics');
|
||||
* workspace.
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
* @implements {Blockly.IDeleteArea}
|
||||
* @implements {Blockly.IFlyout}
|
||||
*/
|
||||
Blockly.Flyout = function(workspaceOptions) {
|
||||
workspaceOptions.getMetrics =
|
||||
/** @type {function():!Blockly.utils.Metrics} */ (
|
||||
this.getMetrics_.bind(this));
|
||||
workspaceOptions.setMetrics = this.setMetrics_.bind(this);
|
||||
|
||||
/**
|
||||
@@ -59,6 +62,9 @@ Blockly.Flyout = function(workspaceOptions) {
|
||||
* @protected
|
||||
*/
|
||||
this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
|
||||
this.workspace_.setMetricsManager(
|
||||
new Blockly.FlyoutMetricsManager(this.workspace_, this));
|
||||
|
||||
this.workspace_.isFlyout = true;
|
||||
// Keep the workspace visibility consistent with the flyout's visibility.
|
||||
this.workspace_.setVisible(this.isVisible_);
|
||||
@@ -253,7 +259,6 @@ Blockly.Flyout.prototype.createDom = function(tagName) {
|
||||
this.svgBackground_, 'flyoutBackgroundColour', 'fill');
|
||||
this.workspace_.getThemeManager().subscribe(
|
||||
this.svgBackground_, 'flyoutOpacity', 'fill-opacity');
|
||||
this.workspace_.getMarkerManager().setCursor(new Blockly.FlyoutCursor());
|
||||
return this.svgGroup_;
|
||||
};
|
||||
|
||||
@@ -266,25 +271,25 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
|
||||
this.targetWorkspace = targetWorkspace;
|
||||
this.workspace_.targetWorkspace = targetWorkspace;
|
||||
|
||||
/**
|
||||
* @type {!Blockly.Scrollbar}
|
||||
* @package
|
||||
*/
|
||||
this.scrollbar = new Blockly.Scrollbar(this.workspace_,
|
||||
this.horizontalLayout, false, 'blocklyFlyoutScrollbar');
|
||||
this.workspace_.scrollbar = new Blockly.ScrollbarPair(
|
||||
this.workspace_, this.horizontalLayout, !this.horizontalLayout,
|
||||
'blocklyFlyoutScrollbar');
|
||||
|
||||
this.hide();
|
||||
|
||||
Array.prototype.push.apply(this.eventWrappers_,
|
||||
Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, this.wheel_));
|
||||
Array.prototype.push.apply(
|
||||
this.eventWrappers_,
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
this.svgGroup_, 'wheel', this, this.wheel_));
|
||||
if (!this.autoClose) {
|
||||
this.filterWrapper_ = this.filterForCapacity_.bind(this);
|
||||
this.targetWorkspace.addChangeListener(this.filterWrapper_);
|
||||
}
|
||||
|
||||
// Dragging the flyout up and down.
|
||||
Array.prototype.push.apply(this.eventWrappers_,
|
||||
Blockly.bindEventWithChecks_(
|
||||
Array.prototype.push.apply(
|
||||
this.eventWrappers_,
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
this.svgBackground_, 'mousedown', this, this.onMouseDown_));
|
||||
|
||||
// A flyout connected to a workspace doesn't have its own current gesture.
|
||||
@@ -304,15 +309,11 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
|
||||
*/
|
||||
Blockly.Flyout.prototype.dispose = function() {
|
||||
this.hide();
|
||||
Blockly.unbindEvent_(this.eventWrappers_);
|
||||
Blockly.browserEvents.unbind(this.eventWrappers_);
|
||||
if (this.filterWrapper_) {
|
||||
this.targetWorkspace.removeChangeListener(this.filterWrapper_);
|
||||
this.filterWrapper_ = null;
|
||||
}
|
||||
if (this.scrollbar) {
|
||||
this.scrollbar.dispose();
|
||||
this.scrollbar = null;
|
||||
}
|
||||
if (this.workspace_) {
|
||||
this.workspace_.getThemeManager().unsubscribe(this.svgBackground_);
|
||||
this.workspace_.targetWorkspace = null;
|
||||
@@ -343,6 +344,15 @@ Blockly.Flyout.prototype.getHeight = function() {
|
||||
return this.height_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the scale (zoom level) of the flyout. By default,
|
||||
* this matches the target workspace scale, but this can be overridden.
|
||||
* @return {number} Flyout workspace scale.
|
||||
*/
|
||||
Blockly.Flyout.prototype.getFlyoutScale = function() {
|
||||
return this.targetWorkspace.scale;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the workspace inside the flyout.
|
||||
* @return {!Blockly.WorkspaceSvg} The workspace inside the flyout.
|
||||
@@ -401,7 +411,7 @@ Blockly.Flyout.prototype.updateDisplay_ = function() {
|
||||
this.svgGroup_.style.display = show ? 'block' : 'none';
|
||||
// Update the scrollbar's visibility too since it should mimic the
|
||||
// flyout's visibility.
|
||||
this.scrollbar.setContainerVisible(show);
|
||||
this.workspace_.scrollbar.setContainerVisible(show);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -415,6 +425,8 @@ Blockly.Flyout.prototype.updateDisplay_ = function() {
|
||||
Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) {
|
||||
this.svgGroup_.setAttribute("width", width);
|
||||
this.svgGroup_.setAttribute("height", height);
|
||||
this.workspace_.setCachedParentSvgSize(width, height);
|
||||
|
||||
if (this.svgGroup_.tagName == 'svg') {
|
||||
var transform = 'translate(' + x + 'px,' + y + 'px)';
|
||||
Blockly.utils.dom.setCssTransform(this.svgGroup_, transform);
|
||||
@@ -426,14 +438,22 @@ Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) {
|
||||
}
|
||||
|
||||
// Update the scrollbar (if one exists).
|
||||
if (this.scrollbar) {
|
||||
var scrollbar = this.workspace_.scrollbar;
|
||||
if (scrollbar) {
|
||||
// Set the scrollbars origin to be the top left of the flyout.
|
||||
this.scrollbar.setOrigin(x, y);
|
||||
this.scrollbar.resize();
|
||||
// Set the position again so that if the metrics were the same (and the
|
||||
// resize failed) our position is still updated.
|
||||
this.scrollbar.setPosition(
|
||||
this.scrollbar.position.x, this.scrollbar.position.y);
|
||||
scrollbar.setOrigin(x, y);
|
||||
scrollbar.resize();
|
||||
// If origin changed and metrics haven't changed enough to trigger
|
||||
// reposition in resize, we need to call setPosition. See issue #4692.
|
||||
if (scrollbar.hScroll) {
|
||||
scrollbar.hScroll.setPosition(
|
||||
scrollbar.hScroll.position.x, scrollbar.hScroll.position.y);
|
||||
}
|
||||
if (scrollbar.vScroll) {
|
||||
scrollbar.vScroll.setPosition(
|
||||
scrollbar.vScroll.position.x, scrollbar.vScroll.position.y);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -447,7 +467,7 @@ Blockly.Flyout.prototype.hide = function() {
|
||||
this.setVisible(false);
|
||||
// Delete all the event listeners.
|
||||
for (var i = 0, listen; (listen = this.listeners_[i]); i++) {
|
||||
Blockly.unbindEvent_(listen);
|
||||
Blockly.browserEvents.unbind(listen);
|
||||
}
|
||||
this.listeners_.length = 0;
|
||||
if (this.reflowWrapper_) {
|
||||
@@ -492,8 +512,8 @@ Blockly.Flyout.prototype.show = function(flyoutDef) {
|
||||
}
|
||||
};
|
||||
|
||||
this.listeners_.push(Blockly.bindEventWithChecks_(this.svgBackground_,
|
||||
'mouseover', this, deselectAll));
|
||||
this.listeners_.push(Blockly.browserEvents.conditionalBind(
|
||||
this.svgBackground_, 'mouseover', this, deselectAll));
|
||||
|
||||
if (this.horizontalLayout) {
|
||||
this.height_ = 0;
|
||||
@@ -722,18 +742,18 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) {
|
||||
this.listeners_.push(Blockly.bindEventWithChecks_(root, 'mousedown', null,
|
||||
this.blockMouseDown_(block)));
|
||||
this.listeners_.push(Blockly.bindEventWithChecks_(rect, 'mousedown', null,
|
||||
this.blockMouseDown_(block)));
|
||||
this.listeners_.push(Blockly.bindEvent_(root, 'mouseenter', block,
|
||||
block.addSelect));
|
||||
this.listeners_.push(Blockly.bindEvent_(root, 'mouseleave', block,
|
||||
block.removeSelect));
|
||||
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseenter', block,
|
||||
block.addSelect));
|
||||
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseleave', block,
|
||||
block.removeSelect));
|
||||
this.listeners_.push(Blockly.browserEvents.conditionalBind(
|
||||
root, 'mousedown', null, this.blockMouseDown_(block)));
|
||||
this.listeners_.push(Blockly.browserEvents.conditionalBind(
|
||||
rect, 'mousedown', null, this.blockMouseDown_(block)));
|
||||
this.listeners_.push(
|
||||
Blockly.browserEvents.bind(root, 'mouseenter', block, block.addSelect));
|
||||
this.listeners_.push(Blockly.browserEvents.bind(
|
||||
root, 'mouseleave', block, block.removeSelect));
|
||||
this.listeners_.push(
|
||||
Blockly.browserEvents.bind(rect, 'mouseenter', block, block.addSelect));
|
||||
this.listeners_.push(Blockly.browserEvents.bind(
|
||||
rect, 'mouseleave', block, block.removeSelect));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -806,12 +826,14 @@ Blockly.Flyout.prototype.createBlock = function(originalBlock) {
|
||||
// Fire a VarCreate event for each (if any) new variable created.
|
||||
for (var i = 0; i < newVariables.length; i++) {
|
||||
var thisVariable = newVariables[i];
|
||||
Blockly.Events.fire(new Blockly.Events.VarCreate(thisVariable));
|
||||
Blockly.Events.fire(
|
||||
new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(thisVariable));
|
||||
}
|
||||
|
||||
// Block events come after var events, in case they refer to newly created
|
||||
// variables.
|
||||
Blockly.Events.fire(new Blockly.Events.Create(newBlock));
|
||||
Blockly.Events.fire(
|
||||
new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(newBlock));
|
||||
}
|
||||
if (this.autoClose) {
|
||||
this.hide();
|
||||
@@ -835,9 +857,8 @@ Blockly.Flyout.prototype.initFlyoutButton_ = function(button, x, y) {
|
||||
button.show();
|
||||
// Clicking on a flyout button or label is a lot like clicking on the
|
||||
// flyout background.
|
||||
this.listeners_.push(
|
||||
Blockly.bindEventWithChecks_(
|
||||
buttonSvg, 'mousedown', this, this.onMouseDown_));
|
||||
this.listeners_.push(Blockly.browserEvents.conditionalBind(
|
||||
buttonSvg, 'mousedown', this, this.onMouseDown_));
|
||||
|
||||
this.buttons_.push(button);
|
||||
};
|
||||
@@ -933,7 +954,8 @@ Blockly.Flyout.prototype.reflow = function() {
|
||||
* @package
|
||||
*/
|
||||
Blockly.Flyout.prototype.isScrollable = function() {
|
||||
return this.scrollbar ? this.scrollbar.isVisible() : false;
|
||||
return this.workspace_.scrollbar ?
|
||||
this.workspace_.scrollbar.isVisible() : false;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -995,18 +1017,6 @@ Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
|
||||
return block;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard accessibility mode is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the flyout handled the action, false otherwise.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Flyout.prototype.onBlocklyAction = function(action) {
|
||||
var cursor = this.workspace_.getCursor();
|
||||
return cursor.onBlocklyAction(action);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the deletion rectangle for this flyout in viewport coordinates.
|
||||
* @return {Blockly.utils.Rect} Rectangle in which to delete.
|
||||
@@ -1030,15 +1040,6 @@ Blockly.Flyout.prototype.position;
|
||||
*/
|
||||
Blockly.Flyout.prototype.isDragTowardWorkspace;
|
||||
|
||||
/**
|
||||
* Return an object with all the metrics required to size scrollbars for the
|
||||
* flyout.
|
||||
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
|
||||
* flyout.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Flyout.prototype.getMetrics_;
|
||||
|
||||
/**
|
||||
* Sets the translation of the flyout to match the scrollbars.
|
||||
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
|
||||
|
||||
@@ -12,12 +12,16 @@
|
||||
|
||||
goog.provide('Blockly.FlyoutButton');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.utils.toolbox');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a button in the flyout.
|
||||
@@ -82,7 +86,7 @@ Blockly.FlyoutButton = function(workspace, targetWorkspace, json, isLabel) {
|
||||
|
||||
/**
|
||||
* Mouse up event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onMouseUpWrapper_ = null;
|
||||
@@ -195,7 +199,7 @@ Blockly.FlyoutButton.prototype.createDom = function() {
|
||||
|
||||
this.updateTransform_();
|
||||
|
||||
this.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMouseUpWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
this.svgGroup_, 'mouseup', this, this.onMouseUp_);
|
||||
return this.svgGroup_;
|
||||
};
|
||||
@@ -265,7 +269,7 @@ Blockly.FlyoutButton.prototype.getTargetWorkspace = function() {
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.dispose = function() {
|
||||
if (this.onMouseUpWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMouseUpWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMouseUpWrapper_);
|
||||
}
|
||||
if (this.svgGroup_) {
|
||||
Blockly.utils.dom.removeNode(this.svgGroup_);
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Methods for dragging a flyout visually.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.FlyoutDragger');
|
||||
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.WorkspaceDragger');
|
||||
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a flyout dragger. It moves a flyout workspace around when it is
|
||||
* being dragged by a mouse or touch.
|
||||
* Note that the workspace itself manages whether or not it has a drag surface
|
||||
* and how to do translations based on that. This simply passes the right
|
||||
* commands based on events.
|
||||
* @param {!Blockly.IFlyout} flyout The flyout to drag.
|
||||
* @extends {Blockly.WorkspaceDragger}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FlyoutDragger = function(flyout) {
|
||||
Blockly.FlyoutDragger.superClass_.constructor.call(this,
|
||||
flyout.getWorkspace());
|
||||
|
||||
/**
|
||||
* The scrollbar to update to move the flyout.
|
||||
* Unlike the main workspace, the flyout has only one scrollbar, in either the
|
||||
* horizontal or the vertical direction.
|
||||
* @type {!Blockly.Scrollbar}
|
||||
* @private
|
||||
*/
|
||||
this.scrollbar_ = flyout.scrollbar;
|
||||
|
||||
/**
|
||||
* Whether the flyout scrolls horizontally. If false, the flyout scrolls
|
||||
* vertically.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.horizontalLayout_ = flyout.horizontalLayout;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FlyoutDragger, Blockly.WorkspaceDragger);
|
||||
|
||||
/**
|
||||
* Move the flyout based on the most recent mouse movements.
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at the start of the drag, in pixel coordinates.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FlyoutDragger.prototype.drag = function(currentDragDeltaXY) {
|
||||
// startScrollXY_ is assigned by the superclass.
|
||||
var newXY = Blockly.utils.Coordinate.sum(this.startScrollXY_,
|
||||
currentDragDeltaXY);
|
||||
|
||||
// We can't call workspace.scroll because the flyout's workspace doesn't own
|
||||
// it's own scrollbars. This is because (as of 2.20190722.1) the
|
||||
// workspace's scrollbar property must be a scrollbar pair, rather than a
|
||||
// single scrollbar.
|
||||
// Instead we'll just expect setting the scrollbar to update the scroll of
|
||||
// the workspace as well.
|
||||
if (this.horizontalLayout_) {
|
||||
this.scrollbar_.set(-newXY.x);
|
||||
} else {
|
||||
this.scrollbar_.set(-newXY.y);
|
||||
}
|
||||
};
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
goog.provide('Blockly.HorizontalFlyout');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Block');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Flyout');
|
||||
goog.require('Blockly.registry');
|
||||
@@ -20,9 +22,11 @@ goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
goog.require('Blockly.WidgetDiv');
|
||||
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.Options');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,64 +42,6 @@ Blockly.HorizontalFlyout = function(workspaceOptions) {
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.HorizontalFlyout, Blockly.Flyout);
|
||||
|
||||
/**
|
||||
* Return an object with all the metrics required to size scrollbars for the
|
||||
* flyout. 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 contents,
|
||||
* .viewTop: Offset of top edge of visible rectangle from parent,
|
||||
* .contentTop: Offset of the top-most content from the y=0 coordinate,
|
||||
* .absoluteTop: Top-edge of view.
|
||||
* .viewLeft: Offset of the left edge of visible rectangle from parent,
|
||||
* .contentLeft: Offset of the left-most content from the x=0 coordinate,
|
||||
* .absoluteLeft: Left-edge of view.
|
||||
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
|
||||
* flyout.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
|
||||
if (!this.isVisible()) {
|
||||
// Flyout is hidden.
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var optionBox = this.workspace_.getCanvas().getBBox();
|
||||
} catch (e) {
|
||||
// Firefox has trouble with hidden elements (Bug 528969).
|
||||
var optionBox = {height: 0, y: 0, width: 0, x: 0};
|
||||
}
|
||||
|
||||
var absoluteTop = this.SCROLLBAR_PADDING;
|
||||
var absoluteLeft = this.SCROLLBAR_PADDING;
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) {
|
||||
absoluteTop = 0;
|
||||
}
|
||||
var viewHeight = this.height_;
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
viewHeight -= this.SCROLLBAR_PADDING;
|
||||
}
|
||||
var viewWidth = this.width_ - 2 * this.SCROLLBAR_PADDING;
|
||||
|
||||
var metrics = {
|
||||
contentHeight: (optionBox.height + 2 * this.MARGIN) * this.workspace_.scale,
|
||||
contentWidth: (optionBox.width + 2 * this.MARGIN) * this.workspace_.scale,
|
||||
contentTop: 0,
|
||||
contentLeft: 0,
|
||||
|
||||
viewHeight: viewHeight,
|
||||
viewWidth: viewWidth,
|
||||
viewTop: -this.workspace_.scrollY,
|
||||
viewLeft: -this.workspace_.scrollX,
|
||||
|
||||
absoluteTop: absoluteTop,
|
||||
absoluteLeft: absoluteLeft
|
||||
};
|
||||
return metrics;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the translation of the flyout to match the scrollbars.
|
||||
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
|
||||
@@ -104,18 +50,23 @@ Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
||||
var metrics = this.getMetrics_();
|
||||
// This is a fix to an apparent race condition.
|
||||
if (!metrics) {
|
||||
if (!this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var metricsManager = this.workspace_.getMetricsManager();
|
||||
var scrollMetrics = metricsManager.getScrollMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
||||
|
||||
if (typeof xyRatio.x == 'number') {
|
||||
this.workspace_.scrollX = -metrics.contentWidth * xyRatio.x;
|
||||
this.workspace_.scrollX =
|
||||
-(scrollMetrics.left +
|
||||
(scrollMetrics.width - viewMetrics.width) * xyRatio.x);
|
||||
}
|
||||
|
||||
this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft,
|
||||
this.workspace_.scrollY + metrics.absoluteTop);
|
||||
this.workspace_.translate(this.workspace_.scrollX + absoluteMetrics.left,
|
||||
this.workspace_.scrollY + absoluteMetrics.top);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -132,42 +83,44 @@ Blockly.HorizontalFlyout.prototype.getX = function() {
|
||||
* @return {number} Y coordinate.
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.getY = function() {
|
||||
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
|
||||
if (!targetWorkspaceMetrics) {
|
||||
// Hidden components will return null.
|
||||
if (!this.isVisible()) {
|
||||
return 0;
|
||||
}
|
||||
var metricsManager = this.targetWorkspace.getMetricsManager();
|
||||
var absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var toolboxMetrics = metricsManager.getToolboxMetrics();
|
||||
|
||||
var y = 0;
|
||||
var atTop = this.toolboxPosition_ == Blockly.utils.toolbox.Position.TOP;
|
||||
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a category toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxHeight) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
y = targetWorkspaceMetrics.toolboxHeight;
|
||||
if (this.targetWorkspace.getToolbox()) {
|
||||
if (atTop) {
|
||||
y = toolboxMetrics.height;
|
||||
} else {
|
||||
y = targetWorkspaceMetrics.viewHeight - this.height_;
|
||||
y = viewMetrics.height - this.height_;
|
||||
}
|
||||
// Simple (flyout-only) toolbox.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
if (atTop) {
|
||||
y = 0;
|
||||
} else {
|
||||
// The simple flyout does not cover the workspace.
|
||||
y = targetWorkspaceMetrics.viewHeight;
|
||||
y = viewMetrics.height;
|
||||
}
|
||||
}
|
||||
// Trashcan flyout is opposite the main flyout.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
if (atTop) {
|
||||
y = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the top, but we want
|
||||
// to align the bottom edge of the flyout with the bottom edge of the
|
||||
// blocklyDiv, we calculate the full height of the div minus the height
|
||||
// of the flyout.
|
||||
y = targetWorkspaceMetrics.viewHeight +
|
||||
targetWorkspaceMetrics.absoluteTop - this.height_;
|
||||
y = viewMetrics.height + absoluteMetrics.top - this.height_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,24 +131,22 @@ 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 workspace metrics.
|
||||
this.width_ = targetWorkspaceViewMetrics.width;
|
||||
|
||||
var edgeWidth = targetWorkspaceViewMetrics.width - 2 * this.CORNER_RADIUS;
|
||||
var edgeHeight = this.height_ - this.CORNER_RADIUS;
|
||||
this.setBackgroundPath_(edgeWidth, edgeHeight);
|
||||
|
||||
var x = this.getX();
|
||||
var y = this.getY();
|
||||
|
||||
|
||||
this.positionAt_(this.width_, this.height_, x, y);
|
||||
};
|
||||
|
||||
@@ -207,9 +158,9 @@ Blockly.HorizontalFlyout.prototype.position = function() {
|
||||
* rounded corners.
|
||||
* @private
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(width,
|
||||
height) {
|
||||
var atTop = this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP;
|
||||
Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(
|
||||
width, height) {
|
||||
var atTop = this.toolboxPosition_ == Blockly.utils.toolbox.Position.TOP;
|
||||
// Start at top left.
|
||||
var path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)];
|
||||
|
||||
@@ -247,7 +198,7 @@ Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(width,
|
||||
* Scroll the flyout to the top.
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.scrollToStart = function() {
|
||||
this.scrollbar.set(this.RTL ? Infinity : 0);
|
||||
this.workspace_.scrollbar.setX(this.RTL ? Infinity : 0);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -260,12 +211,12 @@ Blockly.HorizontalFlyout.prototype.wheel_ = function(e) {
|
||||
var delta = scrollDelta.x || scrollDelta.y;
|
||||
|
||||
if (delta) {
|
||||
var metrics = this.getMetrics_();
|
||||
var pos = metrics.viewLeft + delta;
|
||||
var limit = metrics.contentWidth - metrics.viewWidth;
|
||||
pos = Math.min(pos, limit);
|
||||
pos = Math.max(pos, 0);
|
||||
this.scrollbar.set(pos);
|
||||
var metricsManager = this.workspace_.getMetricsManager();
|
||||
var scrollMetrics = metricsManager.getScrollMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
|
||||
var pos = (viewMetrics.left - scrollMetrics.left) + delta;
|
||||
this.workspace_.scrollbar.setX(pos);
|
||||
// When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv.
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
@@ -367,7 +318,7 @@ Blockly.HorizontalFlyout.prototype.getClientRect = function() {
|
||||
var BIG_NUM = 1000000000;
|
||||
var top = flyoutRect.top;
|
||||
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
if (this.toolboxPosition_ == Blockly.utils.toolbox.Position.TOP) {
|
||||
var height = flyoutRect.height;
|
||||
return new Blockly.utils.Rect(-BIG_NUM, top + height, -BIG_NUM, BIG_NUM);
|
||||
} else { // Bottom.
|
||||
@@ -381,7 +332,7 @@ Blockly.HorizontalFlyout.prototype.getClientRect = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.workspace_.scale = this.targetWorkspace.scale;
|
||||
this.workspace_.scale = this.getFlyoutScale();
|
||||
var flyoutHeight = 0;
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; (block = blocks[i]); i++) {
|
||||
@@ -399,7 +350,7 @@ Blockly.HorizontalFlyout.prototype.reflowInternal_ = function() {
|
||||
}
|
||||
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_ &&
|
||||
this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP &&
|
||||
this.toolboxPosition_ == Blockly.utils.toolbox.Position.TOP &&
|
||||
!this.targetWorkspace.getToolbox()) {
|
||||
// This flyout is a simple toolbox. Reposition the workspace so that (0,0)
|
||||
// is in the correct position relative to the new absolute edge (ie
|
||||
@@ -408,7 +359,7 @@ Blockly.HorizontalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.targetWorkspace.scrollX, this.targetWorkspace.scrollY + flyoutHeight);
|
||||
}
|
||||
|
||||
// Record the height for .getMetrics_ and .position.
|
||||
// Record the height for workspace metrics and .position.
|
||||
this.height_ = flyoutHeight;
|
||||
this.position();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
goog.provide('Blockly.VerticalFlyout');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Block');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Flyout');
|
||||
goog.require('Blockly.registry');
|
||||
@@ -20,10 +22,11 @@ goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
goog.require('Blockly.WidgetDiv');
|
||||
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.Options');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
@@ -44,63 +47,6 @@ Blockly.utils.object.inherits(Blockly.VerticalFlyout, Blockly.Flyout);
|
||||
*/
|
||||
Blockly.VerticalFlyout.registryName = 'verticalFlyout';
|
||||
|
||||
/**
|
||||
* Return an object with all the metrics required to size scrollbars for the
|
||||
* flyout. 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 contents,
|
||||
* .viewTop: Offset of top edge of visible rectangle from parent,
|
||||
* .contentTop: Offset of the top-most content from the y=0 coordinate,
|
||||
* .absoluteTop: Top-edge of view.
|
||||
* .viewLeft: Offset of the left edge of visible rectangle from parent,
|
||||
* .contentLeft: Offset of the left-most content from the x=0 coordinate,
|
||||
* .absoluteLeft: Left-edge of view.
|
||||
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
|
||||
* flyout.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
|
||||
if (!this.isVisible()) {
|
||||
// Flyout is hidden.
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var optionBox = this.workspace_.getCanvas().getBBox();
|
||||
} catch (e) {
|
||||
// Firefox has trouble with hidden elements (Bug 528969).
|
||||
var optionBox = {height: 0, y: 0, width: 0, x: 0};
|
||||
}
|
||||
|
||||
// Padding for the end of the scrollbar.
|
||||
var absoluteTop = this.SCROLLBAR_PADDING;
|
||||
var absoluteLeft = 0;
|
||||
|
||||
var viewHeight = this.height_ - 2 * this.SCROLLBAR_PADDING;
|
||||
var viewWidth = this.width_;
|
||||
if (!this.RTL) {
|
||||
viewWidth -= this.SCROLLBAR_PADDING;
|
||||
}
|
||||
|
||||
var metrics = {
|
||||
contentHeight: optionBox.height * this.workspace_.scale + 2 * this.MARGIN,
|
||||
contentWidth: optionBox.width * this.workspace_.scale + 2 * this.MARGIN,
|
||||
contentTop: optionBox.y,
|
||||
contentLeft: optionBox.x,
|
||||
|
||||
viewHeight: viewHeight,
|
||||
viewWidth: viewWidth,
|
||||
viewTop: -this.workspace_.scrollY + optionBox.y,
|
||||
viewLeft: -this.workspace_.scrollX,
|
||||
|
||||
absoluteTop: absoluteTop,
|
||||
absoluteLeft: absoluteLeft
|
||||
};
|
||||
return metrics;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the translation of the flyout to match the scrollbars.
|
||||
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
|
||||
@@ -109,16 +55,21 @@ Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
||||
var metrics = this.getMetrics_();
|
||||
// This is a fix to an apparent race condition.
|
||||
if (!metrics) {
|
||||
if (!this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
var metricsManager = this.workspace_.getMetricsManager();
|
||||
var scrollMetrics = metricsManager.getScrollMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
||||
|
||||
if (typeof xyRatio.y == 'number') {
|
||||
this.workspace_.scrollY = -metrics.contentHeight * xyRatio.y;
|
||||
this.workspace_.scrollY =
|
||||
-(scrollMetrics.top +
|
||||
(scrollMetrics.height - viewMetrics.height) * xyRatio.y);
|
||||
}
|
||||
this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft,
|
||||
this.workspace_.scrollY + metrics.absoluteTop);
|
||||
this.workspace_.translate(this.workspace_.scrollX + absoluteMetrics.left,
|
||||
this.workspace_.scrollY + absoluteMetrics.top);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -126,43 +77,43 @@ Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
||||
* @return {number} X coordinate.
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.getX = function() {
|
||||
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
|
||||
if (!targetWorkspaceMetrics) {
|
||||
// Hidden components will return null.
|
||||
if (!this.isVisible()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var metricsManager = this.targetWorkspace.getMetricsManager();
|
||||
var absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var toolboxMetrics = metricsManager.getToolboxMetrics();
|
||||
var x = 0;
|
||||
|
||||
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
|
||||
// If there is a category toolbox.
|
||||
if (targetWorkspaceMetrics.toolboxWidth) {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
x = targetWorkspaceMetrics.toolboxWidth;
|
||||
if (this.targetWorkspace.getToolbox()) {
|
||||
if (this.toolboxPosition_ == Blockly.utils.toolbox.Position.LEFT) {
|
||||
x = toolboxMetrics.width;
|
||||
} else {
|
||||
x = targetWorkspaceMetrics.viewWidth - this.width_;
|
||||
x = viewMetrics.width - this.width_;
|
||||
}
|
||||
// Simple (flyout-only) toolbox.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
if (this.toolboxPosition_ == Blockly.utils.toolbox.Position.LEFT) {
|
||||
x = 0;
|
||||
} else {
|
||||
// The simple flyout does not cover the workspace.
|
||||
x = targetWorkspaceMetrics.viewWidth;
|
||||
x = viewMetrics.width;
|
||||
}
|
||||
}
|
||||
// Trashcan flyout is opposite the main flyout.
|
||||
} else {
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
if (this.toolboxPosition_ == Blockly.utils.toolbox.Position.LEFT) {
|
||||
x = 0;
|
||||
} else {
|
||||
// Because the anchor point of the flyout is on the left, but we want
|
||||
// to align the right edge of the flyout with the right edge of the
|
||||
// blocklyDiv, we calculate the full width of the div minus the width
|
||||
// of the flyout.
|
||||
x = targetWorkspaceMetrics.viewWidth +
|
||||
targetWorkspaceMetrics.absoluteLeft - this.width_;
|
||||
x = viewMetrics.width + absoluteMetrics.left - this.width_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,24 +133,22 @@ Blockly.VerticalFlyout.prototype.getY = function() {
|
||||
* Move the flyout to the edge of the workspace.
|
||||
*/
|
||||
Blockly.VerticalFlyout.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 height for Blockly.Flyout.getMetrics_
|
||||
this.height_ = targetWorkspaceMetrics.viewHeight;
|
||||
var metricsManager = this.targetWorkspace.getMetricsManager();
|
||||
var targetWorkspaceViewMetrics = metricsManager.getViewMetrics();
|
||||
|
||||
// Record the height for workspace metrics.
|
||||
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();
|
||||
var y = this.getY();
|
||||
|
||||
|
||||
this.positionAt_(this.width_, this.height_, x, y);
|
||||
};
|
||||
|
||||
@@ -212,7 +161,7 @@ Blockly.VerticalFlyout.prototype.position = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
|
||||
var atRight = this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT;
|
||||
var atRight = this.toolboxPosition_ == Blockly.utils.toolbox.Position.RIGHT;
|
||||
var totalWidth = width + this.CORNER_RADIUS;
|
||||
|
||||
// Decide whether to start on the left or right.
|
||||
@@ -241,7 +190,7 @@ Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
|
||||
* Scroll the flyout to the top.
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.scrollToStart = function() {
|
||||
this.scrollbar.set(0);
|
||||
this.workspace_.scrollbar.setY(0);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -253,12 +202,12 @@ Blockly.VerticalFlyout.prototype.wheel_ = function(e) {
|
||||
var scrollDelta = Blockly.utils.getScrollDeltaPixels(e);
|
||||
|
||||
if (scrollDelta.y) {
|
||||
var metrics = this.getMetrics_();
|
||||
var pos = (metrics.viewTop - metrics.contentTop) + scrollDelta.y;
|
||||
var limit = metrics.contentHeight - metrics.viewHeight;
|
||||
pos = Math.min(pos, limit);
|
||||
pos = Math.max(pos, 0);
|
||||
this.scrollbar.set(pos);
|
||||
var metricsManager = this.workspace_.getMetricsManager();
|
||||
var scrollMetrics = metricsManager.getScrollMetrics();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var pos = (viewMetrics.top - scrollMetrics.top) + scrollDelta.y;
|
||||
|
||||
this.workspace_.scrollbar.setY(pos);
|
||||
// When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv.
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
@@ -352,7 +301,7 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
var BIG_NUM = 1000000000;
|
||||
var left = flyoutRect.left;
|
||||
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
if (this.toolboxPosition_ == Blockly.utils.toolbox.Position.LEFT) {
|
||||
var width = flyoutRect.width;
|
||||
return new Blockly.utils.Rect(-BIG_NUM, BIG_NUM, -BIG_NUM, left + width);
|
||||
} else { // Right
|
||||
@@ -366,7 +315,7 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.workspace_.scale = this.targetWorkspace.scale;
|
||||
this.workspace_.scale = this.getFlyoutScale();
|
||||
var flyoutWidth = 0;
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; (block = blocks[i]); i++) {
|
||||
@@ -409,7 +358,7 @@ Blockly.VerticalFlyout.prototype.reflowInternal_ = function() {
|
||||
}
|
||||
|
||||
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_ &&
|
||||
this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT &&
|
||||
this.toolboxPosition_ == Blockly.utils.toolbox.Position.LEFT &&
|
||||
!this.targetWorkspace.getToolbox()) {
|
||||
// This flyout is a simple toolbox. Reposition the workspace so that (0,0)
|
||||
// is in the correct position relative to the new absolute edge (ie
|
||||
@@ -418,7 +367,7 @@ Blockly.VerticalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.targetWorkspace.scrollX + flyoutWidth, this.targetWorkspace.scrollY);
|
||||
}
|
||||
|
||||
// Record the width for .getMetrics_ and .position.
|
||||
// Record the width for workspace metrics and .position.
|
||||
this.width_ = flyoutWidth;
|
||||
this.position();
|
||||
}
|
||||
|
||||
@@ -13,8 +13,12 @@
|
||||
|
||||
goog.provide('Blockly.Generator');
|
||||
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Block');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
|
||||
goog.requireType('Blockly.Names');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,23 +13,26 @@
|
||||
|
||||
goog.provide('Blockly.Gesture');
|
||||
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.BlockDragger');
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.BubbleDragger');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.Click');
|
||||
goog.require('Blockly.FlyoutDragger');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.WorkspaceDragger');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IBubble');
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
@@ -155,7 +158,7 @@ Blockly.Gesture = function(e, creatorWorkspace) {
|
||||
/**
|
||||
* A handle to use to unbind a mouse move listener at the end of a drag.
|
||||
* Opaque data returned from Blockly.bindEventWithChecks_.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @protected
|
||||
*/
|
||||
this.onMoveWrapper_ = null;
|
||||
@@ -163,7 +166,7 @@ Blockly.Gesture = function(e, creatorWorkspace) {
|
||||
/**
|
||||
* A handle to use to unbind a mouse up listener at the end of a drag.
|
||||
* Opaque data returned from Blockly.bindEventWithChecks_.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @protected
|
||||
*/
|
||||
this.onUpWrapper_ = null;
|
||||
@@ -238,10 +241,10 @@ Blockly.Gesture.prototype.dispose = function() {
|
||||
this.creatorWorkspace_.clearGesture();
|
||||
|
||||
if (this.onMoveWrapper_) {
|
||||
Blockly.unbindEvent_(this.onMoveWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onMoveWrapper_);
|
||||
}
|
||||
if (this.onUpWrapper_) {
|
||||
Blockly.unbindEvent_(this.onUpWrapper_);
|
||||
Blockly.browserEvents.unbind(this.onUpWrapper_);
|
||||
}
|
||||
|
||||
if (this.blockDragger_) {
|
||||
@@ -384,7 +387,7 @@ Blockly.Gesture.prototype.updateIsDraggingBlock_ = function() {
|
||||
* This function should be called on a mouse/touch move event the first time the
|
||||
* drag radius is exceeded. It should be called no more than once per gesture.
|
||||
* If a workspace is being dragged this function creates the necessary
|
||||
* WorkspaceDragger or FlyoutDragger and starts the drag.
|
||||
* WorkspaceDragger and starts the drag.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.updateIsDraggingWorkspace_ = function() {
|
||||
@@ -396,12 +399,8 @@ Blockly.Gesture.prototype.updateIsDraggingWorkspace_ = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.flyout_) {
|
||||
this.workspaceDragger_ = new Blockly.FlyoutDragger(this.flyout_);
|
||||
} else {
|
||||
this.workspaceDragger_ = new Blockly.WorkspaceDragger(
|
||||
/** @type {!Blockly.WorkspaceSvg} */ (this.startWorkspace_));
|
||||
}
|
||||
this.workspaceDragger_ = new Blockly.WorkspaceDragger(
|
||||
/** @type {!Blockly.WorkspaceSvg} */ (this.startWorkspace_));
|
||||
|
||||
this.isDraggingWorkspace_ = true;
|
||||
this.workspaceDragger_.startDrag();
|
||||
@@ -488,13 +487,7 @@ Blockly.Gesture.prototype.doStart = function(e) {
|
||||
Blockly.Tooltip.block();
|
||||
|
||||
if (this.targetBlock_) {
|
||||
if (!this.targetBlock_.isInFlyout && e.shiftKey &&
|
||||
this.targetBlock_.workspace.keyboardAccessibilityMode) {
|
||||
this.creatorWorkspace_.getCursor().setCurNode(
|
||||
Blockly.ASTNode.createTopNode(this.targetBlock_));
|
||||
} else {
|
||||
this.targetBlock_.select();
|
||||
}
|
||||
this.targetBlock_.select();
|
||||
}
|
||||
|
||||
if (Blockly.utils.isRightButton(e)) {
|
||||
@@ -520,9 +513,9 @@ Blockly.Gesture.prototype.doStart = function(e) {
|
||||
* @package
|
||||
*/
|
||||
Blockly.Gesture.prototype.bindMouseEvents = function(e) {
|
||||
this.onMoveWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onMoveWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
document, 'mousemove', null, this.handleMove.bind(this));
|
||||
this.onUpWrapper_ = Blockly.bindEventWithChecks_(
|
||||
this.onUpWrapper_ = Blockly.browserEvents.conditionalBind(
|
||||
document, 'mouseup', null, this.handleUp.bind(this));
|
||||
|
||||
e.preventDefault();
|
||||
@@ -654,9 +647,6 @@ Blockly.Gesture.prototype.handleWsStart = function(e, ws) {
|
||||
this.setStartWorkspace_(ws);
|
||||
this.mostRecentEvent_ = e;
|
||||
this.doStart(e);
|
||||
if (this.startWorkspace_.keyboardAccessibilityMode) {
|
||||
Blockly.navigation.setState(Blockly.navigation.STATE_WS);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -665,8 +655,8 @@ Blockly.Gesture.prototype.handleWsStart = function(e, ws) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.fireWorkspaceClick_ = function(ws) {
|
||||
var clickEvent = new Blockly.Events.Click(null, ws.id, 'workspace');
|
||||
Blockly.Events.fire(clickEvent);
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.CLICK))(
|
||||
null, ws.id, 'workspace'));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -756,7 +746,7 @@ Blockly.Gesture.prototype.doBlockClick_ = function() {
|
||||
}
|
||||
} else {
|
||||
// Clicks events are on the start block, even if it was a shadow.
|
||||
var event = new Blockly.Events.Click(
|
||||
var event = new (Blockly.Events.get(Blockly.Events.CLICK))(
|
||||
this.startBlock_, this.startWorkspace_.id, 'block');
|
||||
Blockly.Events.fire(event);
|
||||
}
|
||||
@@ -767,17 +757,12 @@ Blockly.Gesture.prototype.doBlockClick_ = function() {
|
||||
/**
|
||||
* Execute a workspace click. When in accessibility mode shift clicking will
|
||||
* move the cursor.
|
||||
* @param {!Event} e A mouse up or touch end event.
|
||||
* @param {!Event} _e A mouse up or touch end event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.doWorkspaceClick_ = function(e) {
|
||||
Blockly.Gesture.prototype.doWorkspaceClick_ = function(_e) {
|
||||
var ws = this.creatorWorkspace_;
|
||||
if (e.shiftKey && ws.keyboardAccessibilityMode) {
|
||||
var screenCoord = new Blockly.utils.Coordinate(e.clientX, e.clientY);
|
||||
var wsCoord = Blockly.utils.screenToWsCoordinates(ws, screenCoord);
|
||||
var wsNode = Blockly.ASTNode.createWorkspaceNode(ws, wsCoord);
|
||||
ws.getCursor().setCurNode(wsNode);
|
||||
} else if (Blockly.selected) {
|
||||
if (Blockly.selected) {
|
||||
Blockly.selected.unselect();
|
||||
}
|
||||
this.fireWorkspaceClick_(this.startWorkspace_ || ws);
|
||||
|
||||
@@ -12,12 +12,16 @@
|
||||
|
||||
goog.provide('Blockly.Icon');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Bubble');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an icon.
|
||||
@@ -87,7 +91,7 @@ Blockly.Icon.prototype.createIcon = function() {
|
||||
this.drawIcon_(this.iconGroup_);
|
||||
|
||||
this.block_.getSvgRoot().appendChild(this.iconGroup_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
this.iconGroup_, 'mouseup', this, this.iconClick_);
|
||||
this.updateEditable();
|
||||
};
|
||||
|
||||
331
core/inject.js
331
core/inject.js
@@ -13,6 +13,7 @@
|
||||
goog.provide('Blockly.inject');
|
||||
|
||||
goog.require('Blockly.BlockDragSurfaceSvg');
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.Css');
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.Events');
|
||||
@@ -22,13 +23,14 @@ goog.require('Blockly.Options');
|
||||
goog.require('Blockly.ScrollbarPair');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.WorkspaceDragSurfaceSvg');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
@@ -178,147 +180,7 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
|
||||
// A null translation will also apply the correct initial scale.
|
||||
mainWorkspace.translate(0, 0);
|
||||
|
||||
if (!wsOptions.readOnly && !mainWorkspace.isMovable()) {
|
||||
// Helper function for the workspaceChanged callback.
|
||||
// TODO (#2300): Move metrics math back to the WorkspaceSvg.
|
||||
var getWorkspaceMetrics = function() {
|
||||
var workspaceMetrics = Object.create(null);
|
||||
var defaultMetrics = mainWorkspace.getMetrics();
|
||||
var scale = mainWorkspace.scale;
|
||||
|
||||
workspaceMetrics.RTL = mainWorkspace.RTL;
|
||||
|
||||
// Get the view metrics in workspace units.
|
||||
workspaceMetrics.viewLeft = defaultMetrics.viewLeft / scale;
|
||||
workspaceMetrics.viewTop = defaultMetrics.viewTop / scale;
|
||||
workspaceMetrics.viewRight =
|
||||
(defaultMetrics.viewLeft + defaultMetrics.viewWidth) / scale;
|
||||
workspaceMetrics.viewBottom =
|
||||
(defaultMetrics.viewTop + defaultMetrics.viewHeight) / scale;
|
||||
|
||||
// Get the exact content metrics (in workspace units), even if the
|
||||
// content is bounded.
|
||||
if (mainWorkspace.isContentBounded()) {
|
||||
// Already in workspace units, no need to divide by scale.
|
||||
var blocksBoundingBox = mainWorkspace.getBlocksBoundingBox();
|
||||
workspaceMetrics.contentLeft = blocksBoundingBox.left;
|
||||
workspaceMetrics.contentTop = blocksBoundingBox.top;
|
||||
workspaceMetrics.contentRight = blocksBoundingBox.right;
|
||||
workspaceMetrics.contentBottom = blocksBoundingBox.bottom;
|
||||
} else {
|
||||
workspaceMetrics.contentLeft = defaultMetrics.contentLeft / scale;
|
||||
workspaceMetrics.contentTop = defaultMetrics.contentTop / scale;
|
||||
workspaceMetrics.contentRight =
|
||||
(defaultMetrics.contentLeft + defaultMetrics.contentWidth) / scale;
|
||||
workspaceMetrics.contentBottom =
|
||||
(defaultMetrics.contentTop + defaultMetrics.contentHeight) / scale;
|
||||
}
|
||||
|
||||
return workspaceMetrics;
|
||||
};
|
||||
|
||||
var getObjectMetrics = function(object) {
|
||||
var objectMetrics = object.getBoundingRectangle();
|
||||
objectMetrics.height = objectMetrics.bottom - objectMetrics.top;
|
||||
objectMetrics.width = objectMetrics.right - objectMetrics.left;
|
||||
return objectMetrics;
|
||||
};
|
||||
|
||||
var bumpObjects = function(e) {
|
||||
// We always check isMovable_ again because the original
|
||||
// "not movable" state of isMovable_ could have been changed.
|
||||
if (!mainWorkspace.isDragging() && !mainWorkspace.isMovable() &&
|
||||
(Blockly.Events.BUMP_EVENTS.indexOf(e.type) != -1)) {
|
||||
var metrics = getWorkspaceMetrics();
|
||||
if (metrics.contentTop < metrics.viewTop ||
|
||||
metrics.contentBottom > metrics.viewBottom ||
|
||||
metrics.contentLeft < metrics.viewLeft ||
|
||||
metrics.contentRight > metrics.viewRight) {
|
||||
|
||||
// Handle undo.
|
||||
var oldGroup = null;
|
||||
if (e) {
|
||||
oldGroup = Blockly.Events.getGroup();
|
||||
Blockly.Events.setGroup(e.group);
|
||||
}
|
||||
|
||||
switch (e.type) {
|
||||
case Blockly.Events.BLOCK_CREATE:
|
||||
case Blockly.Events.BLOCK_MOVE:
|
||||
var object = mainWorkspace.getBlockById(e.blockId);
|
||||
if (object) {
|
||||
object = object.getRootBlock();
|
||||
}
|
||||
break;
|
||||
case Blockly.Events.COMMENT_CREATE:
|
||||
case Blockly.Events.COMMENT_MOVE:
|
||||
var object = mainWorkspace.getCommentById(e.commentId);
|
||||
break;
|
||||
}
|
||||
if (object) {
|
||||
var objectMetrics = getObjectMetrics(object);
|
||||
|
||||
// The idea is to find the region of valid coordinates for the top
|
||||
// left corner of the object, and then clamp the object's
|
||||
// top left corner within that region.
|
||||
|
||||
// The top of the object should always be at or below the top of
|
||||
// the workspace.
|
||||
var topClamp = metrics.viewTop;
|
||||
// The top of the object should ideally be positioned so that
|
||||
// the bottom of the object is not below the bottom of the
|
||||
// workspace.
|
||||
var bottomClamp = metrics.viewBottom - objectMetrics.height;
|
||||
// If the object is taller than the workspace we want to
|
||||
// top-align the block, which means setting the bottom clamp to
|
||||
// match.
|
||||
bottomClamp = Math.max(topClamp, bottomClamp);
|
||||
|
||||
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.
|
||||
|
||||
// The left edge of the object should ideally be positioned at
|
||||
// or to the right of the left edge of the workspace.
|
||||
var leftClamp = metrics.viewLeft;
|
||||
// The left edge of the object should ideally be positioned so
|
||||
// that the right of the object is not outside the workspace bounds.
|
||||
var rightClamp = metrics.viewRight - objectMetrics.width;
|
||||
if (metrics.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;
|
||||
|
||||
object.moveBy(deltaX, deltaY);
|
||||
}
|
||||
if (e) {
|
||||
if (!e.group && object) {
|
||||
console.warn('Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.');
|
||||
}
|
||||
if (oldGroup !== null) {
|
||||
Blockly.Events.setGroup(oldGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
mainWorkspace.addChangeListener(bumpObjects);
|
||||
}
|
||||
mainWorkspace.addChangeListener(Blockly.bumpIntoBoundsHandler_(mainWorkspace));
|
||||
|
||||
// The SVG is now fully assembled.
|
||||
Blockly.svgResize(mainWorkspace);
|
||||
@@ -328,6 +190,148 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface,
|
||||
return mainWorkspace;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the object from the given event.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace the event originated
|
||||
* from.
|
||||
* @param {!Blockly.Events.BumpEvent} e An event containing an object.
|
||||
* @return {?Blockly.BlockSvg|?Blockly.WorkspaceCommentSvg} The extracted
|
||||
* object.
|
||||
* @private
|
||||
*/
|
||||
Blockly.extractObjectFromEvent_ = function(workspace, e) {
|
||||
var object = null;
|
||||
switch (e.type) {
|
||||
case Blockly.Events.BLOCK_CREATE:
|
||||
case Blockly.Events.BLOCK_MOVE:
|
||||
object = workspace.getBlockById(e.blockId);
|
||||
if (object) {
|
||||
object = object.getRootBlock();
|
||||
}
|
||||
break;
|
||||
case Blockly.Events.COMMENT_CREATE:
|
||||
case Blockly.Events.COMMENT_MOVE:
|
||||
object = workspace.getCommentById(e.commentId);
|
||||
break;
|
||||
}
|
||||
return object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bumps the top objects in the given workspace into bounds.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace.
|
||||
* @private
|
||||
*/
|
||||
Blockly.bumpTopObjectsIntoBounds_ = function(workspace) {
|
||||
var metricsManager = workspace.getMetricsManager();
|
||||
if (!metricsManager.hasFixedEdges() || workspace.isDragging()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var scrollMetricsInWsCoords = metricsManager.getScrollMetrics(true);
|
||||
var topBlocks = workspace.getTopBoundedElements();
|
||||
for (var i = 0, block; (block = topBlocks[i]); i++) {
|
||||
Blockly.bumpObjectIntoBounds_(
|
||||
workspace, scrollMetricsInWsCoords, block);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a handler for bumping objects when they cross fixed bounds.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace to handle.
|
||||
* @return {function(Blockly.Events.Abstract)} The event handler.
|
||||
* @private
|
||||
*/
|
||||
Blockly.bumpIntoBoundsHandler_ = function(workspace) {
|
||||
return function(e) {
|
||||
var metricsManager = workspace.getMetricsManager();
|
||||
if (!metricsManager.hasFixedEdges || workspace.isDragging()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Blockly.Events.BUMP_EVENTS.indexOf(e.type) !== -1) {
|
||||
var scrollMetricsInWsCoords = metricsManager.getScrollMetrics(true);
|
||||
|
||||
// Triggered by move/create event
|
||||
var object = Blockly.extractObjectFromEvent_(workspace, e);
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
// Handle undo.
|
||||
var oldGroup = Blockly.Events.getGroup();
|
||||
Blockly.Events.setGroup(e.group);
|
||||
|
||||
var wasBumped = Blockly.bumpObjectIntoBounds_(
|
||||
workspace, scrollMetricsInWsCoords,
|
||||
/** @type {!Blockly.IBoundedElement} */ (object));
|
||||
|
||||
if (wasBumped && !e.group) {
|
||||
console.warn('Moved object in bounds but there was no' +
|
||||
' event group. This may break undo.');
|
||||
}
|
||||
if (oldGroup !== null) {
|
||||
Blockly.Events.setGroup(oldGroup);
|
||||
}
|
||||
} else if (e.type === Blockly.Events.VIEWPORT_CHANGE) {
|
||||
var viewportEvent = /** @type {!Blockly.Events.ViewportChange} */ (e);
|
||||
if (viewportEvent.scale > viewportEvent.oldScale) {
|
||||
Blockly.bumpTopObjectsIntoBounds_(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.
|
||||
* @private
|
||||
*/
|
||||
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.
|
||||
@@ -338,7 +342,7 @@ Blockly.init_ = function(mainWorkspace) {
|
||||
var svg = mainWorkspace.getParentSvg();
|
||||
|
||||
// Suppress the browser's context menu.
|
||||
Blockly.bindEventWithChecks_(
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
/** @type {!Element} */ (svg.parentNode), 'contextmenu', null,
|
||||
function(e) {
|
||||
if (!Blockly.utils.isTargetInput(e)) {
|
||||
@@ -346,11 +350,11 @@ Blockly.init_ = function(mainWorkspace) {
|
||||
}
|
||||
});
|
||||
|
||||
var workspaceResizeHandler = Blockly.bindEventWithChecks_(window, 'resize',
|
||||
null,
|
||||
function() {
|
||||
var workspaceResizeHandler =
|
||||
Blockly.browserEvents.conditionalBind(window, 'resize', null, function() {
|
||||
Blockly.hideChaff(true);
|
||||
Blockly.svgResize(mainWorkspace);
|
||||
Blockly.bumpTopObjectsIntoBounds_(mainWorkspace);
|
||||
});
|
||||
mainWorkspace.setResizeHandlerWrapper(workspaceResizeHandler);
|
||||
|
||||
@@ -380,7 +384,14 @@ Blockly.init_ = function(mainWorkspace) {
|
||||
}
|
||||
|
||||
if (options.moveOptions && options.moveOptions.scrollbars) {
|
||||
mainWorkspace.scrollbar = new Blockly.ScrollbarPair(mainWorkspace);
|
||||
var horizontalScroll = options.moveOptions.scrollbars === true ||
|
||||
!!options.moveOptions.scrollbars.horizontal;
|
||||
var verticalScroll = options.moveOptions.scrollbars === true ||
|
||||
!!options.moveOptions.scrollbars.vertical;
|
||||
mainWorkspace.scrollbar =
|
||||
new Blockly.ScrollbarPair(
|
||||
mainWorkspace, horizontalScroll, verticalScroll,
|
||||
'blocklyMainWorkspaceScrollbar');
|
||||
mainWorkspace.scrollbar.resize();
|
||||
} else {
|
||||
mainWorkspace.setMetrics({x: 0.5, y: 0.5});
|
||||
@@ -405,7 +416,7 @@ Blockly.init_ = function(mainWorkspace) {
|
||||
*/
|
||||
Blockly.inject.bindDocumentEvents_ = function() {
|
||||
if (!Blockly.documentEventsBound_) {
|
||||
Blockly.bindEventWithChecks_(document, 'scroll', null, function() {
|
||||
Blockly.browserEvents.conditionalBind(document, 'scroll', null, function() {
|
||||
var workspaces = Blockly.Workspace.getAll();
|
||||
for (var i = 0, workspace; (workspace = workspaces[i]); i++) {
|
||||
if (workspace.updateInverseScreenCTM) {
|
||||
@@ -413,15 +424,17 @@ Blockly.inject.bindDocumentEvents_ = function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
Blockly.bindEventWithChecks_(document, 'keydown', null, Blockly.onKeyDown);
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
document, 'keydown', null, Blockly.onKeyDown);
|
||||
// longStop needs to run to stop the context menu from showing up. It
|
||||
// should run regardless of what other touch event handlers have run.
|
||||
Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_);
|
||||
Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_);
|
||||
Blockly.browserEvents.bind(document, 'touchend', null, Blockly.longStop_);
|
||||
Blockly.browserEvents.bind(
|
||||
document, 'touchcancel', null, Blockly.longStop_);
|
||||
// Some iPad versions don't fire resize after portrait to landscape change.
|
||||
if (Blockly.utils.userAgent.IPAD) {
|
||||
Blockly.bindEventWithChecks_(window, 'orientationchange', document,
|
||||
function() {
|
||||
Blockly.browserEvents.conditionalBind(
|
||||
window, 'orientationchange', document, function() {
|
||||
// TODO (#397): Fix for multiple Blockly workspaces.
|
||||
Blockly.svgResize(/** @type {!Blockly.WorkspaceSvg} */
|
||||
(Blockly.getMainWorkspace()));
|
||||
@@ -462,7 +475,7 @@ Blockly.inject.loadSounds_ = function(pathToMedia, workspace) {
|
||||
var soundBinds = [];
|
||||
var unbindSounds = function() {
|
||||
while (soundBinds.length) {
|
||||
Blockly.unbindEvent_(soundBinds.pop());
|
||||
Blockly.browserEvents.unbind(soundBinds.pop());
|
||||
}
|
||||
audioMgr.preload();
|
||||
};
|
||||
@@ -473,10 +486,8 @@ Blockly.inject.loadSounds_ = function(pathToMedia, workspace) {
|
||||
// necessary.
|
||||
|
||||
// Android ignores any sound not loaded as a result of a user action.
|
||||
soundBinds.push(
|
||||
Blockly.bindEventWithChecks_(document, 'mousemove', null, unbindSounds,
|
||||
true));
|
||||
soundBinds.push(
|
||||
Blockly.bindEventWithChecks_(document, 'touchstart', null, unbindSounds,
|
||||
true));
|
||||
soundBinds.push(Blockly.browserEvents.conditionalBind(
|
||||
document, 'mousemove', null, unbindSounds, true));
|
||||
soundBinds.push(Blockly.browserEvents.conditionalBind(
|
||||
document, 'touchstart', null, unbindSounds, true));
|
||||
};
|
||||
|
||||
@@ -13,8 +13,17 @@
|
||||
goog.provide('Blockly.Input');
|
||||
|
||||
goog.require('Blockly.Connection');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.fieldRegistry');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.FieldLabel');
|
||||
goog.require('Blockly.inputTypes');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,7 +36,7 @@ goog.require('Blockly.FieldLabel');
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Input = function(type, name, block, connection) {
|
||||
if (type != Blockly.DUMMY_INPUT && !name) {
|
||||
if (type != Blockly.inputTypes.DUMMY && !name) {
|
||||
throw Error('Value inputs and statement inputs must have non-empty name.');
|
||||
}
|
||||
/** @type {number} */
|
||||
@@ -49,7 +58,7 @@ Blockly.Input = function(type, name, block, connection) {
|
||||
* Alignment of input's fields (left, right or centre).
|
||||
* @type {number}
|
||||
*/
|
||||
Blockly.Input.prototype.align = Blockly.ALIGN_LEFT;
|
||||
Blockly.Input.prototype.align = Blockly.constants.ALIGN.LEFT;
|
||||
|
||||
/**
|
||||
* Is the input visible?
|
||||
@@ -100,7 +109,10 @@ Blockly.Input.prototype.insertFieldAt = function(index, field, opt_name) {
|
||||
|
||||
// Generate a FieldLabel when given a plain text field.
|
||||
if (typeof field == 'string') {
|
||||
field = new Blockly.FieldLabel(/** @type {string} */ (field));
|
||||
field = /** @type {!Blockly.Field} **/ (Blockly.fieldRegistry.fromJson({
|
||||
'type': 'field_label',
|
||||
'text': field,
|
||||
}));
|
||||
}
|
||||
|
||||
field.setSourceBlock(this.sourceBlock_);
|
||||
@@ -111,17 +123,16 @@ Blockly.Input.prototype.insertFieldAt = function(index, field, opt_name) {
|
||||
field.name = opt_name;
|
||||
field.setVisible(this.isVisible());
|
||||
|
||||
var fieldDropdown = /** @type {Blockly.FieldDropdown} */ (field);
|
||||
if (fieldDropdown.prefixField) {
|
||||
if (field.prefixField) {
|
||||
// Add any prefix.
|
||||
index = this.insertFieldAt(index, fieldDropdown.prefixField);
|
||||
index = this.insertFieldAt(index, field.prefixField);
|
||||
}
|
||||
// Add the field to the field row.
|
||||
this.fieldRow.splice(index, 0, field);
|
||||
++index;
|
||||
if (fieldDropdown.suffixField) {
|
||||
if (field.suffixField) {
|
||||
// Add any suffix.
|
||||
index = this.insertFieldAt(index, fieldDropdown.suffixField);
|
||||
index = this.insertFieldAt(index, field.suffixField);
|
||||
}
|
||||
|
||||
if (this.sourceBlock_.rendered) {
|
||||
@@ -233,8 +244,8 @@ Blockly.Input.prototype.setCheck = function(check) {
|
||||
|
||||
/**
|
||||
* Change the alignment of the connection's field(s).
|
||||
* @param {number} align One of Blockly.ALIGN_LEFT, ALIGN_CENTRE, ALIGN_RIGHT.
|
||||
* In RTL mode directions are reversed, and ALIGN_RIGHT aligns to the left.
|
||||
* @param {number} align One of the values of Blockly.constants.ALIGN.
|
||||
* In RTL mode directions are reversed, and ALIGN.RIGHT aligns to the left.
|
||||
* @return {!Blockly.Input} The input being modified (to allow chaining).
|
||||
*/
|
||||
Blockly.Input.prototype.setAlign = function(align) {
|
||||
|
||||
29
core/input_types.js
Normal file
29
core/input_types.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview An enum for the possible types of inputs.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.inputTypes');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
|
||||
/**
|
||||
* Enum for the type of a connection or input.
|
||||
* @enum {number}
|
||||
*/
|
||||
Blockly.inputTypes = {
|
||||
// A right-facing value input. E.g. 'set item to' or 'return'.
|
||||
VALUE: Blockly.connectionTypes.INPUT_VALUE,
|
||||
// A down-facing block stack. E.g. 'if-do' or 'else'.
|
||||
STATEMENT: Blockly.connectionTypes.NEXT_STATEMENT,
|
||||
// A dummy input. Used to add field(s) with no input.
|
||||
DUMMY: 5
|
||||
};
|
||||
@@ -13,9 +13,16 @@
|
||||
goog.provide('Blockly.InsertionMarkerManager');
|
||||
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class that controls updates to connections during drags. It is primarily
|
||||
@@ -268,7 +275,7 @@ Blockly.InsertionMarkerManager.prototype.createMarkerBlock_ = function(sourceBlo
|
||||
// child blocks here.
|
||||
for (var i = 0; i < sourceBlock.inputList.length; i++) {
|
||||
var sourceInput = sourceBlock.inputList[i];
|
||||
if (sourceInput.name == Blockly.Block.COLLAPSED_INPUT_NAME) {
|
||||
if (sourceInput.name == Blockly.constants.COLLAPSED_INPUT_NAME) {
|
||||
continue; // Ignore the collapsed input.
|
||||
}
|
||||
var resultInput = result.inputList[i];
|
||||
@@ -612,7 +619,8 @@ Blockly.InsertionMarkerManager.prototype.hideInsertionMarker_ = function() {
|
||||
var isFirstInStatementStack =
|
||||
(imConn == markerNext && !(markerPrev && markerPrev.targetConnection));
|
||||
|
||||
var isFirstInOutputStack = imConn.type == Blockly.INPUT_VALUE &&
|
||||
var isFirstInOutputStack =
|
||||
imConn.type == Blockly.connectionTypes.INPUT_VALUE &&
|
||||
!(markerOutput && markerOutput.targetConnection);
|
||||
// The insertion marker is the first block in a stack. Unplug won't do
|
||||
// anything in that case. Instead, unplug the following block.
|
||||
@@ -620,7 +628,8 @@ Blockly.InsertionMarkerManager.prototype.hideInsertionMarker_ = function() {
|
||||
imConn.targetBlock().unplug(false);
|
||||
}
|
||||
// Inside of a C-block, first statement connection.
|
||||
else if (imConn.type == Blockly.NEXT_STATEMENT && imConn != markerNext) {
|
||||
else if (imConn.type == Blockly.connectionTypes.NEXT_STATEMENT &&
|
||||
imConn != markerNext) {
|
||||
var innerConnection = imConn.targetConnection;
|
||||
innerConnection.getSourceBlock().unplug(false);
|
||||
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
goog.provide('Blockly.IASTNodeLocation');
|
||||
goog.provide('Blockly.IASTNodeLocationSvg');
|
||||
goog.provide('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.provide('Blockly.IBlocklyActionable');
|
||||
goog.provide('Blockly.IKeyboardAccessible');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
|
||||
|
||||
/**
|
||||
* An AST node location interface.
|
||||
* @interface
|
||||
@@ -59,15 +62,14 @@ Blockly.IASTNodeLocationWithBlock.prototype.getSourceBlock;
|
||||
|
||||
|
||||
/**
|
||||
* An interface for an object that handles Blockly actions when keyboard
|
||||
* navigation is enabled.
|
||||
* An interface for an object that handles keyboard shortcuts.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IBlocklyActionable = function() {};
|
||||
Blockly.IKeyboardAccessible = function() {};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* Handles the given keyboard shortcut.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} shortcut The shortcut to be handled.
|
||||
* @return {boolean} True if the shortcut has been handled, false otherwise.
|
||||
*/
|
||||
Blockly.IBlocklyActionable.prototype.onBlocklyAction;
|
||||
Blockly.IKeyboardAccessible.prototype.onShortcut;
|
||||
|
||||
@@ -29,3 +29,10 @@ Blockly.IBoundedElement = function() {};
|
||||
* @return {!Blockly.utils.Rect} Object with coordinates of the bounded element.
|
||||
*/
|
||||
Blockly.IBoundedElement.prototype.getBoundingRectangle;
|
||||
|
||||
/**
|
||||
* Move the element by a relative offset.
|
||||
* @param {number} dx Horizontal offset in workspace units.
|
||||
* @param {number} dy Vertical offset in workspace units.
|
||||
*/
|
||||
Blockly.IBoundedElement.prototype.moveBy;
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
|
||||
goog.provide('Blockly.IBubble');
|
||||
|
||||
goog.requireType('Blockly.BlockDragSurfaceSvg');
|
||||
goog.requireType('Blockly.IContextMenu');
|
||||
goog.requireType('Blockly.IDeletable');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
goog.provide('Blockly.IConnectionChecker');
|
||||
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
goog.provide('Blockly.IDeleteArea');
|
||||
|
||||
goog.requireType('Blockly.utils.Rect');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a component that can delete a block that is dropped on top of it.
|
||||
|
||||
@@ -15,7 +15,6 @@ goog.provide('Blockly.IFlyout');
|
||||
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.IRegistrable');
|
||||
goog.requireType('Blockly.utils.dom');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
goog.requireType('Blockly.utils.Svg');
|
||||
goog.requireType('Blockly.utils.toolbox');
|
||||
|
||||
145
core/interfaces/i_metrics_manager.js
Normal file
145
core/interfaces/i_metrics_manager.js
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a metrics manager.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IMetricsManager');
|
||||
|
||||
goog.requireType('Blockly.MetricsManager');
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.utils.Size');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a metrics manager.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IMetricsManager = function() {};
|
||||
|
||||
/**
|
||||
* Returns whether the scroll area has fixed edges.
|
||||
* @return {boolean} Whether the scroll area has fixed edges.
|
||||
* @package
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.hasFixedEdges;
|
||||
|
||||
/**
|
||||
* Returns the metrics for the scroll area of the workspace.
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the scroll metrics
|
||||
* in workspace coordinates, false to get them in pixel coordinates.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view
|
||||
* metrics if they have been previously computed. Passing in null may cause
|
||||
* the view metrics to be computed again, if it is needed.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion=} opt_contentMetrics The
|
||||
* content metrics if they have been previously computed. Passing in null
|
||||
* may cause the content metrics to be computed again, if it is needed.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The metrics for the scroll
|
||||
* container
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getScrollMetrics;
|
||||
|
||||
/**
|
||||
* Gets the width and the height of the flyout on the workspace in pixel
|
||||
* coordinates. Returns 0 for the width and height if the workspace has a
|
||||
* category toolbox instead of a simple toolbox.
|
||||
* @param {boolean=} opt_own Whether to only return the workspace's own flyout.
|
||||
* @return {!Blockly.MetricsManager.ToolboxMetrics} The width and height of the
|
||||
* flyout.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getFlyoutMetrics;
|
||||
|
||||
/**
|
||||
* Gets the width, height and position of the toolbox on the workspace in pixel
|
||||
* coordinates. Returns 0 for the width and height if the workspace has a simple
|
||||
* toolbox instead of a category toolbox. To get the width and height of a
|
||||
* simple toolbox @see {@link getFlyoutMetrics}.
|
||||
* @return {!Blockly.MetricsManager.ToolboxMetrics} The object with the width,
|
||||
* height and position of the toolbox.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getToolboxMetrics;
|
||||
|
||||
/**
|
||||
* Gets the width and height of the workspace's parent svg element in pixel
|
||||
* coordinates. This area includes the toolbox and the visible workspace area.
|
||||
* @return {!Blockly.utils.Size} The width and height of the workspace's parent
|
||||
* svg element.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getSvgMetrics;
|
||||
|
||||
/**
|
||||
* Gets the absolute left and absolute top in pixel coordinates.
|
||||
* This is where the visible workspace starts in relation to the svg container.
|
||||
* @return {!Blockly.MetricsManager.AbsoluteMetrics} The absolute metrics for
|
||||
* the workspace.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getAbsoluteMetrics;
|
||||
|
||||
/**
|
||||
* Gets the metrics for the visible workspace in either pixel or workspace
|
||||
* coordinates. The visible workspace does not include the toolbox or flyout.
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the view metrics in
|
||||
* workspace coordinates, false to get them in pixel coordinates.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The width, height, top and
|
||||
* left of the viewport in either workspace coordinates or pixel
|
||||
* coordinates.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getViewMetrics;
|
||||
|
||||
/**
|
||||
* Gets content metrics in either pixel or workspace coordinates.
|
||||
* The content area is a rectangle around all the top bounded elements on the
|
||||
* workspace (workspace comments and blocks).
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the content metrics
|
||||
* in workspace coordinates, false to get them in pixel coordinates.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The
|
||||
* metrics for the content container.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getContentMetrics;
|
||||
|
||||
/**
|
||||
* Returns an object with all the metrics required to size scrollbars for a
|
||||
* top level workspace. The following properties are computed:
|
||||
* Coordinate system: pixel coordinates, -left, -up, +right, +down
|
||||
* .viewHeight: Height of the visible portion of the workspace.
|
||||
* .viewWidth: Width of the visible portion of the workspace.
|
||||
* .contentHeight: Height of the content.
|
||||
* .contentWidth: Width of the content.
|
||||
* .svgHeight: Height of the Blockly div (the view + the toolbox,
|
||||
* simple or otherwise),
|
||||
* .svgWidth: Width of the Blockly div (the view + the toolbox,
|
||||
* simple or otherwise),
|
||||
* .viewTop: Top-edge of the visible portion of the workspace, relative to
|
||||
* the workspace origin.
|
||||
* .viewLeft: Left-edge of the visible portion of the workspace, relative to
|
||||
* the workspace origin.
|
||||
* .contentTop: Top-edge of the content, relative to the workspace origin.
|
||||
* .contentLeft: Left-edge of the content relative to the workspace origin.
|
||||
* .absoluteTop: Top-edge of the visible portion of the workspace, relative
|
||||
* to the blocklyDiv.
|
||||
* .absoluteLeft: Left-edge of the visible portion of the workspace, relative
|
||||
* to the blocklyDiv.
|
||||
* .toolboxWidth: Width of the toolbox, if it exists. Otherwise zero.
|
||||
* .toolboxHeight: Height of the toolbox, if it exists. Otherwise zero.
|
||||
* .flyoutWidth: Width of the flyout if it is always open. Otherwise zero.
|
||||
* .flyoutHeight: Height of the flyout if it is always open. Otherwise zero.
|
||||
* .toolboxPosition: Top, bottom, left or right. Use TOOLBOX_AT constants to
|
||||
* compare.
|
||||
* @return {!Blockly.utils.Metrics} Contains size and position metrics of a top
|
||||
* level workspace.
|
||||
* @public
|
||||
*/
|
||||
Blockly.IMetricsManager.prototype.getMetrics;
|
||||
22
core/interfaces/i_plugin.js
Normal file
22
core/interfaces/i_plugin.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Interface for a plugin.
|
||||
* @author kozbial@google.com (Monica Kozbial)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IPlugin');
|
||||
|
||||
|
||||
/**
|
||||
* The interface for a workspace plugin.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IPlugin = function() {};
|
||||
|
||||
39
core/interfaces/i_positionable.js
Normal file
39
core/interfaces/i_positionable.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a positionable ui element.
|
||||
* @author kozbial@google.com (Monica Kozbial)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IPositionable');
|
||||
|
||||
goog.require('Blockly.IPlugin');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a component that is positioned on top of the workspace.
|
||||
* @extends {Blockly.IPlugin}
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IPositionable = function() {};
|
||||
|
||||
/**
|
||||
* Positions the element. Called when the window is resized.
|
||||
* @param {!Blockly.MetricsManager.UiMetrics} metrics The workspace metrics.
|
||||
* @param {!Array<!Blockly.utils.Rect>} savedPositions List of rectangles that
|
||||
* are already on the workspace.
|
||||
*/
|
||||
Blockly.IPositionable.prototype.position;
|
||||
|
||||
/**
|
||||
* Returns the bounding rectangle of the UI element in pixel units relative to
|
||||
* the Blockly injection div.
|
||||
* @return {!Blockly.utils.Rect} The plugin’s bounding box.
|
||||
*/
|
||||
Blockly.IPositionable.prototype.getBoundingRectangle;
|
||||
20
core/interfaces/i_workspace_plugin.js
Normal file
20
core/interfaces/i_workspace_plugin.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Interface for plugins that can be registered on the workspace.
|
||||
* @author kozbial@google.com (Monica Kozbial)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IWorkspacePlugin');
|
||||
|
||||
/**
|
||||
* Base interface for a plugin that can be registered on the workspace.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IWorkspacePlugin = function() {};
|
||||
@@ -12,11 +12,18 @@
|
||||
|
||||
goog.provide('Blockly.ASTNode');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IASTNodeLocation');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.requireType('Blockly.Input');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
@@ -142,16 +149,17 @@ Blockly.ASTNode.createConnectionNode = function(connection) {
|
||||
if (!connection) {
|
||||
return null;
|
||||
}
|
||||
if (connection.type == Blockly.INPUT_VALUE) {
|
||||
var type = connection.type;
|
||||
if (type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
return Blockly.ASTNode.createInputNode(connection.getParentInput());
|
||||
} else if (connection.type == Blockly.NEXT_STATEMENT &&
|
||||
} else if (type == Blockly.connectionTypes.NEXT_STATEMENT &&
|
||||
connection.getParentInput()) {
|
||||
return Blockly.ASTNode.createInputNode(connection.getParentInput());
|
||||
} else if (connection.type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.NEXT, connection);
|
||||
} else if (connection.type == Blockly.OUTPUT_VALUE) {
|
||||
} else if (type == Blockly.connectionTypes.OUTPUT_VALUE) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.OUTPUT, connection);
|
||||
} else if (connection.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
} else if (type == Blockly.connectionTypes.PREVIOUS_STATEMENT) {
|
||||
return new Blockly.ASTNode(Blockly.ASTNode.types.PREVIOUS, connection);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -15,6 +15,7 @@ goog.provide('Blockly.BasicCursor');
|
||||
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.Cursor');
|
||||
goog.require('Blockly.registry');
|
||||
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,12 @@ Blockly.BasicCursor = function() {
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.BasicCursor, Blockly.Cursor);
|
||||
|
||||
/**
|
||||
* Name used for registering a basic cursor.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.BasicCursor.registrationName = 'basicCursor';
|
||||
|
||||
/**
|
||||
* Find the next node in the pre order traversal.
|
||||
* @return {Blockly.ASTNode} The next node, or null if the current node is
|
||||
@@ -50,7 +57,8 @@ Blockly.BasicCursor.prototype.next = function() {
|
||||
|
||||
/**
|
||||
* For a basic cursor we only have the ability to go next and previous, so
|
||||
* in will also allow the user to get to the next node in the pre order traversal.
|
||||
* in will also allow the user to get to the next node in the pre order
|
||||
* traversal.
|
||||
* @return {Blockly.ASTNode} The next node, or null if the current node is
|
||||
* not set or there is no next value.
|
||||
* @override
|
||||
@@ -80,7 +88,8 @@ Blockly.BasicCursor.prototype.prev = function() {
|
||||
|
||||
/**
|
||||
* For a basic cursor we only have the ability to go next and previous, so
|
||||
* out will allow the user to get to the previous node in the pre order traversal.
|
||||
* out will allow the user to get to the previous node in the pre order
|
||||
* traversal.
|
||||
* @return {Blockly.ASTNode} The previous node, or null if the current node is
|
||||
* not set or there is no previous value.
|
||||
* @override
|
||||
@@ -119,9 +128,9 @@ Blockly.BasicCursor.prototype.getNextNode_ = function(node, isValid) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverses the pre order traversal in order to find the previous node. This will
|
||||
* allow a user to easily navigate the entire Blockly AST without having to go in
|
||||
* and out levels on the tree.
|
||||
* Reverses the pre order traversal in order to find the previous node. This
|
||||
* will allow a user to easily navigate the entire Blockly AST without having to
|
||||
* go in and out levels on the tree.
|
||||
* @param {Blockly.ASTNode} node The current position in the AST.
|
||||
* @param {!function(Blockly.ASTNode) : boolean} isValid A function true/false
|
||||
* depending on whether the given node should be traversed.
|
||||
@@ -204,5 +213,8 @@ Blockly.BasicCursor.prototype.getRightMostChild_ = function(node) {
|
||||
newNode = newNode.next();
|
||||
}
|
||||
return this.getRightMostChild_(newNode);
|
||||
|
||||
};
|
||||
|
||||
Blockly.registry.register(
|
||||
Blockly.registry.Type.CURSOR, Blockly.BasicCursor.registrationName,
|
||||
Blockly.BasicCursor);
|
||||
|
||||
@@ -15,19 +15,15 @@ goog.provide('Blockly.Cursor');
|
||||
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.Marker');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a cursor.
|
||||
* A cursor controls how a user navigates the Blockly AST.
|
||||
* @constructor
|
||||
* @extends {Blockly.Marker}
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
*/
|
||||
Blockly.Cursor = function() {
|
||||
Blockly.Cursor.superClass_.constructor.call(this);
|
||||
@@ -43,7 +39,7 @@ Blockly.utils.object.inherits(Blockly.Cursor, Blockly.Marker);
|
||||
* Find the next connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The next element, or null if the current node is
|
||||
* not set or there is no next value.
|
||||
* @protected
|
||||
* @public
|
||||
*/
|
||||
Blockly.Cursor.prototype.next = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -53,8 +49,8 @@ Blockly.Cursor.prototype.next = function() {
|
||||
|
||||
var newNode = curNode.next();
|
||||
while (newNode && newNode.next() &&
|
||||
(newNode.getType() == Blockly.ASTNode.types.NEXT ||
|
||||
newNode.getType() == Blockly.ASTNode.types.BLOCK)) {
|
||||
(newNode.getType() == Blockly.ASTNode.types.NEXT ||
|
||||
newNode.getType() == Blockly.ASTNode.types.BLOCK)) {
|
||||
newNode = newNode.next();
|
||||
}
|
||||
|
||||
@@ -68,7 +64,7 @@ Blockly.Cursor.prototype.next = function() {
|
||||
* Find the in connection or field.
|
||||
* @return {Blockly.ASTNode} The in element, or null if the current node is
|
||||
* not set or there is no in value.
|
||||
* @protected
|
||||
* @public
|
||||
*/
|
||||
Blockly.Cursor.prototype.in = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -78,7 +74,7 @@ Blockly.Cursor.prototype.in = function() {
|
||||
// If we are on a previous or output connection, go to the block level before
|
||||
// performing next operation.
|
||||
if (curNode.getType() == Blockly.ASTNode.types.PREVIOUS ||
|
||||
curNode.getType() == Blockly.ASTNode.types.OUTPUT) {
|
||||
curNode.getType() == Blockly.ASTNode.types.OUTPUT) {
|
||||
curNode = curNode.next();
|
||||
}
|
||||
var newNode = curNode.in();
|
||||
@@ -93,7 +89,7 @@ Blockly.Cursor.prototype.in = function() {
|
||||
* Find the previous connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The previous element, or null if the current node
|
||||
* is not set or there is no previous value.
|
||||
* @protected
|
||||
* @public
|
||||
*/
|
||||
Blockly.Cursor.prototype.prev = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -103,8 +99,8 @@ Blockly.Cursor.prototype.prev = function() {
|
||||
var newNode = curNode.prev();
|
||||
|
||||
while (newNode && newNode.prev() &&
|
||||
(newNode.getType() == Blockly.ASTNode.types.NEXT ||
|
||||
newNode.getType() == Blockly.ASTNode.types.BLOCK)) {
|
||||
(newNode.getType() == Blockly.ASTNode.types.NEXT ||
|
||||
newNode.getType() == Blockly.ASTNode.types.BLOCK)) {
|
||||
newNode = newNode.prev();
|
||||
}
|
||||
|
||||
@@ -118,7 +114,7 @@ Blockly.Cursor.prototype.prev = function() {
|
||||
* Find the out connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The out element, or null if the current node is
|
||||
* not set or there is no out value.
|
||||
* @protected
|
||||
* @public
|
||||
*/
|
||||
Blockly.Cursor.prototype.out = function() {
|
||||
var curNode = this.getCurNode();
|
||||
@@ -137,34 +133,5 @@ Blockly.Cursor.prototype.out = function() {
|
||||
return newNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard navigation is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
*/
|
||||
Blockly.Cursor.prototype.onBlocklyAction = function(action) {
|
||||
// If we are on a field give it the option to handle the action
|
||||
if (this.getCurNode() &&
|
||||
this.getCurNode().getType() === Blockly.ASTNode.types.FIELD &&
|
||||
(/** @type {!Blockly.Field} */ (this.getCurNode().getLocation()))
|
||||
.onBlocklyAction(action)) {
|
||||
return true;
|
||||
}
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.OUT:
|
||||
this.out();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.next();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.IN:
|
||||
this.in();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Blockly.registry.register(
|
||||
Blockly.registry.Type.CURSOR, Blockly.registry.DEFAULT, Blockly.Cursor);
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The class representing a cursor used to navigate the flyout.
|
||||
* Used primarily for keyboard navigation.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.FlyoutCursor');
|
||||
|
||||
goog.require('Blockly.Cursor');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.ShortcutRegistry');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a flyout cursor.
|
||||
* This controls how a user navigates blocks in the flyout.
|
||||
* @constructor
|
||||
* @extends {Blockly.Cursor}
|
||||
*/
|
||||
Blockly.FlyoutCursor = function() {
|
||||
Blockly.FlyoutCursor.superClass_.constructor.call(this);
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.FlyoutCursor, Blockly.Cursor);
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* This is only triggered when keyboard navigation is enabled.
|
||||
* @param {!Blockly.ShortcutRegistry.KeyboardShortcut} action The action to be handled.
|
||||
* @return {boolean} True if the action has been handled, false otherwise.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.onBlocklyAction = function(action) {
|
||||
switch (action.name) {
|
||||
case Blockly.navigation.actionNames.PREVIOUS:
|
||||
this.prev();
|
||||
return true;
|
||||
case Blockly.navigation.actionNames.NEXT:
|
||||
this.next();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the next connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The next element, or null if the current node is
|
||||
* not set or there is no next value.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.next = function() {
|
||||
var curNode = this.getCurNode();
|
||||
if (!curNode) {
|
||||
return null;
|
||||
}
|
||||
var newNode = curNode.next();
|
||||
|
||||
if (newNode) {
|
||||
this.setCurNode(newNode);
|
||||
}
|
||||
return newNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a no-op since a flyout cursor can not go in.
|
||||
* @return {null} Always null.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.in = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the previous connection, field, or block.
|
||||
* @return {Blockly.ASTNode} The previous element, or null if the current node
|
||||
* is not set or there is no previous value.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.prev = function() {
|
||||
var curNode = this.getCurNode();
|
||||
if (!curNode) {
|
||||
return null;
|
||||
}
|
||||
var newNode = curNode.prev();
|
||||
|
||||
if (newNode) {
|
||||
this.setCurNode(newNode);
|
||||
}
|
||||
return newNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a no-op since a flyout cursor can not go out.
|
||||
* @return {null} Always null.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutCursor.prototype.out = function() {
|
||||
return null;
|
||||
};
|
||||
@@ -14,7 +14,8 @@
|
||||
goog.provide('Blockly.Marker');
|
||||
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.navigation');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.MarkerSvg');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,8 @@ goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.BasicCursor');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.Field');
|
||||
|
||||
|
||||
/**
|
||||
* A cursor for navigating between tab navigable fields.
|
||||
|
||||
@@ -15,6 +15,8 @@ goog.provide('Blockly.MarkerManager');
|
||||
goog.require('Blockly.Cursor');
|
||||
goog.require('Blockly.Marker');
|
||||
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage the multiple markers and the cursor on a workspace.
|
||||
@@ -52,6 +54,13 @@ Blockly.MarkerManager = function(workspace){
|
||||
this.workspace_ = workspace;
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the local marker.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
Blockly.MarkerManager.LOCAL_MARKER = 'local_marker_1';
|
||||
|
||||
/**
|
||||
* Register the marker by adding it to the map of markers.
|
||||
* @param {string} id A unique identifier for the marker.
|
||||
|
||||
44
core/menu.js
44
core/menu.js
@@ -12,12 +12,16 @@
|
||||
|
||||
goog.provide('Blockly.Menu');
|
||||
|
||||
goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.KeyCodes');
|
||||
goog.require('Blockly.utils.style');
|
||||
|
||||
goog.requireType('Blockly.MenuItem');
|
||||
goog.requireType('Blockly.utils.Size');
|
||||
|
||||
|
||||
/**
|
||||
* A basic menu class.
|
||||
@@ -52,35 +56,35 @@ Blockly.Menu = function() {
|
||||
|
||||
/**
|
||||
* Mouse over event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.mouseOverHandler_ = null;
|
||||
|
||||
/**
|
||||
* Click event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.clickHandler_ = null;
|
||||
|
||||
/**
|
||||
* Mouse enter event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.mouseEnterHandler_ = null;
|
||||
|
||||
/**
|
||||
* Mouse leave event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.mouseLeaveHandler_ = null;
|
||||
|
||||
/**
|
||||
* Key down event data.
|
||||
* @type {?Blockly.EventData}
|
||||
* @type {?Blockly.browserEvents.Data}
|
||||
* @private
|
||||
*/
|
||||
this.onKeyDownHandler_ = null;
|
||||
@@ -129,16 +133,16 @@ Blockly.Menu.prototype.render = function(container) {
|
||||
}
|
||||
|
||||
// Add event handlers.
|
||||
this.mouseOverHandler_ = Blockly.bindEventWithChecks_(element,
|
||||
'mouseover', this, this.handleMouseOver_, true);
|
||||
this.clickHandler_ = Blockly.bindEventWithChecks_(element,
|
||||
'click', this, this.handleClick_, true);
|
||||
this.mouseEnterHandler_ = Blockly.bindEventWithChecks_(element,
|
||||
'mouseenter', this, this.handleMouseEnter_, true);
|
||||
this.mouseLeaveHandler_ = Blockly.bindEventWithChecks_(element,
|
||||
'mouseleave', this, this.handleMouseLeave_, true);
|
||||
this.onKeyDownHandler_ = Blockly.bindEventWithChecks_(element,
|
||||
'keydown', this, this.handleKeyEvent_);
|
||||
this.mouseOverHandler_ = Blockly.browserEvents.conditionalBind(
|
||||
element, 'mouseover', this, this.handleMouseOver_, true);
|
||||
this.clickHandler_ = Blockly.browserEvents.conditionalBind(
|
||||
element, 'click', this, this.handleClick_, true);
|
||||
this.mouseEnterHandler_ = Blockly.browserEvents.conditionalBind(
|
||||
element, 'mouseenter', this, this.handleMouseEnter_, true);
|
||||
this.mouseLeaveHandler_ = Blockly.browserEvents.conditionalBind(
|
||||
element, 'mouseleave', this, this.handleMouseLeave_, true);
|
||||
this.onKeyDownHandler_ = Blockly.browserEvents.conditionalBind(
|
||||
element, 'keydown', this, this.handleKeyEvent_);
|
||||
|
||||
container.appendChild(element);
|
||||
};
|
||||
@@ -191,23 +195,23 @@ Blockly.Menu.prototype.setRole = function(roleName) {
|
||||
Blockly.Menu.prototype.dispose = function() {
|
||||
// Remove event handlers.
|
||||
if (this.mouseOverHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseOverHandler_);
|
||||
Blockly.browserEvents.unbind(this.mouseOverHandler_);
|
||||
this.mouseOverHandler_ = null;
|
||||
}
|
||||
if (this.clickHandler_) {
|
||||
Blockly.unbindEvent_(this.clickHandler_);
|
||||
Blockly.browserEvents.unbind(this.clickHandler_);
|
||||
this.clickHandler_ = null;
|
||||
}
|
||||
if (this.mouseEnterHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseEnterHandler_);
|
||||
Blockly.browserEvents.unbind(this.mouseEnterHandler_);
|
||||
this.mouseEnterHandler_ = null;
|
||||
}
|
||||
if (this.mouseLeaveHandler_) {
|
||||
Blockly.unbindEvent_(this.mouseLeaveHandler_);
|
||||
Blockly.browserEvents.unbind(this.mouseLeaveHandler_);
|
||||
this.mouseLeaveHandler_ = null;
|
||||
}
|
||||
if (this.onKeyDownHandler_) {
|
||||
Blockly.unbindEvent_(this.onKeyDownHandler_);
|
||||
Blockly.browserEvents.unbind(this.onKeyDownHandler_);
|
||||
this.onKeyDownHandler_ = null;
|
||||
}
|
||||
|
||||
|
||||
597
core/metrics_manager.js
Normal file
597
core/metrics_manager.js
Normal file
@@ -0,0 +1,597 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Calculates and reports workspace metrics.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.FlyoutMetricsManager');
|
||||
goog.provide('Blockly.MetricsManager');
|
||||
|
||||
goog.require('Blockly.IMetricsManager');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.Size');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* The manager for all workspace metrics calculations.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace to calculate metrics
|
||||
* for.
|
||||
* @implements {Blockly.IMetricsManager}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.MetricsManager = function(workspace) {
|
||||
/**
|
||||
* The workspace to calculate metrics for.
|
||||
* @type {!Blockly.WorkspaceSvg}
|
||||
* @protected
|
||||
*/
|
||||
this.workspace_ = workspace;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the width, height and location of the toolbox on the main
|
||||
* workspace.
|
||||
* @typedef {{
|
||||
* width: number,
|
||||
* height: number,
|
||||
* position: !Blockly.utils.toolbox.Position
|
||||
* }}
|
||||
*/
|
||||
Blockly.MetricsManager.ToolboxMetrics;
|
||||
|
||||
/**
|
||||
* Describes where the viewport starts in relation to the workspace svg.
|
||||
* @typedef {{
|
||||
* left: number,
|
||||
* top: number
|
||||
* }}
|
||||
*/
|
||||
Blockly.MetricsManager.AbsoluteMetrics;
|
||||
|
||||
|
||||
/**
|
||||
* All the measurements needed to describe the size and location of a container.
|
||||
* @typedef {{
|
||||
* height: number,
|
||||
* width: number,
|
||||
* top: number,
|
||||
* left: number
|
||||
* }}
|
||||
*/
|
||||
Blockly.MetricsManager.ContainerRegion;
|
||||
|
||||
/**
|
||||
* Describes fixed edges of the workspace.
|
||||
* @typedef {{
|
||||
* top: (number|undefined),
|
||||
* bottom: (number|undefined),
|
||||
* left: (number|undefined),
|
||||
* right: (number|undefined)
|
||||
* }}
|
||||
*/
|
||||
Blockly.MetricsManager.FixedEdges;
|
||||
|
||||
/**
|
||||
* Common metrics used for ui elements.
|
||||
* @typedef {{
|
||||
* viewMetrics: !Blockly.MetricsManager.ContainerRegion,
|
||||
* absoluteMetrics: !Blockly.MetricsManager.AbsoluteMetrics,
|
||||
* toolboxMetrics: !Blockly.MetricsManager.ToolboxMetrics
|
||||
* }}
|
||||
*/
|
||||
Blockly.MetricsManager.UiMetrics;
|
||||
|
||||
/**
|
||||
* Gets the dimensions of the given workspace component, in pixel coordinates.
|
||||
* @param {?Blockly.IToolbox|?Blockly.IFlyout} elem The element to get the
|
||||
* dimensions of, or null. It should be a toolbox or flyout, and should
|
||||
* implement getWidth() and getHeight().
|
||||
* @return {!Blockly.utils.Size} An object containing width and height
|
||||
* attributes, which will both be zero if elem did not exist.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getDimensionsPx_ = function(elem) {
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
if (elem) {
|
||||
width = elem.getWidth();
|
||||
height = elem.getHeight();
|
||||
}
|
||||
return new Blockly.utils.Size(width, height);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the width and the height of the flyout on the workspace in pixel
|
||||
* coordinates. Returns 0 for the width and height if the workspace has a
|
||||
* category toolbox instead of a simple toolbox.
|
||||
* @param {boolean=} opt_own Whether to only return the workspace's own flyout.
|
||||
* @return {!Blockly.MetricsManager.ToolboxMetrics} The width and height of the
|
||||
* flyout.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getFlyoutMetrics = function(opt_own) {
|
||||
var flyoutDimensions =
|
||||
this.getDimensionsPx_(this.workspace_.getFlyout(opt_own));
|
||||
return {
|
||||
width: flyoutDimensions.width,
|
||||
height: flyoutDimensions.height,
|
||||
position: this.workspace_.toolboxPosition
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the width, height and position of the toolbox on the workspace in pixel
|
||||
* coordinates. Returns 0 for the width and height if the workspace has a simple
|
||||
* toolbox instead of a category toolbox. To get the width and height of a
|
||||
* simple toolbox @see {@link getFlyoutMetrics}.
|
||||
* @return {!Blockly.MetricsManager.ToolboxMetrics} The object with the width,
|
||||
* height and position of the toolbox.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getToolboxMetrics = function() {
|
||||
var toolboxDimensions = this.getDimensionsPx_(this.workspace_.getToolbox());
|
||||
|
||||
return {
|
||||
width: toolboxDimensions.width,
|
||||
height: toolboxDimensions.height,
|
||||
position: this.workspace_.toolboxPosition
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the width and height of the workspace's parent svg element in pixel
|
||||
* coordinates. This area includes the toolbox and the visible workspace area.
|
||||
* @return {!Blockly.utils.Size} The width and height of the workspace's parent
|
||||
* svg element.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getSvgMetrics = function() {
|
||||
return this.workspace_.getCachedParentSvgSize();
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the absolute left and absolute top in pixel coordinates.
|
||||
* This is where the visible workspace starts in relation to the svg container.
|
||||
* @return {!Blockly.MetricsManager.AbsoluteMetrics} The absolute metrics for
|
||||
* the workspace.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getAbsoluteMetrics = function() {
|
||||
var absoluteLeft = 0;
|
||||
var toolboxMetrics = this.getToolboxMetrics();
|
||||
var flyoutMetrics = this.getFlyoutMetrics(true);
|
||||
var doesToolboxExist = !!this.workspace_.getToolbox();
|
||||
var doesFlyoutExist = !!this.workspace_.getFlyout(true);
|
||||
var toolboxPosition =
|
||||
doesToolboxExist ? toolboxMetrics.position : flyoutMetrics.position;
|
||||
|
||||
var atLeft = toolboxPosition == Blockly.utils.toolbox.Position.LEFT;
|
||||
var atTop = toolboxPosition == Blockly.utils.toolbox.Position.TOP;
|
||||
if (doesToolboxExist && atLeft) {
|
||||
absoluteLeft = toolboxMetrics.width;
|
||||
} else if (doesFlyoutExist && atLeft) {
|
||||
absoluteLeft = flyoutMetrics.width;
|
||||
}
|
||||
var absoluteTop = 0;
|
||||
if (doesToolboxExist && atTop) {
|
||||
absoluteTop = toolboxMetrics.height;
|
||||
} else if (doesFlyoutExist && atTop) {
|
||||
absoluteTop = flyoutMetrics.height;
|
||||
}
|
||||
|
||||
return {
|
||||
top: absoluteTop,
|
||||
left: absoluteLeft,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the metrics for the visible workspace in either pixel or workspace
|
||||
* coordinates. The visible workspace does not include the toolbox or flyout.
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the view metrics in
|
||||
* workspace coordinates, false to get them in pixel coordinates.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The width, height, top and
|
||||
* left of the viewport in either workspace coordinates or pixel
|
||||
* coordinates.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getViewMetrics = function(
|
||||
opt_getWorkspaceCoordinates) {
|
||||
var scale = opt_getWorkspaceCoordinates ? this.workspace_.scale : 1;
|
||||
var svgMetrics = this.getSvgMetrics();
|
||||
var toolboxMetrics = this.getToolboxMetrics();
|
||||
var flyoutMetrics = this.getFlyoutMetrics(true);
|
||||
var doesToolboxExist = !!this.workspace_.getToolbox();
|
||||
var toolboxPosition =
|
||||
doesToolboxExist ? toolboxMetrics.position : flyoutMetrics.position;
|
||||
|
||||
if (this.workspace_.getToolbox()) {
|
||||
if (toolboxPosition == Blockly.utils.toolbox.Position.TOP ||
|
||||
toolboxPosition == Blockly.utils.toolbox.Position.BOTTOM) {
|
||||
svgMetrics.height -= toolboxMetrics.height;
|
||||
} else if (toolboxPosition == Blockly.utils.toolbox.Position.LEFT ||
|
||||
toolboxPosition == Blockly.utils.toolbox.Position.RIGHT) {
|
||||
svgMetrics.width -= toolboxMetrics.width;
|
||||
}
|
||||
} else if (this.workspace_.getFlyout(true)) {
|
||||
if (toolboxPosition == Blockly.utils.toolbox.Position.TOP ||
|
||||
toolboxPosition == Blockly.utils.toolbox.Position.BOTTOM) {
|
||||
svgMetrics.height -= flyoutMetrics.height;
|
||||
} else if (toolboxPosition == Blockly.utils.toolbox.Position.LEFT ||
|
||||
toolboxPosition == Blockly.utils.toolbox.Position.RIGHT) {
|
||||
svgMetrics.width -= flyoutMetrics.width;
|
||||
}
|
||||
}
|
||||
return {
|
||||
height: svgMetrics.height / scale,
|
||||
width: svgMetrics.width / scale,
|
||||
top: -this.workspace_.scrollY / scale,
|
||||
left: -this.workspace_.scrollX / scale,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets content metrics in either pixel or workspace coordinates.
|
||||
* The content area is a rectangle around all the top bounded elements on the
|
||||
* workspace (workspace comments and blocks).
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the content metrics
|
||||
* in workspace coordinates, false to get them in pixel coordinates.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The
|
||||
* metrics for the content container.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getContentMetrics = function(
|
||||
opt_getWorkspaceCoordinates) {
|
||||
var scale = opt_getWorkspaceCoordinates ? 1 : this.workspace_.scale;
|
||||
|
||||
// Block bounding box is in workspace coordinates.
|
||||
var blockBox = this.workspace_.getBlocksBoundingBox();
|
||||
|
||||
return {
|
||||
height: (blockBox.bottom - blockBox.top) * scale,
|
||||
width: (blockBox.right - blockBox.left) * scale,
|
||||
top: blockBox.top * scale,
|
||||
left: blockBox.left * scale,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the scroll area has fixed edges.
|
||||
* @return {boolean} Whether the scroll area has fixed edges.
|
||||
* @package
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.hasFixedEdges = function() {
|
||||
// This exists for optimization of bump logic.
|
||||
return !this.workspace_.isMovableHorizontally() ||
|
||||
!this.workspace_.isMovableVertically();
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the fixed edges of the scroll area.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view
|
||||
* metrics if they have been previously computed. Passing in null may cause
|
||||
* the view metrics to be computed again, if it is needed.
|
||||
* @return {!Blockly.MetricsManager.FixedEdges} The fixed edges of the scroll
|
||||
* area.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getComputedFixedEdges_ = function(
|
||||
opt_viewMetrics) {
|
||||
if (!this.hasFixedEdges()) {
|
||||
// Return early if there are no edges.
|
||||
return {};
|
||||
}
|
||||
|
||||
var hScrollEnabled = this.workspace_.isMovableHorizontally();
|
||||
var vScrollEnabled = this.workspace_.isMovableVertically();
|
||||
|
||||
var viewMetrics = opt_viewMetrics || this.getViewMetrics(false);
|
||||
|
||||
var edges = {};
|
||||
if (!vScrollEnabled) {
|
||||
edges.top = viewMetrics.top;
|
||||
edges.bottom = viewMetrics.top + viewMetrics.height;
|
||||
}
|
||||
if (!hScrollEnabled) {
|
||||
edges.left = viewMetrics.left;
|
||||
edges.right = viewMetrics.left + viewMetrics.width;
|
||||
}
|
||||
return edges;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the content area with added padding.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The view
|
||||
* metrics.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} contentMetrics The content
|
||||
* metrics.
|
||||
* @return {{top: number, bottom: number, left: number, right: number}} The
|
||||
* padded content area.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getPaddedContent_ = function(
|
||||
viewMetrics, contentMetrics) {
|
||||
var contentBottom = contentMetrics.top + contentMetrics.height;
|
||||
var contentRight = contentMetrics.left + contentMetrics.width;
|
||||
|
||||
var viewWidth = viewMetrics.width;
|
||||
var viewHeight = viewMetrics.height;
|
||||
var halfWidth = viewWidth / 2;
|
||||
var halfHeight = viewHeight / 2;
|
||||
|
||||
// Add a padding around the content that is at least half a screen wide.
|
||||
// Ensure padding is wide enough that blocks can scroll over entire screen.
|
||||
var top =
|
||||
Math.min(contentMetrics.top - halfHeight, contentBottom - viewHeight);
|
||||
var left =
|
||||
Math.min(contentMetrics.left - halfWidth, contentRight - viewWidth);
|
||||
var bottom =
|
||||
Math.max(contentBottom + halfHeight, contentMetrics.top + viewHeight);
|
||||
var right =
|
||||
Math.max(contentRight + halfWidth, contentMetrics.left + viewWidth);
|
||||
|
||||
return {top: top, bottom: bottom, left: left, right: right};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the metrics for the scroll area of the workspace.
|
||||
* @param {boolean=} opt_getWorkspaceCoordinates True to get the scroll metrics
|
||||
* in workspace coordinates, false to get them in pixel coordinates.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion=} opt_viewMetrics The view
|
||||
* metrics if they have been previously computed. Passing in null may cause
|
||||
* the view metrics to be computed again, if it is needed.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion=} opt_contentMetrics The
|
||||
* content metrics if they have been previously computed. Passing in null
|
||||
* may cause the content metrics to be computed again, if it is needed.
|
||||
* @return {!Blockly.MetricsManager.ContainerRegion} The metrics for the scroll
|
||||
* container
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getScrollMetrics = function(
|
||||
opt_getWorkspaceCoordinates, opt_viewMetrics, opt_contentMetrics) {
|
||||
var scale = opt_getWorkspaceCoordinates ? this.workspace_.scale : 1;
|
||||
var viewMetrics = opt_viewMetrics || this.getViewMetrics(false);
|
||||
var contentMetrics = opt_contentMetrics || this.getContentMetrics();
|
||||
var fixedEdges = this.getComputedFixedEdges_(viewMetrics);
|
||||
|
||||
// Add padding around content
|
||||
var paddedContent = this.getPaddedContent_(viewMetrics, contentMetrics);
|
||||
|
||||
// Use combination of fixed bounds and padded content to make scroll area.
|
||||
var top = fixedEdges.top !== undefined ?
|
||||
fixedEdges.top : paddedContent.top;
|
||||
var left = fixedEdges.left !== undefined ?
|
||||
fixedEdges.left : paddedContent.left;
|
||||
var bottom = fixedEdges.bottom !== undefined ?
|
||||
fixedEdges.bottom : paddedContent.bottom;
|
||||
var right = fixedEdges.right !== undefined ?
|
||||
fixedEdges.right : paddedContent.right;
|
||||
|
||||
return {
|
||||
top: top / scale,
|
||||
left: left / scale,
|
||||
width: (right - left) / scale,
|
||||
height: (bottom - top) / scale,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns common metrics used by ui elements.
|
||||
* @return {!Blockly.MetricsManager.UiMetrics} The ui metrics.
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getUiMetrics = function() {
|
||||
return {
|
||||
viewMetrics: this.getViewMetrics(),
|
||||
absoluteMetrics: this.getAbsoluteMetrics(),
|
||||
toolboxMetrics: this.getToolboxMetrics()
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an object with all the metrics required to size scrollbars for a
|
||||
* top level workspace. The following properties are computed:
|
||||
* Coordinate system: pixel coordinates, -left, -up, +right, +down
|
||||
* .viewHeight: Height of the visible portion of the workspace.
|
||||
* .viewWidth: Width of the visible portion of the workspace.
|
||||
* .contentHeight: Height of the content.
|
||||
* .contentWidth: Width of the content.
|
||||
* .scrollHeight: Height of the scroll area.
|
||||
* .scrollWidth: Width of the scroll area.
|
||||
* .svgHeight: Height of the Blockly div (the view + the toolbox,
|
||||
* simple or otherwise),
|
||||
* .svgWidth: Width of the Blockly div (the view + the toolbox,
|
||||
* simple or otherwise),
|
||||
* .viewTop: Top-edge of the visible portion of the workspace, relative to
|
||||
* the workspace origin.
|
||||
* .viewLeft: Left-edge of the visible portion of the workspace, relative to
|
||||
* the workspace origin.
|
||||
* .contentTop: Top-edge of the content, relative to the workspace origin.
|
||||
* .contentLeft: Left-edge of the content relative to the workspace origin.
|
||||
* .scrollTop: Top-edge of the scroll area, relative to the workspace origin.
|
||||
* .scrollLeft: Left-edge of the scroll area relative to the workspace origin.
|
||||
* .absoluteTop: Top-edge of the visible portion of the workspace, relative
|
||||
* to the blocklyDiv.
|
||||
* .absoluteLeft: Left-edge of the visible portion of the workspace, relative
|
||||
* to the blocklyDiv.
|
||||
* .toolboxWidth: Width of the toolbox, if it exists. Otherwise zero.
|
||||
* .toolboxHeight: Height of the toolbox, if it exists. Otherwise zero.
|
||||
* .flyoutWidth: Width of the flyout if it is always open. Otherwise zero.
|
||||
* .flyoutHeight: Height of the flyout if it is always open. Otherwise zero.
|
||||
* .toolboxPosition: Top, bottom, left or right. Use TOOLBOX_AT constants to
|
||||
* compare.
|
||||
* @return {!Blockly.utils.Metrics} Contains size and position metrics of a top
|
||||
* level workspace.
|
||||
* @public
|
||||
*/
|
||||
Blockly.MetricsManager.prototype.getMetrics = function() {
|
||||
var toolboxMetrics = this.getToolboxMetrics();
|
||||
var flyoutMetrics = this.getFlyoutMetrics(true);
|
||||
var svgMetrics = this.getSvgMetrics();
|
||||
var absoluteMetrics = this.getAbsoluteMetrics();
|
||||
var viewMetrics = this.getViewMetrics();
|
||||
var contentMetrics = this.getContentMetrics();
|
||||
var scrollMetrics = this.getScrollMetrics(false, viewMetrics, contentMetrics);
|
||||
|
||||
return {
|
||||
contentHeight: contentMetrics.height,
|
||||
contentWidth: contentMetrics.width,
|
||||
contentTop: contentMetrics.top,
|
||||
contentLeft: contentMetrics.left,
|
||||
|
||||
scrollHeight: scrollMetrics.height,
|
||||
scrollWidth: scrollMetrics.width,
|
||||
scrollTop: scrollMetrics.top,
|
||||
scrollLeft: scrollMetrics.left,
|
||||
|
||||
viewHeight: viewMetrics.height,
|
||||
viewWidth: viewMetrics.width,
|
||||
viewTop: viewMetrics.top,
|
||||
viewLeft: viewMetrics.left,
|
||||
|
||||
absoluteTop: absoluteMetrics.top,
|
||||
absoluteLeft: absoluteMetrics.left,
|
||||
|
||||
svgHeight: svgMetrics.height,
|
||||
svgWidth: svgMetrics.width,
|
||||
|
||||
toolboxWidth: toolboxMetrics.width,
|
||||
toolboxHeight: toolboxMetrics.height,
|
||||
toolboxPosition: toolboxMetrics.position,
|
||||
|
||||
flyoutWidth: flyoutMetrics.width,
|
||||
flyoutHeight: flyoutMetrics.height
|
||||
};
|
||||
};
|
||||
|
||||
Blockly.registry.register(
|
||||
Blockly.registry.Type.METRICS_MANAGER, Blockly.registry.DEFAULT,
|
||||
Blockly.MetricsManager);
|
||||
|
||||
/**
|
||||
* Calculates metrics for a flyout's workspace.
|
||||
* The metrics are mainly used to size scrollbars for the flyout.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The flyout's workspace.
|
||||
* @param {!Blockly.IFlyout} flyout The flyout.
|
||||
* @extends {Blockly.MetricsManager}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager = function(workspace, flyout) {
|
||||
/**
|
||||
* The flyout that owns the workspace to calculate metrics for.
|
||||
* @type {!Blockly.IFlyout}
|
||||
* @protected
|
||||
*/
|
||||
this.flyout_ = flyout;
|
||||
|
||||
Blockly.FlyoutMetricsManager.superClass_.constructor.call(this, workspace);
|
||||
};
|
||||
Blockly.utils.object.inherits(
|
||||
Blockly.FlyoutMetricsManager, Blockly.MetricsManager);
|
||||
|
||||
/**
|
||||
* Gets the bounding box of the blocks on the flyout's workspace.
|
||||
* This is in workspace coordinates.
|
||||
* @returns {!SVGRect|{height: number, y: number, width: number, x: number}} The
|
||||
* bounding box of the blocks on the workspace.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager.prototype.getBoundingBox_ = function() {
|
||||
try {
|
||||
var blockBoundingBox = this.workspace_.getCanvas().getBBox();
|
||||
} catch (e) {
|
||||
// Firefox has trouble with hidden elements (Bug 528969).
|
||||
// 2021 Update: It looks like this was fixed around Firefox 77 released in
|
||||
// 2020.
|
||||
var blockBoundingBox = {height: 0, y: 0, width: 0, x: 0};
|
||||
}
|
||||
return blockBoundingBox;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager.prototype.getContentMetrics = function(
|
||||
opt_getWorkspaceCoordinates) {
|
||||
// The bounding box is in workspace coordinates.
|
||||
var blockBoundingBox = this.getBoundingBox_();
|
||||
var scale = opt_getWorkspaceCoordinates ? 1 : this.workspace_.scale;
|
||||
|
||||
return {
|
||||
height: blockBoundingBox.height * scale,
|
||||
width: blockBoundingBox.width * scale,
|
||||
top: blockBoundingBox.y * scale,
|
||||
left: blockBoundingBox.x * scale,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager.prototype.getScrollMetrics = function(
|
||||
opt_getWorkspaceCoordinates, opt_viewMetrics, opt_contentMetrics) {
|
||||
var contentMetrics = opt_contentMetrics || this.getContentMetrics();
|
||||
var margin = this.flyout_.MARGIN * this.workspace_.scale;
|
||||
var scale = opt_getWorkspaceCoordinates ? this.workspace_.scale : 1;
|
||||
|
||||
// The left padding isn't just the margin. Some blocks are also offset by
|
||||
// tabWidth so that value and statement blocks line up.
|
||||
// The contentMetrics.left value is equivalent to the variable left padding.
|
||||
var leftPadding = contentMetrics.left;
|
||||
|
||||
return {
|
||||
height: (contentMetrics.height + 2 * margin) / scale,
|
||||
width: (contentMetrics.width + leftPadding + margin) / scale,
|
||||
top: 0,
|
||||
left: 0,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager.prototype.getViewMetrics = function(
|
||||
opt_getWorkspaceCoordinates) {
|
||||
var svgMetrics = this.getSvgMetrics();
|
||||
var scale = opt_getWorkspaceCoordinates ? this.workspace_.scale : 1;
|
||||
if (this.flyout_.horizontalLayout) {
|
||||
var viewWidth = svgMetrics.width - 2 * this.flyout_.SCROLLBAR_PADDING;
|
||||
var viewHeight = svgMetrics.height - this.flyout_.SCROLLBAR_PADDING;
|
||||
} else {
|
||||
var viewWidth = svgMetrics.width - this.flyout_.SCROLLBAR_PADDING;
|
||||
var viewHeight = svgMetrics.height - 2 * this.flyout_.SCROLLBAR_PADDING;
|
||||
}
|
||||
return {
|
||||
height: viewHeight / scale,
|
||||
width: viewWidth / scale,
|
||||
top: -this.workspace_.scrollY / scale,
|
||||
left: -this.workspace_.scrollX / scale,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.FlyoutMetricsManager.prototype.getAbsoluteMetrics = function() {
|
||||
var scrollbarPadding = this.flyout_.SCROLLBAR_PADDING;
|
||||
|
||||
if (this.flyout_.horizontalLayout) {
|
||||
// The viewWidth is svgWidth - 2 * scrollbarPadding. We want to put half
|
||||
// of that padding to the left of the blocks.
|
||||
return {top: 0, left: scrollbarPadding};
|
||||
} else {
|
||||
// The viewHeight is svgHeight - 2 * scrollbarPadding. We want to put half
|
||||
// of that padding to the top of the blocks.
|
||||
return {top: scrollbarPadding, left: 0};
|
||||
}
|
||||
};
|
||||
@@ -15,13 +15,13 @@ goog.provide('Blockly.Mutator');
|
||||
|
||||
goog.require('Blockly.Bubble');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BubbleOpen');
|
||||
goog.require('Blockly.Icon');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.global');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
@@ -29,7 +29,12 @@ goog.require('Blockly.utils.xml');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.Events.Abstract');
|
||||
goog.requireType('Blockly.utils.Coordinate');
|
||||
goog.requireType('Blockly.Workspace');
|
||||
|
||||
|
||||
/**
|
||||
@@ -177,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;
|
||||
@@ -237,8 +241,9 @@ Blockly.Mutator.prototype.resizeBubble_ = function() {
|
||||
var height = workspaceSize.height + doubleBorderWidth * 3;
|
||||
var flyout = this.workspace_.getFlyout();
|
||||
if (flyout) {
|
||||
var flyoutMetrics = flyout.getMetrics_();
|
||||
height = Math.max(height, flyoutMetrics.contentHeight + 20);
|
||||
var flyoutScrollMetrics = flyout.getWorkspace().getMetricsManager()
|
||||
.getScrollMetrics();
|
||||
height = Math.max(height, flyoutScrollMetrics.height + 20);
|
||||
width += flyout.getWidth();
|
||||
}
|
||||
if (this.block_.RTL) {
|
||||
@@ -248,7 +253,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.
|
||||
@@ -256,6 +261,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) {
|
||||
@@ -285,8 +292,8 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
|
||||
// No change.
|
||||
return;
|
||||
}
|
||||
Blockly.Events.fire(
|
||||
new Blockly.Events.BubbleOpen(this.block_, visible, 'mutator'));
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BUBBLE_OPEN))(
|
||||
this.block_, visible, 'mutator'));
|
||||
if (visible) {
|
||||
// Create the bubble.
|
||||
this.bubble_ = new Blockly.Bubble(
|
||||
@@ -414,11 +421,6 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
|
||||
// Mutation may have added some elements that need initializing.
|
||||
block.initSvg();
|
||||
|
||||
if ((/** @type {!Blockly.WorkspaceSvg} */ (Blockly.getMainWorkspace()))
|
||||
.keyboardAccessibilityMode) {
|
||||
Blockly.navigation.moveCursorOnBlockMutation(block);
|
||||
}
|
||||
|
||||
if (block.rendered) {
|
||||
block.render();
|
||||
}
|
||||
@@ -426,7 +428,7 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
|
||||
var newMutationDom = block.mutationToDom();
|
||||
var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
|
||||
if (oldMutation != newMutation) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
block, 'mutation', null, oldMutation, newMutation));
|
||||
// Ensure that any bump is part of this mutation's event group.
|
||||
var group = Blockly.Events.getGroup();
|
||||
@@ -446,39 +448,6 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an object with all the metrics required to size scrollbars for the
|
||||
* mutator 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,
|
||||
|
||||
viewHeight: this.workspaceHeight_,
|
||||
viewWidth: this.workspaceWidth_ - flyoutWidth,
|
||||
viewTop: unsupported,
|
||||
viewLeft: unsupported,
|
||||
|
||||
absoluteTop: unsupported,
|
||||
absoluteLeft: this.workspace_.RTL ? 0 : flyoutWidth
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of this mutator.
|
||||
*/
|
||||
|
||||
@@ -12,9 +12,12 @@
|
||||
|
||||
goog.provide('Blockly.Names');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Msg');
|
||||
|
||||
goog.requireType('Blockly.VariableMap');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a database of entity names (variables, functions, etc).
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
|
||||
goog.provide('Blockly.Options');
|
||||
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.Theme');
|
||||
goog.require('Blockly.Themes.Classic');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.IdGenerator');
|
||||
goog.require('Blockly.utils.Metrics');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
@@ -134,7 +132,7 @@ Blockly.Options = function(options) {
|
||||
/** @type {!Blockly.Options.MoveOptions} */
|
||||
this.moveOptions = Blockly.Options.parseMoveOptions_(options, hasCategories);
|
||||
/** @deprecated January 2019 */
|
||||
this.hasScrollbars = this.moveOptions.scrollbars;
|
||||
this.hasScrollbars = !!this.moveOptions.scrollbars;
|
||||
/** @type {boolean} */
|
||||
this.hasTrashcan = hasTrashcan;
|
||||
/** @type {number} */
|
||||
@@ -205,12 +203,21 @@ Blockly.Options.GridOptions;
|
||||
* Move Options.
|
||||
* @typedef {{
|
||||
* drag: boolean,
|
||||
* scrollbars: boolean,
|
||||
* scrollbars: (boolean | !Blockly.Options.ScrollbarOptions),
|
||||
* wheel: boolean
|
||||
* }}
|
||||
*/
|
||||
Blockly.Options.MoveOptions;
|
||||
|
||||
/**
|
||||
* Scrollbar Options.
|
||||
* @typedef {{
|
||||
* horizontal: boolean,
|
||||
* vertical: boolean
|
||||
* }}
|
||||
*/
|
||||
Blockly.Options.ScrollbarOptions;
|
||||
|
||||
/**
|
||||
* Zoom Options.
|
||||
* @typedef {{
|
||||
@@ -252,12 +259,26 @@ Blockly.Options.parseMoveOptions_ = function(options, hasCategories) {
|
||||
var moveOptions = {};
|
||||
if (move['scrollbars'] === undefined && options['scrollbars'] === undefined) {
|
||||
moveOptions.scrollbars = hasCategories;
|
||||
} else if (typeof move['scrollbars'] == 'object') {
|
||||
moveOptions.scrollbars = {};
|
||||
moveOptions.scrollbars.horizontal = !!move['scrollbars']['horizontal'];
|
||||
moveOptions.scrollbars.vertical = !!move['scrollbars']['vertical'];
|
||||
// Convert scrollbars object to boolean if they have the same value.
|
||||
// This allows us to easily check for whether any scrollbars exist using
|
||||
// !!moveOptions.scrollbars.
|
||||
if (moveOptions.scrollbars.horizontal && moveOptions.scrollbars.vertical) {
|
||||
moveOptions.scrollbars = true;
|
||||
} else if (!moveOptions.scrollbars.horizontal &&
|
||||
!moveOptions.scrollbars.vertical) {
|
||||
moveOptions.scrollbars = false;
|
||||
}
|
||||
} else {
|
||||
moveOptions.scrollbars = !!move['scrollbars'] || !!options['scrollbars'];
|
||||
}
|
||||
|
||||
if (!moveOptions.scrollbars || move['wheel'] === undefined) {
|
||||
// Defaults to false so that developers' settings don't appear to change.
|
||||
moveOptions.wheel = false;
|
||||
// Defaults to true if single-direction scroll is enabled.
|
||||
moveOptions.wheel = typeof moveOptions.scrollbars == 'object';
|
||||
} else {
|
||||
moveOptions.wheel = !!move['wheel'];
|
||||
}
|
||||
|
||||
137
core/plugin_manager.js
Normal file
137
core/plugin_manager.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Manager for all items registered with the workspace.
|
||||
* @author kozbial@google.com (Monica Kozbial)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.PluginManager');
|
||||
|
||||
|
||||
/**
|
||||
* Manager for all items registered with the workspace.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.PluginManager = function() {
|
||||
/**
|
||||
* A map of the plugins registered with the workspace, mapped to id.
|
||||
* @type {!Object<string, !Blockly.PluginManager.PluginDatum>}
|
||||
* @private
|
||||
*/
|
||||
this.pluginData_ = {};
|
||||
|
||||
/**
|
||||
* A map of types to plugin ids.
|
||||
* @type {!Object<string, Array<string>>}
|
||||
* @private
|
||||
*/
|
||||
this.typeToPluginIds_ = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* An object storing plugin information.
|
||||
* @typedef {{
|
||||
* id: string,
|
||||
* plugin: !Blockly.IPlugin,
|
||||
* types: !Array<string|!Blockly.PluginManager.Type<Blockly.IPlugin>>,
|
||||
* weight: number
|
||||
* }}
|
||||
*/
|
||||
Blockly.PluginManager.PluginDatum;
|
||||
|
||||
/**
|
||||
* Adds a plugin.
|
||||
* @param {!Blockly.PluginManager.PluginDatum} pluginDataObject The plugin.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.PluginManager.prototype.addPlugin = function(pluginDataObject) {
|
||||
this.pluginData_[pluginDataObject.id] = pluginDataObject;
|
||||
for (var i = 0, type; (type = pluginDataObject.types[i]); i++) {
|
||||
var typeKey = String(type).toLowerCase();
|
||||
if (this.typeToPluginIds_[typeKey] === undefined) {
|
||||
this.typeToPluginIds_[typeKey] = [pluginDataObject.id];
|
||||
} else {
|
||||
this.typeToPluginIds_[typeKey].push(pluginDataObject.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the plugin with the given id and the given type.
|
||||
* @param {string} id The id of the plugin to get.
|
||||
* @return {!Blockly.IPlugin|undefined} The plugin with the given name
|
||||
* or undefined if not found.
|
||||
*/
|
||||
Blockly.PluginManager.prototype.getPlugin = function(id) {
|
||||
return this.pluginData_[id] && this.pluginData_[id].plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all the plugins of the specified type.
|
||||
* @param {!Blockly.PluginManager.Type<T>} type The type of the plugin.
|
||||
* @param {boolean} sorted Whether to return list ordered by weights.
|
||||
* @return {!Array<T>} The plugins that match the
|
||||
* specified type.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.PluginManager.prototype.getPlugins = function(type, sorted) {
|
||||
var typeKey = String(type).toLowerCase();
|
||||
var pluginIds = this.typeToPluginIds_[typeKey];
|
||||
if (!pluginIds) {
|
||||
return [];
|
||||
}
|
||||
var plugins = [];
|
||||
if (sorted) {
|
||||
var pluginDataList = [];
|
||||
var pluginData = this.pluginData_;
|
||||
pluginIds.forEach(function(id) {
|
||||
pluginDataList.push(pluginData[id]);
|
||||
});
|
||||
pluginDataList.sort(function(a, b) {
|
||||
return a.weight - b.weight;
|
||||
});
|
||||
pluginDataList.forEach(function(pluginDatum) {
|
||||
plugins.push(pluginDatum.plugin);
|
||||
});
|
||||
} else {
|
||||
var pluginData = this.pluginData_;
|
||||
pluginIds.forEach(function(id) {
|
||||
plugins.push(pluginData[id].plugin);
|
||||
});
|
||||
}
|
||||
return plugins;
|
||||
};
|
||||
|
||||
/**
|
||||
* A name with the type of the element stored in the generic.
|
||||
* @param {string} name The name of the plugin type.
|
||||
* @constructor
|
||||
* @template T
|
||||
*/
|
||||
Blockly.PluginManager.Type = function(name) {
|
||||
/**
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.name_ = name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the type.
|
||||
* @return {string} The name.
|
||||
* @override
|
||||
*/
|
||||
Blockly.PluginManager.Type.prototype.toString = function() {
|
||||
return this.name_;
|
||||
};
|
||||
|
||||
/** @type {!Blockly.PluginManager.Type<!Blockly.IPositionable>} */
|
||||
Blockly.PluginManager.Type.POSITIONABLE =
|
||||
new Blockly.PluginManager.Type('positionable');
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
goog.provide('Blockly.Procedures');
|
||||
|
||||
goog.require('Blockly.Blocks');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.Msg');
|
||||
@@ -27,6 +29,10 @@ goog.require('Blockly.utils.xml');
|
||||
goog.require('Blockly.Workspace');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Events.Abstract');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Constant to separate procedure names from variables and generated functions
|
||||
@@ -374,7 +380,7 @@ Blockly.Procedures.mutateCallers = function(defBlock) {
|
||||
// undo action since it is deterministically tied to the procedure's
|
||||
// definition mutation.
|
||||
Blockly.Events.recordUndo = false;
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
Blockly.Events.fire(new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
|
||||
caller, 'mutation', null, oldMutation, newMutation));
|
||||
Blockly.Events.recordUndo = oldRecordUndo;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,16 @@
|
||||
goog.provide('Blockly.registry');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Renderer');
|
||||
goog.requireType('Blockly.Cursor');
|
||||
goog.requireType('Blockly.Events.Abstract');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IConnectionChecker');
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
goog.requireType('Blockly.IMetricsManager');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.Options');
|
||||
goog.requireType('Blockly.Theme');
|
||||
goog.requireType('Blockly.ToolboxItem');
|
||||
|
||||
|
||||
/**
|
||||
@@ -64,6 +68,9 @@ Blockly.registry.Type.prototype.toString = function() {
|
||||
Blockly.registry.Type.CONNECTION_CHECKER =
|
||||
new Blockly.registry.Type('connectionChecker');
|
||||
|
||||
/** @type {!Blockly.registry.Type<Blockly.Cursor>} */
|
||||
Blockly.registry.Type.CURSOR = new Blockly.registry.Type('cursor');
|
||||
|
||||
/** @type {!Blockly.registry.Type<Blockly.Events.Abstract>} */
|
||||
Blockly.registry.Type.EVENT = new Blockly.registry.Type('event');
|
||||
|
||||
@@ -90,6 +97,10 @@ Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX =
|
||||
Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX =
|
||||
new Blockly.registry.Type('flyoutsHorizontalToolbox');
|
||||
|
||||
/** @type {!Blockly.registry.Type<Blockly.IMetricsManager>} */
|
||||
Blockly.registry.Type.METRICS_MANAGER =
|
||||
new Blockly.registry.Type('metricsManager');
|
||||
|
||||
/**
|
||||
* Registers a class based on a type and name.
|
||||
* @param {string|!Blockly.registry.Type<T>} type The type of the plugin.
|
||||
@@ -97,22 +108,27 @@ Blockly.registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX =
|
||||
* @param {string} name The plugin's name. (Ex. field_angle, geras)
|
||||
* @param {?function(new:T, ...?)|Object} registryItem The class or object to
|
||||
* register.
|
||||
* @param {boolean=} opt_allowOverrides True to prevent an error when overriding an
|
||||
* already registered item.
|
||||
* @param {boolean=} opt_allowOverrides True to prevent an error when overriding
|
||||
* an already registered item.
|
||||
* @throws {Error} if the type or name is empty, a name with the given type has
|
||||
* already been registered, or if the given class or object is not valid for it's type.
|
||||
* already been registered, or if the given class or object is not valid for
|
||||
* it's type.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.registry.register = function(type, name, registryItem, opt_allowOverrides) {
|
||||
if ((!(type instanceof Blockly.registry.Type) && typeof type != 'string') || String(type).trim() == '') {
|
||||
throw Error('Invalid type "' + type + '". The type must be a' +
|
||||
' non-empty string or a Blockly.registry.Type.');
|
||||
Blockly.registry.register = function(
|
||||
type, name, registryItem, opt_allowOverrides) {
|
||||
if ((!(type instanceof Blockly.registry.Type) && typeof type != 'string') ||
|
||||
String(type).trim() == '') {
|
||||
throw Error(
|
||||
'Invalid type "' + type + '". The type must be a' +
|
||||
' non-empty string or a Blockly.registry.Type.');
|
||||
}
|
||||
type = String(type).toLowerCase();
|
||||
|
||||
if ((typeof name != 'string') || (name.trim() == '')) {
|
||||
throw Error('Invalid name "' + name + '". The name must be a' +
|
||||
' non-empty string.');
|
||||
throw Error(
|
||||
'Invalid name "' + name + '". The name must be a' +
|
||||
' non-empty string.');
|
||||
}
|
||||
name = name.toLowerCase();
|
||||
if (!registryItem) {
|
||||
@@ -129,7 +145,8 @@ Blockly.registry.register = function(type, name, registryItem, opt_allowOverride
|
||||
|
||||
// Don't throw an error if opt_allowOverrides is true.
|
||||
if (!opt_allowOverrides && typeRegistry[name]) {
|
||||
throw Error('Name "' + name + '" with type "' + type + '" already registered.');
|
||||
throw Error(
|
||||
'Name "' + name + '" with type "' + type + '" already registered.');
|
||||
}
|
||||
typeRegistry[name] = registryItem;
|
||||
};
|
||||
@@ -163,12 +180,9 @@ Blockly.registry.unregister = function(type, name) {
|
||||
type = String(type).toLowerCase();
|
||||
name = name.toLowerCase();
|
||||
var typeRegistry = Blockly.registry.typeMap_[type];
|
||||
if (!typeRegistry) {
|
||||
console.warn('No type "' + type + '" found');
|
||||
return;
|
||||
}
|
||||
if (!typeRegistry[name]) {
|
||||
console.warn('No name "' + name + '" with type "' + type + '" found');
|
||||
if (!typeRegistry || !typeRegistry[name]) {
|
||||
console.warn('Unable to unregister [' + name + '][' + type + '] from the ' +
|
||||
'registry.');
|
||||
return;
|
||||
}
|
||||
delete Blockly.registry.typeMap_[type][name];
|
||||
@@ -180,20 +194,24 @@ Blockly.registry.unregister = function(type, name) {
|
||||
* @param {string|!Blockly.registry.Type<T>} type The type of the plugin.
|
||||
* (e.g. Field, Renderer)
|
||||
* @param {string} name The plugin's name. (Ex. field_angle, geras)
|
||||
* @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we
|
||||
* are unable to find the plugin.
|
||||
* @return {?function(new:T, ...?)|Object} The class or object with the given
|
||||
* name and type or null if none exists.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.registry.getItem_ = function(type, name) {
|
||||
Blockly.registry.getItem_ = function(type, name, opt_throwIfMissing) {
|
||||
type = String(type).toLowerCase();
|
||||
name = name.toLowerCase();
|
||||
var typeRegistry = Blockly.registry.typeMap_[type];
|
||||
if (!typeRegistry) {
|
||||
console.warn('No type "' + type + '" found');
|
||||
return null;
|
||||
}
|
||||
if (!typeRegistry[name]) {
|
||||
console.warn('No name "' + name + '" with type "' + type + '" found');
|
||||
if (!typeRegistry || !typeRegistry[name]) {
|
||||
var msg = 'Unable to find [' + name + '][' + type + '] in the registry.';
|
||||
if (opt_throwIfMissing) {
|
||||
throw new Error(msg + ' You must require or register a ' + type +
|
||||
' plugin.');
|
||||
} else {
|
||||
console.warn(msg);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return typeRegistry[name];
|
||||
@@ -224,12 +242,15 @@ Blockly.registry.hasItem = function(type, name) {
|
||||
* @param {string|!Blockly.registry.Type<T>} type The type of the plugin.
|
||||
* (e.g. Field, Renderer)
|
||||
* @param {string} name The plugin's name. (Ex. field_angle, geras)
|
||||
* @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we
|
||||
* are unable to find the plugin.
|
||||
* @return {?function(new:T, ...?)} The class with the given name and type or
|
||||
* null if none exists.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.registry.getClass = function(type, name) {
|
||||
return /** @type {?function(new:T, ...?)} */ (Blockly.registry.getItem_(type, name));
|
||||
Blockly.registry.getClass = function(type, name, opt_throwIfMissing) {
|
||||
return /** @type {?function(new:T, ...?)} */ (
|
||||
Blockly.registry.getItem_(type, name, opt_throwIfMissing));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -237,11 +258,14 @@ Blockly.registry.getClass = function(type, name) {
|
||||
* @param {string|!Blockly.registry.Type<T>} type The type of the plugin.
|
||||
* (e.g. Category)
|
||||
* @param {string} name The plugin's name. (Ex. logic_category)
|
||||
* @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we
|
||||
* are unable to find the object.
|
||||
* @returns {T} The object with the given name and type or null if none exists.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.registry.getObject = function(type, name) {
|
||||
return /** @type {T} */ (Blockly.registry.getItem_(type, name));
|
||||
Blockly.registry.getObject = function(type, name, opt_throwIfMissing) {
|
||||
return /** @type {T} */ (
|
||||
Blockly.registry.getItem_(type, name, opt_throwIfMissing));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -250,10 +274,13 @@ Blockly.registry.getObject = function(type, name) {
|
||||
* @param {!Blockly.registry.Type<T>} type The type of the plugin.
|
||||
* @param {!Blockly.Options} options The option object to check for the given
|
||||
* plugin.
|
||||
* @param {boolean=} opt_throwIfMissing Whether or not to throw an error if we
|
||||
* are unable to find the plugin.
|
||||
* @return {?function(new:T, ...?)} The class for the plugin.
|
||||
* @template T
|
||||
*/
|
||||
Blockly.registry.getClassFromOptions = function(type, options) {
|
||||
Blockly.registry.getClassFromOptions = function(type, options,
|
||||
opt_throwIfMissing) {
|
||||
var typeName = type.toString();
|
||||
var plugin = options.plugins[typeName] || Blockly.registry.DEFAULT;
|
||||
|
||||
@@ -261,5 +288,5 @@ Blockly.registry.getClassFromOptions = function(type, options) {
|
||||
if (typeof plugin == 'function') {
|
||||
return plugin;
|
||||
}
|
||||
return Blockly.registry.getClass(type, plugin);
|
||||
return Blockly.registry.getClass(type, plugin, opt_throwIfMissing);
|
||||
};
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
goog.provide('Blockly.RenderedConnection');
|
||||
|
||||
goog.require('Blockly.Connection');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.deprecation');
|
||||
@@ -22,6 +23,10 @@ goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.ConnectionDB');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a connection between blocks that may be rendered on screen.
|
||||
@@ -284,7 +289,8 @@ Blockly.RenderedConnection.prototype.highlight = function() {
|
||||
var sourceBlockSvg = /** @type {!Blockly.BlockSvg} */ (this.sourceBlock_);
|
||||
var renderConstants = sourceBlockSvg.workspace.getRenderer().getConstants();
|
||||
var shape = renderConstants.shapeFor(this);
|
||||
if (this.type == Blockly.INPUT_VALUE || this.type == Blockly.OUTPUT_VALUE) {
|
||||
if (this.type == Blockly.connectionTypes.INPUT_VALUE ||
|
||||
this.type == Blockly.connectionTypes.OUTPUT_VALUE) {
|
||||
// Vertical line, puzzle tab, vertical line.
|
||||
var yLen = renderConstants.TAB_OFFSET_FROM_TOP;
|
||||
steps = Blockly.utils.svgPaths.moveBy(0, -yLen) +
|
||||
@@ -389,7 +395,8 @@ Blockly.RenderedConnection.prototype.startTrackingAll = function() {
|
||||
// of lower blocks. Also, since rendering a block renders all its parents,
|
||||
// we only need to render the leaf nodes.
|
||||
var renderList = [];
|
||||
if (this.type != Blockly.INPUT_VALUE && this.type != Blockly.NEXT_STATEMENT) {
|
||||
if (this.type != Blockly.connectionTypes.INPUT_VALUE &&
|
||||
this.type != Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
// Only spider down.
|
||||
return renderList;
|
||||
}
|
||||
@@ -529,8 +536,8 @@ Blockly.RenderedConnection.prototype.connect_ = function(childConnection) {
|
||||
childBlock.updateDisabled();
|
||||
}
|
||||
if (parentRendered && childRendered) {
|
||||
if (parentConnection.type == Blockly.NEXT_STATEMENT ||
|
||||
parentConnection.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
if (parentConnection.type == Blockly.connectionTypes.NEXT_STATEMENT ||
|
||||
parentConnection.type == Blockly.connectionTypes.PREVIOUS_STATEMENT) {
|
||||
// Child block may need to square off its corners if it is in a stack.
|
||||
// Rendering a child will render its parent.
|
||||
childBlock.render();
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
goog.provide('Blockly.blockRendering');
|
||||
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Renderer');
|
||||
goog.requireType('Blockly.Theme');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
goog.provide('Blockly.blockRendering.ConstantProvider');
|
||||
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.colour');
|
||||
@@ -21,6 +23,8 @@ goog.require('Blockly.utils.svgPaths');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Debug');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
goog.requireType('Blockly.Theme');
|
||||
|
||||
|
||||
/**
|
||||
@@ -993,11 +997,11 @@ Blockly.blockRendering.ConstantProvider.prototype.makeOutsideCorners = function(
|
||||
Blockly.blockRendering.ConstantProvider.prototype.shapeFor = function(
|
||||
connection) {
|
||||
switch (connection.type) {
|
||||
case Blockly.INPUT_VALUE:
|
||||
case Blockly.OUTPUT_VALUE:
|
||||
case Blockly.connectionTypes.INPUT_VALUE:
|
||||
case Blockly.connectionTypes.OUTPUT_VALUE:
|
||||
return this.PUZZLE_TAB;
|
||||
case Blockly.PREVIOUS_STATEMENT:
|
||||
case Blockly.NEXT_STATEMENT:
|
||||
case Blockly.connectionTypes.PREVIOUS_STATEMENT:
|
||||
case Blockly.connectionTypes.NEXT_STATEMENT:
|
||||
return this.NOTCH;
|
||||
default:
|
||||
throw Error('Unknown connection type');
|
||||
|
||||
@@ -12,18 +12,21 @@
|
||||
|
||||
goog.provide('Blockly.blockRendering.Debug');
|
||||
|
||||
goog.require('Blockly.blockRendering.BottomRow');
|
||||
goog.require('Blockly.blockRendering.InputRow');
|
||||
goog.require('Blockly.blockRendering.Measurable');
|
||||
goog.require('Blockly.blockRendering.RenderInfo');
|
||||
goog.require('Blockly.blockRendering.Row');
|
||||
goog.require('Blockly.blockRendering.SpacerRow');
|
||||
goog.require('Blockly.blockRendering.TopRow');
|
||||
goog.require('Blockly.blockRendering.Types');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.blockRendering.InRowSpacer');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
|
||||
|
||||
/**
|
||||
* An object that renders rectangles and dots for debugging rendering code.
|
||||
@@ -223,19 +226,19 @@ Blockly.blockRendering.Debug.prototype.drawConnection = function(conn) {
|
||||
var colour;
|
||||
var size;
|
||||
var fill;
|
||||
if (conn.type == Blockly.INPUT_VALUE) {
|
||||
if (conn.type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
size = 4;
|
||||
colour = 'magenta';
|
||||
fill = 'none';
|
||||
} else if (conn.type == Blockly.OUTPUT_VALUE) {
|
||||
} else if (conn.type == Blockly.connectionTypes.OUTPUT_VALUE) {
|
||||
size = 2;
|
||||
colour = 'magenta';
|
||||
fill = colour;
|
||||
} else if (conn.type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (conn.type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
size = 4;
|
||||
colour = 'goldenrod';
|
||||
fill = 'none';
|
||||
} else if (conn.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
} else if (conn.type == Blockly.connectionTypes.PREVIOUS_STATEMENT) {
|
||||
size = 2;
|
||||
colour = 'goldenrod';
|
||||
fill = colour;
|
||||
|
||||
@@ -12,16 +12,17 @@
|
||||
|
||||
goog.provide('Blockly.blockRendering.Drawer');
|
||||
|
||||
goog.require('Blockly.blockRendering.BottomRow');
|
||||
goog.require('Blockly.blockRendering.InputRow');
|
||||
goog.require('Blockly.blockRendering.Measurable');
|
||||
goog.require('Blockly.blockRendering.RenderInfo');
|
||||
goog.require('Blockly.blockRendering.Row');
|
||||
goog.require('Blockly.blockRendering.SpacerRow');
|
||||
goog.require('Blockly.blockRendering.TopRow');
|
||||
goog.require('Blockly.blockRendering.Types');
|
||||
goog.require('Blockly.utils.svgPaths');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.blockRendering.Field');
|
||||
goog.requireType('Blockly.blockRendering.Icon');
|
||||
goog.requireType('Blockly.blockRendering.InlineInput');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
|
||||
|
||||
/**
|
||||
* An object that draws a block based on the given rendering information.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
goog.provide('Blockly.blockRendering.IPathObject');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.Theme');
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ goog.require('Blockly.blockRendering.BottomRow');
|
||||
goog.require('Blockly.blockRendering.ExternalValueInput');
|
||||
goog.require('Blockly.blockRendering.Hat');
|
||||
goog.require('Blockly.blockRendering.InlineInput');
|
||||
goog.require('Blockly.blockRendering.InRowSpacer');
|
||||
goog.require('Blockly.blockRendering.InputRow');
|
||||
goog.require('Blockly.blockRendering.InRowSpacer');
|
||||
goog.require('Blockly.blockRendering.Measurable');
|
||||
goog.require('Blockly.blockRendering.NextConnection');
|
||||
goog.require('Blockly.blockRendering.OutputConnection');
|
||||
@@ -25,11 +25,20 @@ goog.require('Blockly.blockRendering.PreviousConnection');
|
||||
goog.require('Blockly.blockRendering.RoundCorner');
|
||||
goog.require('Blockly.blockRendering.Row');
|
||||
goog.require('Blockly.blockRendering.SpacerRow');
|
||||
goog.require('Blockly.blockRendering.StatementInput');
|
||||
goog.require('Blockly.blockRendering.SquareCorner');
|
||||
goog.require('Blockly.blockRendering.StatementInput');
|
||||
goog.require('Blockly.blockRendering.TopRow');
|
||||
goog.require('Blockly.blockRendering.Types');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.inputTypes');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.blockRendering.Icon');
|
||||
goog.requireType('Blockly.blockRendering.Renderer');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Input');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
|
||||
|
||||
/**
|
||||
@@ -279,7 +288,7 @@ Blockly.blockRendering.RenderInfo.prototype.populateTopRow_ = function() {
|
||||
}
|
||||
|
||||
var precedesStatement = this.block_.inputList.length &&
|
||||
this.block_.inputList[0].type == Blockly.NEXT_STATEMENT;
|
||||
this.block_.inputList[0].type == Blockly.inputTypes.STATEMENT;
|
||||
|
||||
// This is the minimum height for the row. If one of its elements has a
|
||||
// greater height it will be overwritten in the compute pass.
|
||||
@@ -308,10 +317,9 @@ Blockly.blockRendering.RenderInfo.prototype.populateTopRow_ = function() {
|
||||
Blockly.blockRendering.RenderInfo.prototype.populateBottomRow_ = function() {
|
||||
this.bottomRow.hasNextConnection = !!this.block_.nextConnection;
|
||||
|
||||
var followsStatement =
|
||||
this.block_.inputList.length &&
|
||||
this.block_.inputList[this.block_.inputList.length - 1]
|
||||
.type == Blockly.NEXT_STATEMENT;
|
||||
var followsStatement = this.block_.inputList.length &&
|
||||
this.block_.inputList[this.block_.inputList.length - 1].type ==
|
||||
Blockly.inputTypes.STATEMENT;
|
||||
|
||||
// This is the minimum height for the row. If one of its elements has a
|
||||
// greater height it will be overwritten in the compute pass.
|
||||
@@ -360,19 +368,19 @@ Blockly.blockRendering.RenderInfo.prototype.populateBottomRow_ = function() {
|
||||
*/
|
||||
Blockly.blockRendering.RenderInfo.prototype.addInput_ = function(input, activeRow) {
|
||||
// Non-dummy inputs have visual representations onscreen.
|
||||
if (this.isInline && input.type == Blockly.INPUT_VALUE) {
|
||||
if (this.isInline && input.type == Blockly.inputTypes.VALUE) {
|
||||
activeRow.elements.push(
|
||||
new Blockly.blockRendering.InlineInput(this.constants_, input));
|
||||
activeRow.hasInlineInput = true;
|
||||
} else if (input.type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (input.type == Blockly.inputTypes.STATEMENT) {
|
||||
activeRow.elements.push(
|
||||
new Blockly.blockRendering.StatementInput(this.constants_, input));
|
||||
activeRow.hasStatement = true;
|
||||
} else if (input.type == Blockly.INPUT_VALUE) {
|
||||
} else if (input.type == Blockly.inputTypes.VALUE) {
|
||||
activeRow.elements.push(
|
||||
new Blockly.blockRendering.ExternalValueInput(this.constants_, input));
|
||||
activeRow.hasExternalInput = true;
|
||||
} else if (input.type == Blockly.DUMMY_INPUT) {
|
||||
} else if (input.type == Blockly.inputTypes.DUMMY) {
|
||||
// Dummy inputs have no visual representation, but the information is still
|
||||
// important.
|
||||
activeRow.minHeight = Math.max(activeRow.minHeight,
|
||||
@@ -400,12 +408,13 @@ Blockly.blockRendering.RenderInfo.prototype.shouldStartNewRow_ = function(input,
|
||||
return false;
|
||||
}
|
||||
// A statement input or an input following one always gets a new row.
|
||||
if (input.type == Blockly.NEXT_STATEMENT ||
|
||||
lastInput.type == Blockly.NEXT_STATEMENT) {
|
||||
if (input.type == Blockly.inputTypes.STATEMENT ||
|
||||
lastInput.type == Blockly.inputTypes.STATEMENT) {
|
||||
return true;
|
||||
}
|
||||
// Value and dummy inputs get new row if inputs are not inlined.
|
||||
if (input.type == Blockly.INPUT_VALUE || input.type == Blockly.DUMMY_INPUT) {
|
||||
if (input.type == Blockly.inputTypes.VALUE ||
|
||||
input.type == Blockly.inputTypes.DUMMY) {
|
||||
return !this.isInline;
|
||||
}
|
||||
return false;
|
||||
@@ -584,14 +593,14 @@ Blockly.blockRendering.RenderInfo.prototype.addAlignmentPadding_ = function(row,
|
||||
}
|
||||
|
||||
// Decide where the extra padding goes.
|
||||
if (row.align == Blockly.ALIGN_LEFT) {
|
||||
if (row.align == Blockly.constants.ALIGN.LEFT) {
|
||||
// Add padding to the end of the row.
|
||||
lastSpacer.width += missingSpace;
|
||||
} else if (row.align == Blockly.ALIGN_CENTRE) {
|
||||
} else if (row.align == Blockly.constants.ALIGN.CENTRE) {
|
||||
// Split the padding between the beginning and end of the row.
|
||||
firstSpacer.width += missingSpace / 2;
|
||||
lastSpacer.width += missingSpace / 2;
|
||||
} else if (row.align == Blockly.ALIGN_RIGHT) {
|
||||
} else if (row.align == Blockly.constants.ALIGN.RIGHT) {
|
||||
// Add padding at the beginning of the row.
|
||||
firstSpacer.width += missingSpace;
|
||||
} else {
|
||||
|
||||
@@ -14,11 +14,24 @@
|
||||
goog.provide('Blockly.blockRendering.MarkerSvg');
|
||||
|
||||
goog.require('Blockly.ASTNode');
|
||||
goog.require('Blockly.connectionTypes');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('Blockly.Events.MarkerMove');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.BlockSvg');
|
||||
goog.requireType('Blockly.Connection');
|
||||
goog.requireType('Blockly.Field');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.Marker');
|
||||
goog.requireType('Blockly.RenderedConnection');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a marker.
|
||||
@@ -196,13 +209,14 @@ Blockly.blockRendering.MarkerSvg.prototype.draw = function(oldNode, curNode) {
|
||||
Blockly.blockRendering.MarkerSvg.prototype.showAtLocation_ = function(curNode) {
|
||||
var curNodeAsConnection =
|
||||
/** @type {!Blockly.Connection} */ (curNode.getLocation());
|
||||
var connectionType = curNodeAsConnection.type;
|
||||
if (curNode.getType() == Blockly.ASTNode.types.BLOCK) {
|
||||
this.showWithBlock_(curNode);
|
||||
} else if (curNode.getType() == Blockly.ASTNode.types.OUTPUT) {
|
||||
this.showWithOutput_(curNode);
|
||||
} else if (curNodeAsConnection.type == Blockly.INPUT_VALUE) {
|
||||
} else if (connectionType == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
this.showWithInput_(curNode);
|
||||
} else if (curNodeAsConnection.type == Blockly.NEXT_STATEMENT) {
|
||||
} else if (connectionType == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
this.showWithNext_(curNode);
|
||||
} else if (curNode.getType() == Blockly.ASTNode.types.PREVIOUS) {
|
||||
this.showWithPrevious_(curNode);
|
||||
@@ -552,7 +566,7 @@ Blockly.blockRendering.MarkerSvg.prototype.hide = function() {
|
||||
Blockly.blockRendering.MarkerSvg.prototype.fireMarkerEvent_ = function(
|
||||
oldNode, curNode) {
|
||||
var curBlock = curNode.getSourceBlock();
|
||||
var event = new Blockly.Events.MarkerMove(
|
||||
var event = new (Blockly.Events.get(Blockly.Events.MARKER_MOVE))(
|
||||
curBlock, this.isCursor(), oldNode, curNode);
|
||||
Blockly.Events.fire(event);
|
||||
};
|
||||
|
||||
@@ -19,6 +19,9 @@ goog.require('Blockly.Theme');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
|
||||
goog.requireType('Blockly.Block');
|
||||
goog.requireType('Blockly.Connection');
|
||||
|
||||
|
||||
/**
|
||||
* An object that handles creating and setting each of the SVG elements
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user