diff --git a/blocks/loops.js b/blocks/loops.js index a467fb7aa..484bc593a 100644 --- a/blocks/loops.js +++ b/blocks/loops.js @@ -18,6 +18,7 @@ goog.require('Blockly.FieldLabel'); goog.require('Blockly.FieldNumber'); goog.require('Blockly.FieldVariable'); goog.require('Blockly.Warning'); +goog.require('Blockly.loopMixin'); /** @@ -272,73 +273,3 @@ Blockly.Extensions.register('controls_for_tooltip', Blockly.Extensions.register('controls_forEach_tooltip', Blockly.Extensions.buildTooltipWithFieldText( '%{BKY_CONTROLS_FOREACH_TOOLTIP}', 'VAR')); - -/** - * This mixin adds a check to make sure the 'controls_flow_statements' block - * is contained in a loop. Otherwise a warning is added to the block. - * @mixin - * @augments Blockly.Block - * @package - * @readonly - */ -Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = { - /** - * List of block types that are loops and thus do not need warnings. - * To add a new loop type add this to your code: - * Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.push('custom_loop'); - */ - LOOP_TYPES: [ - 'controls_repeat', - 'controls_repeat_ext', - 'controls_forEach', - 'controls_for', - 'controls_whileUntil', - ], - - /** - * Is the given block enclosed (at any level) by a loop? - * @param {!Blockly.Block} block Current block. - * @return {Blockly.Block} The nearest surrounding loop, or null if none. - */ - getSurroundLoop: function(block) { - // Is the block nested in a loop? - do { - if (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES - .indexOf(block.type) !== -1) { - return block; - } - block = block.getSurroundParent(); - } while (block); - return null; - }, - - /** - * Called whenever anything on the workspace changes. - * Add warning if this flow block is not nested inside a loop. - * @param {!Blockly.Events.Abstract} e Change event. - * @this {Blockly.Block} - */ - onchange: function(e) { - // Don't change state if: - // * It's at the start of a drag. - // * It's not a move event. - if (!this.workspace.isDragging || this.workspace.isDragging() || - e.type !== Blockly.Events.BLOCK_MOVE) { - return; - } - const enabled = Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN - .getSurroundLoop(this); - this.setWarningText(enabled ? null : - Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING']); - if (!this.isInFlyout) { - const group = Blockly.Events.getGroup(); - // Makes it so the move and the disable event get undone together. - Blockly.Events.setGroup(e.group); - this.setEnabled(enabled); - Blockly.Events.setGroup(group); - } - }, -}; - -Blockly.Extensions.registerMixin('controls_flow_in_loop_check', - Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN); diff --git a/core/blockly.js b/core/blockly.js index fa0ef27fe..ca087ce20 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -43,6 +43,7 @@ const dialog = goog.require('Blockly.dialog'); const fieldRegistry = goog.require('Blockly.fieldRegistry'); const geras = goog.require('Blockly.geras'); const internalConstants = goog.require('Blockly.internalConstants'); +const loopMixin = goog.require('Blockly.loopMixin'); const minimalist = goog.require('Blockly.minimalist'); const registry = goog.require('Blockly.registry'); const svgMath = goog.require('Blockly.utils.svgMath'); @@ -682,6 +683,7 @@ exports.fieldRegistry = fieldRegistry; exports.geras = geras; exports.inject = inject; exports.inputTypes = inputTypes; +exports.loopMixin = loopMixin; exports.minimalist = minimalist; exports.registry = registry; exports.thrasos = thrasos; diff --git a/core/loop_mixin.js b/core/loop_mixin.js new file mode 100644 index 000000000..73b5634b9 --- /dev/null +++ b/core/loop_mixin.js @@ -0,0 +1,96 @@ +/** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview The mixin that holds logic for setting a warning on a block if + * it is not inside a loop. + */ +'use strict'; + +goog.module('Blockly.loopMixin'); + +/* eslint-disable-next-line no-unused-vars */ +const Abstract = goog.requireType('Blockly.Events.Abstract'); +const Events = goog.require('Blockly.Events'); +const Extensions = goog.require('Blockly.Extensions'); +const Msg = goog.require('Blockly.Msg'); +/* eslint-disable-next-line no-unused-vars */ +const {Block} = goog.requireType('Blockly.Block'); + + +/** + * This mixin adds a check to make sure the 'controls_flow_statements' block + * is contained in a loop. Otherwise a warning is added to the block. + * @mixin + * @augments Block + * @readonly + */ +const CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = { + /** + * List of block types that are loops and thus do not need warnings. + * To add a new loop type add this to your code: + * Blockly.loopMixin.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.push('custom_loop'); + * + * Please leave a comment on this github issue + * https://github.com/mit-cml/appinventor-sources/issues/2032 if you end up + * needing to use this. + */ + LOOP_TYPES: [ + 'controls_repeat', + 'controls_repeat_ext', + 'controls_forEach', + 'controls_for', + 'controls_whileUntil', + ], + + /** + * Is the given block enclosed (at any level) by a loop? + * @param {!Block} block Current block. + * @return {?Block} The nearest surrounding loop, or null if none. + */ + getSurroundLoop: function(block) { + let searchBlock = block; + // Is the block nested in a loop? + do { + if (CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf( + searchBlock.type) !== -1) { + return searchBlock; + } + searchBlock = searchBlock.getSurroundParent(); + } while (searchBlock); + return null; + }, + + /** + * Called whenever anything on the workspace changes. + * Add warning if this flow block is not nested inside a loop. + * @param {!Abstract} e Change event. + * @this {Block} + */ + onchange: function(e) { + // Don't change state if: + // * It's at the start of a drag. + // * It's not a move event. + if (!this.workspace.isDragging || this.workspace.isDragging() || + e.type !== Events.BLOCK_MOVE) { + return; + } + const enabled = !!CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this); + this.setWarningText( + enabled ? null : Msg['CONTROLS_FLOW_STATEMENTS_WARNING']); + if (!this.isInFlyout) { + const group = Events.getGroup(); + // Makes it so the move and the disable event get undone together. + Events.setGroup(e.group); + this.setEnabled(enabled); + Events.setGroup(group); + } + }, +}; +exports.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = CONTROL_FLOW_IN_LOOP_CHECK_MIXIN; + +Extensions.registerMixin( + 'controls_flow_in_loop_check', CONTROL_FLOW_IN_LOOP_CHECK_MIXIN); diff --git a/externs/block-externs.js b/externs/block-externs.js index d270a4da7..20b6f51b1 100644 --- a/externs/block-externs.js +++ b/externs/block-externs.js @@ -23,5 +23,6 @@ goog.provide('Blockly.FieldTextInput'); goog.provide('Blockly.FieldVariable'); goog.provide('Blockly.Mutator'); goog.provide('Blockly.Warning'); +goog.provide('Blockly.loopMixin'); var Blockly; diff --git a/externs/generator-externs.js b/externs/generator-externs.js index 450735e25..6b6d9d650 100644 --- a/externs/generator-externs.js +++ b/externs/generator-externs.js @@ -12,6 +12,7 @@ goog.provide('Blockly'); goog.provide('Blockly.Generator'); goog.provide('Blockly.inputTypes'); +goog.provide('Blockly.loopMixin'); goog.provide('Blockly.utils.global'); goog.provide('Blockly.utils.object'); goog.provide('Blockly.utils.string'); diff --git a/generators/dart/loops.js b/generators/dart/loops.js index 6078e3d21..f76f8357b 100644 --- a/generators/dart/loops.js +++ b/generators/dart/loops.js @@ -150,7 +150,7 @@ Blockly.Dart['controls_flow_statements'] = function(block) { xfix += Blockly.Dart.injectId(Blockly.Dart.STATEMENT_SUFFIX, block); } if (Blockly.Dart.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + const loop = Blockly.loopMixin .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end diff --git a/generators/javascript/loops.js b/generators/javascript/loops.js index 47975698e..a2132a365 100644 --- a/generators/javascript/loops.js +++ b/generators/javascript/loops.js @@ -12,6 +12,7 @@ goog.provide('Blockly.JavaScript.loops'); goog.require('Blockly.JavaScript'); +goog.require('Blockly.loopMixin'); Blockly.JavaScript['controls_repeat_ext'] = function(block) { @@ -164,7 +165,7 @@ Blockly.JavaScript['controls_flow_statements'] = function(block) { block); } if (Blockly.JavaScript.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + const loop = Blockly.loopMixin .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end diff --git a/generators/lua/loops.js b/generators/lua/loops.js index 2cc9696c7..732d9e6df 100644 --- a/generators/lua/loops.js +++ b/generators/lua/loops.js @@ -154,7 +154,7 @@ Blockly.Lua['controls_flow_statements'] = function(block) { xfix += Blockly.Lua.injectId(Blockly.Lua.STATEMENT_SUFFIX, block); } if (Blockly.Lua.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + const loop = Blockly.loopMixin .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end diff --git a/generators/php/loops.js b/generators/php/loops.js index efc38f654..ce43ce284 100644 --- a/generators/php/loops.js +++ b/generators/php/loops.js @@ -151,7 +151,7 @@ Blockly.PHP['controls_flow_statements'] = function(block) { xfix += Blockly.PHP.injectId(Blockly.PHP.STATEMENT_SUFFIX, block); } if (Blockly.PHP.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + const loop = Blockly.loopMixin .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end diff --git a/generators/python/loops.js b/generators/python/loops.js index 621849747..ec37d2aa9 100644 --- a/generators/python/loops.js +++ b/generators/python/loops.js @@ -195,7 +195,7 @@ Blockly.Python['controls_flow_statements'] = function(block) { xfix += Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX, block); } if (Blockly.Python.STATEMENT_PREFIX) { - const loop = Blockly.Constants.Loops + const loop = Blockly.loopMixin .CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(block); if (loop && !loop.suppressPrefixSuffix) { // Inject loop's statement prefix here since the regular one at the end diff --git a/scripts/migration/renamings.js b/scripts/migration/renamings.js index 7dee91378..d6289b49a 100644 --- a/scripts/migration/renamings.js +++ b/scripts/migration/renamings.js @@ -238,6 +238,11 @@ const renamings = { {module: 'Blockly.Extensions', export: 'runAfterPageLoad'}, }, }, + 'Blockly.Constants.Loops': { + exports: { + CONTROL_FLOW_IN_LOOP_CHECK_MIXIN: {module: 'Blockly.loopMixin'}, + }, + }, 'Blockly.Events.Abstract': { export: 'Abstract', path: 'Blockly.Events.Abstract', diff --git a/tests/deps.js b/tests/deps.js index 6dad4f6f3..418db5580 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -1,7 +1,7 @@ goog.addDependency('../../blocks/colour.js', ['Blockly.Constants.Colour', 'Blockly.blocks.colour'], ['Blockly', 'Blockly.FieldColour', 'Blockly.FieldLabel'], {'lang': 'es5'}); goog.addDependency('../../blocks/lists.js', ['Blockly.Constants.Lists', 'Blockly.blocks.lists'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.Mutator'], {'lang': 'es6'}); goog.addDependency('../../blocks/logic.js', ['Blockly.Constants.Logic', 'Blockly.blocks.logic'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.Mutator'], {'lang': 'es6'}); -goog.addDependency('../../blocks/loops.js', ['Blockly.Constants.Loops', 'Blockly.blocks.loops'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.Warning'], {'lang': 'es6'}); +goog.addDependency('../../blocks/loops.js', ['Blockly.Constants.Loops', 'Blockly.blocks.loops'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.Warning', 'Blockly.loopMixin'], {'lang': 'es6'}); goog.addDependency('../../blocks/math.js', ['Blockly.Constants.Math', 'Blockly.blocks.math'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldLabel', 'Blockly.FieldNumber', 'Blockly.FieldVariable'], {'lang': 'es6'}); goog.addDependency('../../blocks/procedures.js', ['Blockly.blocks.procedures'], ['Blockly', 'Blockly.Comment', 'Blockly.FieldCheckbox', 'Blockly.FieldLabel', 'Blockly.FieldTextInput', 'Blockly.Mutator', 'Blockly.Warning'], {'lang': 'es6'}); goog.addDependency('../../blocks/text.js', ['Blockly.Constants.Text', 'Blockly.blocks.texts'], ['Blockly', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldMultilineInput', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Mutator'], {'lang': 'es6'}); @@ -12,7 +12,7 @@ goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'] goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.svgMath'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.Events.utils', 'Blockly.IBlockDragger', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.bumpObjects', 'Blockly.common', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ConnectionType', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events.BlockMove', 'Blockly.Events.Selected', 'Blockly.Events.utils', 'Blockly.FieldLabel', 'Blockly.IASTNodeLocationSvg', 'Blockly.IBoundedElement', 'Blockly.ICopyable', 'Blockly.IDraggable', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.constants', 'Blockly.internalConstants', 'Blockly.serialization.blocks', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.svgMath', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'}); -goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.Block', 'Blockly.BlockDragSurfaceSvg', 'Blockly.BlockDragger', 'Blockly.BlockSvg', 'Blockly.BlocklyOptions', 'Blockly.Bubble', 'Blockly.BubbleDragger', 'Blockly.CollapsibleToolboxCategory', 'Blockly.Comment', 'Blockly.ComponentManager', 'Blockly.Connection', 'Blockly.ConnectionChecker', 'Blockly.ConnectionDB', 'Blockly.ConnectionType', 'Blockly.ContextMenu', 'Blockly.ContextMenuItems', 'Blockly.ContextMenuRegistry', 'Blockly.Css', 'Blockly.Cursor', 'Blockly.DeleteArea', 'Blockly.DragTarget', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Events.VarCreate', 'Blockly.Extensions', 'Blockly.Field', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabel', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Flyout', 'Blockly.FlyoutButton', 'Blockly.FlyoutMetricsManager', 'Blockly.Generator', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.HorizontalFlyout', 'Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IAutoHideable', 'Blockly.IBlockDragger', 'Blockly.IBoundedElement', 'Blockly.IBubble', 'Blockly.ICollapsibleToolboxItem', 'Blockly.IComponent', 'Blockly.IConnectionChecker', 'Blockly.IContextMenu', 'Blockly.ICopyable', 'Blockly.IDeletable', 'Blockly.IDeleteArea', 'Blockly.IDragTarget', 'Blockly.IDraggable', 'Blockly.IFlyout', 'Blockly.IKeyboardAccessible', 'Blockly.IMetricsManager', 'Blockly.IMovable', 'Blockly.IPositionable', 'Blockly.IRegistrable', 'Blockly.IRegistrableField', 'Blockly.ISelectable', 'Blockly.ISelectableToolboxItem', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.IToolboxItem', 'Blockly.Icon', 'Blockly.Input', 'Blockly.InsertionMarkerManager', 'Blockly.Marker', 'Blockly.MarkerManager', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.MetricsManager', 'Blockly.Mutator', 'Blockly.Names', 'Blockly.Options', 'Blockly.Procedures', 'Blockly.RenderedConnection', 'Blockly.Scrollbar', 'Blockly.ScrollbarPair', 'Blockly.ShortcutItems', 'Blockly.ShortcutRegistry', 'Blockly.TabNavigateCursor', 'Blockly.Theme', 'Blockly.ThemeManager', 'Blockly.Themes', 'Blockly.Toolbox', 'Blockly.ToolboxCategory', 'Blockly.ToolboxItem', 'Blockly.ToolboxSeparator', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.TouchGesture', 'Blockly.Trashcan', 'Blockly.VariableMap', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceComment', 'Blockly.WorkspaceCommentSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceDragger', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'Blockly.blockAnimations', 'Blockly.blockRendering', 'Blockly.blocks', 'Blockly.browserEvents', 'Blockly.bumpObjects', 'Blockly.clipboard', 'Blockly.common', 'Blockly.constants', 'Blockly.dialog', 'Blockly.fieldRegistry', 'Blockly.geras', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.internalConstants', 'Blockly.minimalist', 'Blockly.registry', 'Blockly.thrasos', 'Blockly.uiPosition', 'Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.global', 'Blockly.utils.svgMath', 'Blockly.utils.toolbox', 'Blockly.zelos'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.Block', 'Blockly.BlockDragSurfaceSvg', 'Blockly.BlockDragger', 'Blockly.BlockSvg', 'Blockly.BlocklyOptions', 'Blockly.Bubble', 'Blockly.BubbleDragger', 'Blockly.CollapsibleToolboxCategory', 'Blockly.Comment', 'Blockly.ComponentManager', 'Blockly.Connection', 'Blockly.ConnectionChecker', 'Blockly.ConnectionDB', 'Blockly.ConnectionType', 'Blockly.ContextMenu', 'Blockly.ContextMenuItems', 'Blockly.ContextMenuRegistry', 'Blockly.Css', 'Blockly.Cursor', 'Blockly.DeleteArea', 'Blockly.DragTarget', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Events.VarCreate', 'Blockly.Extensions', 'Blockly.Field', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabel', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Flyout', 'Blockly.FlyoutButton', 'Blockly.FlyoutMetricsManager', 'Blockly.Generator', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.HorizontalFlyout', 'Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IAutoHideable', 'Blockly.IBlockDragger', 'Blockly.IBoundedElement', 'Blockly.IBubble', 'Blockly.ICollapsibleToolboxItem', 'Blockly.IComponent', 'Blockly.IConnectionChecker', 'Blockly.IContextMenu', 'Blockly.ICopyable', 'Blockly.IDeletable', 'Blockly.IDeleteArea', 'Blockly.IDragTarget', 'Blockly.IDraggable', 'Blockly.IFlyout', 'Blockly.IKeyboardAccessible', 'Blockly.IMetricsManager', 'Blockly.IMovable', 'Blockly.IPositionable', 'Blockly.IRegistrable', 'Blockly.IRegistrableField', 'Blockly.ISelectable', 'Blockly.ISelectableToolboxItem', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.IToolboxItem', 'Blockly.Icon', 'Blockly.Input', 'Blockly.InsertionMarkerManager', 'Blockly.Marker', 'Blockly.MarkerManager', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.MetricsManager', 'Blockly.Mutator', 'Blockly.Names', 'Blockly.Options', 'Blockly.Procedures', 'Blockly.RenderedConnection', 'Blockly.Scrollbar', 'Blockly.ScrollbarPair', 'Blockly.ShortcutItems', 'Blockly.ShortcutRegistry', 'Blockly.TabNavigateCursor', 'Blockly.Theme', 'Blockly.ThemeManager', 'Blockly.Themes', 'Blockly.Toolbox', 'Blockly.ToolboxCategory', 'Blockly.ToolboxItem', 'Blockly.ToolboxSeparator', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.TouchGesture', 'Blockly.Trashcan', 'Blockly.VariableMap', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceComment', 'Blockly.WorkspaceCommentSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceDragger', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'Blockly.blockAnimations', 'Blockly.blockRendering', 'Blockly.blocks', 'Blockly.browserEvents', 'Blockly.bumpObjects', 'Blockly.clipboard', 'Blockly.common', 'Blockly.constants', 'Blockly.dialog', 'Blockly.fieldRegistry', 'Blockly.geras', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.internalConstants', 'Blockly.loopMixin', 'Blockly.minimalist', 'Blockly.registry', 'Blockly.thrasos', 'Blockly.uiPosition', 'Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.global', 'Blockly.utils.svgMath', 'Blockly.utils.toolbox', 'Blockly.zelos'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/blockly_options.js', ['Blockly.BlocklyOptions'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/blocks.js', ['Blockly.blocks'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/browser_events.js', ['Blockly.browserEvents'], ['Blockly.Touch', 'Blockly.internalConstants', 'Blockly.utils.global', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'}); @@ -127,6 +127,7 @@ goog.addDependency('../../core/keyboard_nav/basic_cursor.js', ['Blockly.BasicCur goog.addDependency('../../core/keyboard_nav/cursor.js', ['Blockly.Cursor'], ['Blockly.ASTNode', 'Blockly.Marker', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/keyboard_nav/marker.js', ['Blockly.Marker'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/keyboard_nav/tab_navigate_cursor.js', ['Blockly.TabNavigateCursor'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/loop_mixin.js', ['Blockly.loopMixin'], ['Blockly.Extensions'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/marker_manager.js', ['Blockly.MarkerManager'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/menu.js', ['Blockly.Menu'], ['Blockly.browserEvents', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.style'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/menuitem.js', ['Blockly.MenuItem'], ['Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.idGenerator'], {'lang': 'es6', 'module': 'goog'}); @@ -278,7 +279,7 @@ goog.addDependency('../../generators/javascript.js', ['Blockly.JavaScript'], ['B goog.addDependency('../../generators/javascript/colour.js', ['Blockly.JavaScript.colour'], ['Blockly.JavaScript'], {'lang': 'es6'}); goog.addDependency('../../generators/javascript/lists.js', ['Blockly.JavaScript.lists'], ['Blockly.JavaScript'], {'lang': 'es6'}); goog.addDependency('../../generators/javascript/logic.js', ['Blockly.JavaScript.logic'], ['Blockly.JavaScript'], {'lang': 'es6'}); -goog.addDependency('../../generators/javascript/loops.js', ['Blockly.JavaScript.loops'], ['Blockly.JavaScript'], {'lang': 'es6'}); +goog.addDependency('../../generators/javascript/loops.js', ['Blockly.JavaScript.loops'], ['Blockly.JavaScript', 'Blockly.loopMixin'], {'lang': 'es6'}); goog.addDependency('../../generators/javascript/math.js', ['Blockly.JavaScript.math'], ['Blockly.JavaScript'], {'lang': 'es6'}); goog.addDependency('../../generators/javascript/procedures.js', ['Blockly.JavaScript.procedures'], ['Blockly.JavaScript'], {'lang': 'es6'}); goog.addDependency('../../generators/javascript/text.js', ['Blockly.JavaScript.texts'], ['Blockly.JavaScript'], {'lang': 'es6'});